为什么编程语言需要关键字?
例如(在 C 语言中):
int break = 1;
int for = 2;
为什么编译器在推断 break
和 for
是变量时会出现任何问题?
因此,我们需要关键字,因为
- 我们希望程序具有可读性,
- 我们不想使当今已经很复杂的编译器的工作变得过于复杂
- ,但最重要的是,如果某些“关键字”保留给某些特殊的语言,那么语言就会更强大行动。然后,该语言可以认为在更高的级别上是有用的,而不是在试图以明确的方式实现 for 循环中死去。
For example (in C):
int break = 1;
int for = 2;
Why will the compiler have any problems at all in deducing that break
and for
are variables here?
So, we need keywords because
- we want the programs to be readable
- we do not want to over-complicate the job of already complex compilers of today
- but most importantly, a language is lot more powerful if some 'key'words are reserved for some special actions. Then, the language can think of being useful at a higher level rather than dying in trying to implement a for loop in an unambiguous way.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(13)
没有必要——Fortran 没有保留任何单词,所以像这样的东西
是完全合法的。这不仅使编译器难以解析该语言,而且人们通常几乎不可能阅读或发现错误。例如,考虑经典的 Fortran(例如,直到 Fortran 77——我最近没有使用过它,但至少希望他们在更新的标准中修复了一些类似的问题)。 Fortran DO 循环看起来像这样:
如果没有它们并排,您可能会发现您会错过它的不同之处:
不幸的是,后者根本不是 DO 循环 - 它只是一个简单的赋值将值
1.10
赋给名为DO 10 I
的变量(是的,它也允许名称中包含空格)。由于 Fortran 还支持隐式(未声明)变量,因此这是(或曾经)完全合法的,并且某些编译器甚至会在没有警告的情况下接受它!It's not necessary -- Fortran didn't reserve any words, so things like:
are complete legal. This not only makes the language hard for the compiler to parse, but often almost impossible for a person to read or spot errors. for example, consider classic Fortran (say, up through Fortran 77 -- I haven't used it recently, but at least hope they've fixed a few things like this in more recent standards). A Fortran DO loop looks like this:
Without them being side-by-side, you can probably see how you'd miss how this was different:
Unfortunately, the latter isn't a DO loop at all -- it's a simple assignment of the value
1.10
to a variable namedDO 10 I
(yes, it also allows spaces in a name). Since Fortran also supports implicit (undeclared) variables, this is (or was) all perfectly legal, and some compilers would even accept it without a warning!那么当计算机遇到这样的语句时会做什么:
它真的应该崩溃吗?或者应该将其视为
1;
?在某些情况下,语言会变得不明确,或者您必须创建一个非常智能的解析器来推断微妙的语法,而这只是不必要的额外工作。
Then what will the computer do when it comes across a statement like:
Should it actually break? Or should it treat it as
1;
?The language would become ambiguous in certain cases, or you'd have to create a very smart parser that can infer subtle syntax, and that's just unnecessary extra work.
他们不这样做。众所周知,PL/1 没有关键字;每个“关键字”(BEGIN、DO、...)也可以用作变量名。但允许这样做意味着你可以编写非常晦涩的代码:
如果 DO> 开始则打印:=CALL-GOTO;
如果设置了“语句关键字”作为语言通常不会造成损失
名称是谦虚的(因为它在我见过的每种语言中都是如此,除了 PL/1 :-)。
APL 也没有关键字,这是出了名的。但它有一组大约 200 个令人惊叹的标志性符号,可以在其中编写复杂的运算符。 (“多米诺骨牌”运算符[不要问!]是一个方框,中间有一个计算器除号)在这种情况下,语言设计者只是使用图标而不是关键字。结果是 APL 享有“只写”语言的声誉。
底线:不是必需的,但如果关键字是程序员已知的一小部分中的保留标识符,则往往会使程序更具可读性。 (一些语言坚持认为“关键字”以特殊的标点符号开头,例如“.”,以允许使用所有可能的标识符,但这不值得额外的输入麻烦或页面上的混乱;它很容易当关键字集较小时,远离与关键字匹配的“标识符”)。
They don't. PL/1 famously has no keywords; every "keyword" (BEGIN, DO, ...) can also be used a variable name. But allowing this means you can write really obscure code:
IF DO>BEGIN THEN PRINT:=CALL-GOTO;
Reserving the "statement keywords" as the language isn't usually a loss if that set
of names is modest (as it is in every langauge I've ever seen except PL/1 :-).
APL also famously has no keywords. But it has a set of some 200 amazing iconic symbols in which to write complicated operators. (the "domino" operator [don't ask!] is a square box with a calculator divide sign in the middle) In this case, the langauge designers simply used icons instead of keywords. The consequence is that APL has a reputation of being a "write only" language.
Bottom line: not a requirement, but it tends to make programs a lot more readable if the keywords are reserved identifiers from a small set known to the programmers. (Some langauges has insisted that "keywords" start with a special punctuation character like "." to allow all possible identifiers to be used, but this isn't worth the extra trouble to type or the clutter on the page; its pretty easy to stay away from "identifiers" that match keywords when the keyword set is small).
由于它被标记为 C,因此原始 C 语言默认情况下将任何变量定义为
int
类型。这意味着
foo;
将声明一个int
类型的变量。假设您执行了
break;
。那么编译器如何知道你是要声明一个名为break
的变量还是使用关键字break
呢?Since it's tagged C, the original C language was such that by default any variable was defined as type
int
.It means that
foo;
would declare a variable of typeint
.Let's say you do
break;
. So how does the compiler know whether you want to declare a variable namedbreak
or use the keywordbreak
?有几个原因:
您的示例中的关键字可能看起来很明确。但这并不是您使用变量“break”或变量“for”的唯一地方。
编写解析器会更加困难,并且容易出错,但收获甚微。
在库中使用关键字作为函数或过程名称可能会产生不良的、可能与安全相关的副作用。
在库中使用关键字作为函数或过程名称可能会产生不良的、可能
several reasons:
The keywords may seem unambiguous in your samples. But that is not the only place you would use the variable 'break' or the variable 'for'.
writing the parser would be much harder and error prone for little gain.
using a keyword as a function or procedure name in a library may have undesired, possibly security relevant, side effects.
正如其他人所说,这使得编译器更容易解析源代码。
但我想说一点:它还可以让你的源代码更具可读性;考虑这个例子:
if (if > 0) then then = 10 end if
第二个“if”和第二个“then”是变量,而其他则不是。我认为这种代码不可读。 :)
As others said, this makes compiler parsing your source code easier.
But I would like to say a bit more: it can also make your source code more readable; consider this example:
if (if > 0) then then = 10 end if
The second "if" and the second "then" are variables, while others are not. I think this kind of code is not readable. :)
如果我们谈论 C++,它已经具有非常复杂的语法。例如,允许使用关键字作为变量名会使事情变得更加复杂。
If we are speaking of C++ - it already has very complicated grammar. Allowing to use keywords as variable names, for example, will make it even more complicated.
如果您编写如下内容,编译器将会出现问题:
这是一个循环还是对名为
while
的函数的调用?您想要从当前函数返回值 5,还是想要调用名为return
的函数?如果具有特殊含义的构造仅具有可用于明确引用它们的特殊名称,那么通常会简化事情。
The compiler would have problems if you write something like this:
Is that a loop or a call to a function named
while
? Did you want to return the value 5 from the current function, or did you want to call a function namedreturn
?It often simplifies things if constructs with special meaning simply have special names that can be used to unambiguously refer to them.
因为我们想保留我们所拥有的一点点理智:
Because we want to keep what little sanity points we've got:
我想如果不是不可能编写解析器的话,它看起来很奇怪。例如
I guess it look very weird if not impossible to write the parser. E.g
根据语言定义,编译器可能需要也可能不需要关键字。当它不知道该怎么做时,它可以尝试应用优先规则,否则就会失败。
举个例子:
如果 a 大于 2 会发生什么?
要求编译器失败
function
您可以定义不使用关键字的语言。您甚至可以定义一种允许您替换所有符号的语言(因为它们本身只是非常短的关键字)。
问题不在于编译器,如果您的规范完整并且没有错误,它就可以工作。问题是 PEBCAD,使用该语言的此功能的程序将很难阅读,因为您必须跟踪符号定义。
Depending on the language definition a compiler may or may not need keywords. When it does not know what to do it can try to apply precedence rules or just fail.
An example:
What happens if a is greater than 2?
require the compiler to fail
function
You can define a language which dosn't use keywords. You can even define a language which alowes you to replace all symbols (since they are only very short keywords themselfes).
The problem is not the compiler, if your specification is complete and error free it will work. The problem is PEBCAD, programs using this feature of the language will be hard to read as you have to keep track of the symbol definitions.
FWIW,Tcl 没有任何保留字。您可以将变量和函数命名为“if”、“break”等。标记的解释完全取决于上下文。相同的标记可以表示一个上下文中的命令、另一个上下文中的变量或另一个上下文中的文字字符串。
FWIW, Tcl doesn't have any reserved words. You can have variables and functions named "if", "break", etc. The interpretation of a token is totally dependent on the context. The same token can represent a command in one context, a variable in another, or a literal string in another.
在许多情况下,编译器可以将关键字解释为普通标识符,就像在您的示例中一样:
事实上,我只是为简单的类似汇编的玩具语言编写了一个编译器,它可以执行此操作,但会警告用户在这种情况下。
但有时语法的定义方式是关键字和标识符不明确:
最明显的原因是编辑器会强调关键字,以便代码对人类来说更具可读性。允许关键字被视为标识符将使代码突出显示变得更加困难,并且还会导致代码的可读性较差。
In many cases, it would be possible for the compiler to interprete keywords as normal identifiers, like in your example:
As a matter of fact, I just wrote a compiler for a simple assembly-like toy language which does this, but warns the user in such cases.
But sometimes the syntax is defined in a way that keywords and identifiers are ambiguous:
And the most obvious reason is that editors will emphasize keywords so that the code is more readable for humans. Allowing keywords to be treated as identifiers would make code highlighting harder, and would also lead to bad readability of your code.