12

在 C# 中,诸如intor之string类的标识符实际上是语言级别的关键字。
这是什么原因?

请注意,如果作者想要禁止使用这些名称的用户类型,那可能会导致语义错误,而不是语法错误。

基于答案的一些澄清:

  1. 它们是关键字,因为它使解析成为可能/更容易
    我不明白为什么,因为我正在开发一个解析器,并且Type.Rule = IdentifierType.Rule = Identifier | "int" | "string" | ....

  2. 它们是关键字,因为它们是特殊的别名
    var并且dynamic也是特殊的东西,但不是关键字(出于兼容性原因,但它表明作为关键字不一定是特殊的)。在另一个示例中,应用于[Serializable]类型会生成魔术 IL 元数据修饰符serializable,而不是标准自定义属性。但它仍然不是关键字。

  3. 它们是关键字,因为它们是其他语言的关键字
    很好的答案,但是,为什么它们是其他语言的关键字?此外,当然可以在不作为关键字的情况下用蓝色突出显示它们,那么为什么要从其他语言中引入呢?

4

3 回答 3

3

几乎我学过的语言是这样的:C、C++、Java、Pascal、C#。我不太确定,但是根据Compiler Design我在大学学习的课程(在本课程中,我们将学习人们如何编写编译器,一步一步,并实现自己的编译器),您提出问题的主要原因是:为了更容易在词法分析短语

当您编写代码时,所有代码都只是一个简单的字符串。并且编译器在真正编译之前必须做很多短语。

例如,当您键入:

int a = 5;

第一个短语是 Lexical Analysis 必须给出如下字典并发送到Parser pharse

    int ---> identifiers
    a   ---> Variable
    =   ---> Operator(=)
    5   ---> Integer
    ;   ---> ;

以及如何Lexical Analysis知道这一点:首先,它将建立一个字典表并搜索您输入的字符串。当第一个分词器相遇时,它将停止并采用该分词器。(这一点很重要 ! )

像这样的字典:

if   ---> if
then ---> then
int  ---> int
.... // all keywords here
[a-z][a-z0-9_]* ---> variable  // example of regular expression :  I don't sure it's true, just something like this :D

因此,如果语言允许您将 int 命名为变量。如 :

int int = 5;

上面的 for 方法lexical analysis破坏了,当它读取到 second 时int,它不知道它是一个变量还是关键字,并且必须有更复杂的步骤来确定它。

我不是说它不能,但是编译时它更复杂,更慢,不需要。对程序员简单地说:“嘿,不要那样做,否则我不会编译你的程序 :))”

希望这有帮助:)

于 2012-07-21T11:01:50.523 回答
3

据我所知,C# 设计者希望允许使用典型的类型名称,因为它们在 C 风格的语言中很常见,即string,int等等。同时,这些类型中的每一个都必须具有完全限定的类型名称,例如System.StringSystem.Int32。因此,决定为这些常用类型提供别名。

如果我再次找到此声明的来源,我将添加链接。

在其他基于 CLI 的语言中,相同的完全限定类型标识符是有效的。但是,在此类语言中,诸如intor之类的类型名称string可能不常见,因此可能会在此处提供其他别名。

使用类型别名的一个可能优点是提高了可读性,这就是为什么有一个StyleCop 规则强制使用别名而不是常规类型名称的原因。在同一主题的这个线程中也提到了关于简洁的观点。

于 2012-07-21T10:28:07.493 回答
1

这是因为intC# 语言中内置的其他特殊值类型根本不是真正的类型,而是.NET Framework 系统类型的别名

这是语法错误而不是语义错误的原因仅仅是因为在语法错误检测阶段检测到错误,该阶段发生在语义错误之前。语法错误检测具有确定int是用作类型还是用作其他内容所需的所有信息。假设我们有以下规则:

declaration = type identifier ;

语法阶段检查标识符是否为 [aZ]([aZ]+ | [0-9]+)+ 并且不是保留关键字或别名,在您描述的情况下是。因此,将其命名为语法错误是完全有道理的。

于 2012-07-21T10:24:53.567 回答