2

我想知道是否所有编程语言都保留关键字?说IfWhile是保留的关键词。我们不应该将它用作普通变量或函数名称,如果我有If = 3是非法的。所以编译器会在 sanner 阶段产生错误。如果一种语言允许程序员使用保留关键字If作为变量名或函数名会怎样。编译器如何处理这个问题?这是否在扫描仪或解析器中得到处理?语义分析应该做什么?

更新: 我知道这不是一个好的做法,但大多数/所有编程语言不支持这个的真正原因是因为扫描仪或解析器无法准确地扫描语言或解析语言,或者它在幕后的真正含义是什么?谢谢。

4

6 回答 6

5

你绝对可以做这样的事情,但显然它会破坏源代码的直观性。想象一下:

if if == 1

就实际实现而言,词法分析器根本不需要更改。如果词法分析器匹配源中的“if”,它会返回一个带有IF类型的标记。假设我们有下面的赋值语句,其中if是一个变量名,它被赋值为 1。

if <- 1;

要馈送到解析器的词法分析器的令牌流是:

IF, LARROW, INTLITERAL, SEMICOLON

我可能有以下产品来描述赋值语句(\w 整数 rvals):

assignStmt::= id:i LARROW intExpr:e SEMICOLON {: RESULT = new AssignmentStatement(i, e) :}
intExpr::= INTLITERAL:i {: RESULT = i.intVal; :}
id::= ID:i {: RESULT = i.strVal; :}

LARROW, ID, IF, INTLITERAL, 和SEMICOLON是终结符,它们是词法分析器返回的标记,并且assignStmt, id, 和intExpr是非终结符。ID表示一个标识符(例如类/变量/方法名)。

在 if 语句的产生式失败后,我们最终将输入赋值语句的第一个产生式。我们扩展id非终端,其唯一的生产是ID,但我要匹配的令牌是IF,所以assignStmt生产完全失败。

为了让我的语言允许将变量命名为“if”,我所要做的就是:

assignStmt::= id:i LARROW intExpr:e SEMICOLON {: RESULT = new AssignmentStatement(i, e) :}
intExpr::= INTLITERAL:i {: RESULT = i.intVal; :}
id::= ID:i {: RESULT = i.strVal; :}
     |IF {: RESULT = "if"; :}

请注意,它|定义了非终端的替代生产。现在我们有了id非终结符的第二个产生式,它匹配当前标记,并最终匹配一个赋值语句。

AssignmentStatement是一个 AST 节点,定义如下:

class AssignmentStatement {
     String varName;
     int intVal;
     AssignmentStatement(String s, int i){varName = s; intVal = i; }
}

一旦解析器确定源在语法上是正确的,其他任何东西都不会受到影响。变量的名称不应影响编译的后期阶段,也就是说,如果您不创建允许这种情况发生的条件。

于 2012-04-16T01:23:50.303 回答
1

即使可以,您到底为什么要这样做?

它所能做的就是编写不可维护的代码。

if (a==b)- 这是一个 if 表达式还是对if传递布尔 arg 的函数的调用?

我会说,如果有任何语言确实让你这样做,那可能是 3 个用户的一些奇怪的学术问题。

[穿上石棉内衣,为 3 名用户的无情燃烧做准备;-)]

于 2012-04-15T23:57:13.037 回答
1

编程语言往往有保留字,因为人们喜欢将词法扫描器放在解析器前面。词法扫描器会将源代码转换为一系列标记,因此您最终可能会得到一个“>>”标记并说所有这些标记都是移位运算符,然后您不能将这些字符用于其他任何内容,除非作为其他字符的一部分标记(如带引号的字符串),这是或曾经是 C++ 的一个流行问题。像“if”这样的其他词也是一样的,它变成了某种“if”标记,每当解析器看到“if”标记时,它就会将其视为某个条件构造的第一部分。另一个例子是 JavaScript,你可以在其中编写

JSON.stringify({bar:2})

但你不能写

JSON.stringify({var:2})

因为“var”是一个“var”标记,但“bar”只是一个标识符,就像其他任何标识符一样。

于 2012-04-16T00:29:30.137 回答
0

好吧,我想不出任何没有保留关键字的编译语言。它更方便,并且很少有充分的理由使用这些保留关键字('if' 不是一个好的变量名)。

在 PHP 中,变量以美元符号开头,所以我想一种语言可以以这种方式实现它(使用非字母作为变量的前缀,这样你就可以使用 $if)。我想这可以发挥作用,尽管这样做也没多大用处。

于 2012-04-15T23:56:44.607 回答
0

允许任意关键字的一种方法是对所有非标识符句法变量使用非字母符号。APL采用这种方法,Smalltalk 可能也是如此(在Smalltalk-80中,有六个保留字,但它们都具有类似变量的语义;通常是关键字的东西,如条件,在语法上是常规消息)。

于 2012-04-16T08:36:29.787 回答
-1

我认为不存在任何这样的语言。所有信息语言都基于语法,即一组规则,说明必须如何构造代码。这样,您就可以证明代码在结构上是有效的。如果您要允许根据需要切换名称,则必须有一种“即时”更改语法的方法,以确保代码的验证保持正确。

在更实际的层面上,为什么要费心去做这样的事情呢?保留关键字有什么问题?它们真的很有用,至少每个人都以同样的方式说同样的语言。你甚至不会想到用现实世界的语言来做这样的事情......想象一下,如果你开始转换单词的含义!没有人会再明白任何事情了!!

于 2012-04-16T00:02:16.630 回答