我通过创建一个简单的递归下降解析器来学习解析器的工作原理。但是我在定义语法时遇到问题是LL(1)。我希望能够解析以下两个语句:
a = 1
a + 1
为此,我创建了以下语法规则:
statement: assignent | expression
assignment: NAME EQUALS expression
expression: term [(PLUS|MINUS) term]
term: NAME | NUMBER
但是,这会导致使用LL(1)解析器时出现歧义,因为在statement
规则中遇到NAME令牌时,它不知道它是assignment
还是没有预见的expression
。
Python的语法是LL(1),所以我知道这是可行的,但我无法弄清楚如何去做。我已经查看过Python(https://docs.python.org/3/reference/grammar.html)中的Python语法规则,但我还不确定它们是如何实现的。
非常感谢任何帮助:)
答案 0 :(得分:2)
将 = 视为优先级非常低的运算符。但是(除非你想要像C这样的语言,其中 = 实际上是一个优先级非常低的运算符),你需要将其从内部(例如括号)表达式中排除。
如果你只有乘法和加法,你可以使用:
expression: factor ['+' factor]
factor: term ['*' term]
term: ID | NUMBER | '(' expression ')'
这是运算符优先级的指南: 具有更高的优先级,因为 + 的参数可以包含 s但反之亦然。所以我们可以添加作业:
statement: expression ['=' expression]
不幸的是,这将允许,例如:
(a + 1) = b
这是不受欢迎的。因此需要将其消除,但是当接受生产时(通过检查第一个expression
的形式)而不是语法本身,可以消除它。据我了解,这就是Python解析器的功能;查看关于test
和关键字的长评论。
如果您使用LR(1)解析器,则不会出现此问题。