给定一个递归下降解析器,我应该如何修改它以进行语法分析?

Given a recursive descent parser, how should I modify it for Syntax Analysis?

我刚刚为 C Minus 编写了一个递归下降解析器,如果可以解析输入文本文件,它只打印 "ACCEPT",否则打印 "REJECT"。对于语法中的每个规则,我都有一个函数,只是 returns true 或 false。 以下是语法分析中必须执行的一些检查:

基本上,我的问题是,执行此操作的明智方法是什么?

我现在根本没有符号table,但我听同学说我可以简单地把某些检查放在函数本身中。例如,要不允许将浮点数作为数组索引,只需在我的代码中找到带有方括号的函数并在其中放置一些 "check" 以 return 如果浮点数位于两个方括号之间则出错。

您的检查列表不是"syntax"语法检查意义上的分析。

它们是 "syntax" 检查您是否仅将完全有效的程序解释为语言实例。

大多数编译器社区会称之为 "semantic"(有效性)检查。

通常此类检查是关于是否根据语言规则(例如,"operator [] cannot be used except on array types")将运算符应用于操作数。

为此,您必须知道每个运算符(例如“[]”)的操作数类型。为此,人们通常会构建将标识符映射到标识符类型的符号 table,并将源代码区域映射到在这些区域中有效的标识符集 ("scopes")。使用此信息,您可以检查应用于符号的运算符是否有意义。

现在出现了一个复杂情况:一些运算符适用于 表达式s,例如,运算符的其他组合,例如:foo(x)[17] 我打算表示“foo 是一个被调用的函数,returns 是一个数组。所以现在你必须将类型信息与每个表达式相关联。

最简单的方法是将类型信息与树中的每个节点相关联。 您需要阅读有关符号 tables 的内容,如何通过树遍历来构建符号,然后如何遍历树并用类型标记每个节点(标识符很简单:类型就是符号的含义) table 表示标识符的类型是)。通常你可以做一个自下而上的树遍历,先标记叶子节点,然后检查它们上面的运算符节点的有效性,并在有效性检查通过后计算运算符节点的类型,并继续这个过程来标记树节点作为你的分析器爬树了。

[对于某些语言,自下而上扫描不起作用;您已经反复上下传递信息。阿达因此而闻名。

此过程的正式表征称为 "attribute evaluation"。参见 https://en.wikipedia.org/wiki/Attribute_grammar。你不需要成为这个 "formal" 来实现这些想法,你可以手工完成自下而上的案例。

这是聪明的方法。其他方法可能是可行的,但它们很难想象并且可能很难实现 "right".