1 compiler-construction parsing
我和我的研究生正在开发一个训练编译器,我们将用它来教授学生“编译器和口译员”主题。输入程序语言是 Java 语言的一个有限子集,编译器实现语言是 Java。
输入语言句法的文法是LL(1),因为它更容易被学生理解和实现。我们在解析器实现中有以下一般问题。在解析过程中如何区分标识符和函数调用?
例如我们可能有:
b = sum(10,5) //sum is a function call  
Run Code Online (Sandbox Code Playgroud)
或者
b = a //a is an identifier  
Run Code Online (Sandbox Code Playgroud)
在这两种情况下,=我们在符号之后都有一个标识符。
是否可以区分在等号之后我们有什么样的构造(函数调用或标识符)=?  
可能在 LL(1) 解析器中是不可能的,因为我们只能向前看 1 个符号?如果这是真的,您建议如何在语法中定义函数调用?也许在函数调用之前需要一些额外的符号,例如b = @sum(10,5)?  
你认为这个符号会让学生感到困惑吗?什么样的函数调用符号是合适的?
您确实不能在 LL(1) 语法中为函数调用和变量制定单独的规则,因为这需要额外的前瞻。对此的常见解决方案是将它们组合成一个匹配标识符的规则,可选地后跟一个参数列表:
primary_expression ::= ID ( "(" expression_list ")" )?
                     | ...
Run Code Online (Sandbox Code Playgroud)
在函数可以是任意表达式而不仅仅是标识符的语言中,您需要像对待任何其他后缀运算符一样对待它:
postfix_expression ::= primary_expression postfix_operator*
postfix_operator ::= "++"
                   | "--"
                   | "[" expression "]"
                   | "(" expression_list ")"
Run Code Online (Sandbox Code Playgroud)