programming-languages - 为什么很多编程语言把类型*放在*变量名之后?

标签 programming-languages language-design grammar

我刚遇到this question在 Go FAQ 中,它让我想起了困扰我一段时间的事情。不幸的是,我真的不明白答案是什么。

似乎几乎所有非 C 类语言都将类型放在变量名之后,如下所示:

var : int

纯粹出于好奇,这是为什么呢?选择其中一个有优势吗?

最佳答案

正如 Keith Randall 所说,存在解析问题,但这不是他所描述的。 “不知道它是声明还是表达式”根本无关紧要 - 你不关心它是表达式还是声明,直到你已经解析了整个事情,此时歧义得到了解决。

使用上下文无关的解析器,类型是在变量名之前还是之后都没有关系。重要的是,您无需查找用户定义的类型名称即可理解类型规范——您无需了解之前的所有内容即可理解当前标记。

Pascal 语法是上下文无关的 - 如果不完全,至少 WRT 这个问题。变量名在前这一事实不如冒号分隔符和类型描述的语法等细节重要。

C 语法是上下文相关的。为了让解析器确定类型描述在哪里结束以及哪个标记是变量名,它需要已经解释了之前出现的所有内容,以便它可以确定给定的标识符标记是变量名还是只是另一个标记类型描述。

因为 C 语法是上下文相关的,所以使用传统的解析器生成器工具(例如 yacc/bison)解析非常困难(如果不是不可能的话),而使用相同的工具很容易解析 Pascal 语法。也就是说,现在有可以处理 C 甚至 C++ 语法的解析器生成器。虽然它没有正确记录或在 1.?发布等,我个人最喜欢的是Kelbt ,它使用回溯 LR 并支持语义“撤消” - 当推测分析结果错误时,基本上撤消对符号表的添加。

在实践中,C 和 C++ 解析器通常是手写的,混合了递归下降和优先解析。我假设这同样适用于 Java 和 C#。

顺便说一句,C++ 解析中与上下文相关的类似问题已经造成了很多麻烦。 C++0x 的“Alternative Function Syntax”通过将类型规范移到末尾并将其放在分隔符之后来解决类似的问题 - 非常类似于函数返回类型的 Pascal 冒号。它并没有摆脱上下文敏感性,但采用类似 Pascal 的约定确实使它更易于管理。

关于programming-languages - 为什么很多编程语言把类型*放在*变量名之后?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1712274/

相关文章:

c - 带线程的递归 Fib、段错误?

programming-languages - 尝试让编程语言做一些它不想做的事情是不是一个好主意?

design-patterns - 设计模式作为(缺失的)语言特性

compiler-construction - 为什么 Wasm GC 设计要解决类型相等性、标记、子类型和方法等问题?

programming-languages - 在方案或一般情况下使用的 'thunk' 是什么?

python - 为什么 Python 没有符号函数?

language-agnostic - 类型作为一等对象有什么好处?

python - 即使没有关键字 `1 < 2`, bool 运算中的 `not_test` 也是 `not` 吗?

parsing - 现代编程语言的语法是上下文无关的还是上下文敏感的?

inheritance - perl6 语法 Action 类方法似乎没有继承,命名捕获似乎没有制作