32

例如(在 C 中):

int break = 1;
int for = 2;

为什么编译器在推导它时会有任何问题,break并且for这里是变量?


所以,我们需要关键字,因为

  • 我们希望程序是可读的
  • 我们不想使今天已经很复杂的编译器的工作过于复杂
  • 但最重要的是,如果为某些特殊操作保留一些“关键字”,则语言会更强大。然后,该语言可以考虑在更高级别上有用,而不是在尝试以明确的方式实现 for 循环时死去。
4

13 回答 13

29

没有必要——Fortran 没有保留任何字词,所以像:

if if .eq. then then if = else else then = if endif

是完全合法的。这不仅使编译器难以解析该语言,而且人们通常几乎不可能阅读或发现错误。例如,考虑经典的 Fortran(比如说,一直到 Fortran 77 ——我最近没有使用它,但至少希望他们在最近的标准中修复了一些类似的东西)。Fortran DO 循环如下所示:

DO 10 I = 1,10

如果没有它们并排,您可能会看到您会如何想念它的不同之处:

DO 10 I = 1.10

不幸的是,后者根本不是 DO 循环——它是将值简单地分配1.10给一个名为的变量DO 10 I(是的,它还允许名称中有空格)。由于 Fortran 还支持隐式(未声明的)变量,所以这(或曾经)完全合法,一些编译器甚至会在没有警告的情况下接受它!

于 2010-03-16T06:04:43.150 回答
20

那么当计算机遇到如下语句时会做什么:

while(1) {
  ...
  if (condition)
    break;
}

它真的应该打破吗?还是应该将其视为1;

该语言在某些情况下会变得模棱两可,或者您必须创建一个非常智能的解析器来推断微妙的语法,而这只是不必要的额外工作。

于 2010-03-16T05:55:47.613 回答
8

他们没有。众所周知,PL/1 没有关键字;每个“关键字”(BEGIN、DO、...)也可以用作变量名。但允许这意味着你可以编写真正晦涩难懂的代码: IF DO>BEGIN THEN PRINT:=CALL-GOTO; 如果那组名称是适度的(因为它在我见过的所有语言中都是如此,除了 PL/1 :-)。

APL 也以没有关键字着称。但它有一组大约 200 个令人惊叹的标志性符号,可用于编写复杂的运算符。(“多米诺”运算符 [不要问!] 是一个中间有一个计算器分隔符号的方框)在这种情况下,语言设计者只是使用图标而不是关键字。结果是 APL 享有“只写”语言的美誉。

底线:不是必需的,但如果关键字是程序员已知的一小部分保留标识符,它往往会使程序更具可读性。(一些语言坚持“关键字”以“.”之类的特殊标点符号开头,以允许使用所有可能的标识符,但这不值得额外的打字麻烦或页面上的混乱;它很容易当关键字集较小时,远离与关键字匹配的“标识符”)。

于 2010-03-16T06:04:59.470 回答
6

由于它被标记为 C,因此原始 C 语言默认情况下任何变量都定义为 type int

这意味着foo;将声明一个类型为 的变量int

假设你这样做break;。那么编译器是如何知道你是要声明一个名为的变量break还是使用关键字break呢?

于 2010-03-16T07:40:24.710 回答
4

几个原因:

  • 您的示例中的关键字可能看起来很明确。但这不是您使用变量“break”或变量“for”的唯一地方。

  • 编写解析器会更加困难并且容易出错,而且收益甚微。

  • 在库中使用关键字作为函数或过程名称可能会产生不希望的、可能与安全相关的副作用。

于 2010-03-16T05:55:44.633 回答
4

正如其他人所说,这使编译器更容易解析您的源代码。但我还想说一点:它还可以让你的源代码更具可读性;考虑这个例子:

if (if > 0) then then = 10 end if

第二个“if”和第二个“then”是变量,而其他不是。我认为这种代码不可读。:)

于 2010-03-16T06:08:47.090 回答
2

如果你写这样的东西,编译器会出现问题:

while(*s++);
return(5);

这是一个循环还是对名为 的函数的调用while?您是想从当前函数返回值 5,还是要调用一个名为 的函数return

如果具有特殊含义的结构仅具有可用于明确引用它们的特殊名称,它通常会简化事情。

于 2010-03-16T05:58:10.987 回答
2

如果我们说的是 C++——它已经有非常复杂的语法。例如,允许使用关键字作为变量名会使它变得更加复杂。

于 2010-03-16T05:59:24.427 回答
2

因为我们想保留我们所拥有的一些理智点:

void myfunction(bool) { .. };

funcp while = &myfunction;
while(true); 
于 2010-03-16T09:00:07.560 回答
0

我想编写解析器看起来很奇怪,如果不是不可能的话。例如

int break = 1;
while (true) {
   // code to change break
   if (!break) break;   // not very readable code.
}
于 2010-03-16T06:24:48.397 回答
0

根据语言定义,编译器可能需要也可能不需要关键字。当它不知道该做什么时,它可以尝试应用优先规则或失败。
一个例子:

void return(int i){printf("%d",i);}
public int foo(int a)
{
  if(a > 2)return (a+1)*2;
  return a + 3;
}

如果 a 大于 2 会发生什么?

  • 语言规范可能要求编译器失败
  • 语言规范可能要求编译器使用返回函数
  • 语言规范可能要求编译器返回

您可以定义一种不使用关键字的语言。您甚至可以定义一种允许您替换所有符号的语言(因为它们本身只是非常短的关键字)。
问题不在于编译器,如果您的规范完整且没有错误,它将起作用。问题是 PEBCAD,使用该语言特性的程序将难以阅读,因为您必须跟踪符号定义。

于 2010-03-19T15:25:23.857 回答
0

FWIW,Tcl 没有任何保留字。您可以拥有名为“if”、“break”等的变量和函数。令牌的解释完全取决于上下文。同一个标记可以在一个上下文中表示一个命令,在另一个上下文中表示一个变量,或者在另一个上下文中表示一个文字字符串。

于 2010-03-19T16:33:47.110 回答
0

在许多情况下,编译器可以将关键字解释为普通标识符,例如您的示例:

int break = 1;
int for = 2;

事实上,我只是为一种简单的类似汇编的玩具语言编写了一个编译器,它可以做到这一点,但在这种情况下会警告用户。

但有时语法以关键字和标识符不明确的方式定义:

int break;

while(...)
{
    break; // <-- treat this as expression or statement?
}

最明显的原因是编辑器会强调关键字,这样代码对人类来说更具可读性。允许将关键字视为标识符会使代码高亮变得更加困难,并且还会导致代码的可读性差。

于 2010-03-19T16:40:10.677 回答