Pascal 帕斯卡(自由或涡轮)读取

Pascal 帕斯卡(自由或涡轮)读取,pascal,freepascal,turbo-pascal,Pascal,Freepascal,Turbo Pascal,我试图理解在Linux下以Turbo模式编译(特别是fpc-Mtp-vw)的免费Pascal中看到的某种神奇行为。代码来自Jack Crenshaw的“让我们构建一个编译器”,第四部分,特别是带有输入和输出过程的最新版本,位于。 我发现的“神奇”是Read(表[GetName])行。根据FP文档,“Read从文件F中读取一个或多个值,并将结果存储在V1、V2等中;如果未指定文件F,则读取标准输入。” 在GetChar过程中的Read中,它的行为似乎很像C的GetChar(),即从stdin缓冲区

我试图理解在Linux下以Turbo模式编译(特别是
fpc-Mtp-vw
)的免费Pascal中看到的某种神奇行为。代码来自Jack Crenshaw的“让我们构建一个编译器”,第四部分,特别是带有
输入
输出
过程的最新版本,位于。 我发现的“神奇”是
Read(表[GetName])输入过程中的code>行。根据FP文档,“
Read
从文件F中读取一个或多个值,并将结果存储在V1、V2等中;如果未指定文件F,则读取标准输入。” 在
GetChar
过程中的
Read
中,它的行为似乎很像C的
GetChar()
,即从stdin缓冲区中检索下一个字符。在
输入
调用中,它看起来像一个复杂的
scanf()
函数,它自动跳过空白并将多位数转换为整数,并且不需要使用
GetNum
函数,例如,如果使用
?i 345
,则不会调用该函数,但如果您尝试
i=345
,并且在
=
的任一侧留下一个空格会导致解析错误,则确实会被调用。
是否有其他文档证实了Free、Turbo甚至通用Pascal's
Read
的明显多功能性?

我发现了一些关于Pascal's的信息,这表明与C的
getchar()
不同,它将自动正确填写各种类型。但这不是你要问的有趣的事情

杰克的编译器有一个
GetChar()
过程,它填充一个
Look
变量;这是一个单字符前瞻,虽然现在通常隐藏在多层包装纸下,但在解析器中非常常用。但是Jack的所有方法都被告知了这个变量,这就是为什么他们首先检查它,然后在结束时再次调用
GetChar()
,例如:

{ Get a number }
function GetNum : integer;
begin
  if not IsDigit(Look) then
    Expected('Integer');
  GetNum := Ord(Look) - Ord('0');
  GetChar;
end;

请记住,在Pascal中,函数名的赋值是返回值的方式,所以他在这里说的是“我的先行字符是数字吗?如果是,请解码并返回它,然后读取一个新的先行字符,否则将中止。”在本章后面,他将扩展此定义以处理多个数字。Jack在上一章中实际处理了空格,请在其中查找。

Pascal读写例程非常神奇。在某些库中,它不是一个真正的函数,但编译器会生成一系列对运行时的调用。该系列由read、readln、write和writeln以及扩展的Pascal和“from string”版本的read和write组成

调用根据参数的类型而不同,并且如果它们有额外的参数(例如,对于整数,写取:x格式值;对于实数,写取:x:y格式值):

在Free Pascal中,与Turbo Pascal和Delphi相反,还公开了一些类似RTTI的功能,例如,一个类型为enum的变量writeln()将枚举的值打印为identifer(字符串)

错误处理和格式设置在某种程度上是有限的,因此它们的使用会随着问题的复杂性而变化


至于您的观察,您的getchar-like调用可能读取了char类型的变量,而另一个函数的类型则不同。

实际上,wiki中关于
read
的内容正是我要问的。这些文档确实意味着不同类型的处理方式不同,但不像wiki条目那样详细。是的,
GetChar
函数读入一个名为
Look
char
变量(如另一个回复中所述),因此在C中它可以被
Look=GetChar()
替换。OTOH,
Input
过程中的
Read
将一个元素读入一个整数数组,因此C中的等价物必须求助于类似于
scanf(“%d”,Table[GetName()])
。是的。请注意,如果继续阅读但不检查eoln(),iirc read()在行尾也会有一些古怪的行为。您可能会得到重复的值。可能发生在被截断的行iirc.FWIW上,我发现为了在C中实现等价物(我实际上使用的是D),有必要调用
GetName
并保存该值,调用
ungetc
(为了抵消
GetName
中的
GetChar
),在D中调用
scanf
readf
)获取可能的多个数字和前导空格,并通过调用
GetChar
以恢复
Look
字符结束。
writeln(x:10:5);