我正在尝试为一种简单的语言编写解析器:
parser = Lark("""
?start: arithmetic_expr | boolean_expr
// relational operation
?rel_op : arithmetic_expr ("<" | ">" | "==" | "!=") arithmetic_expr
// boolean expression
?boolean_expr: bool_term
| boolean_expr "or" bool_term
?bool_term: bool_atom
| bool_term "and" bool_atom
?bool_atom: "true"
| "false"
| "!" bool_atom
| rel_op
| ID
| "(" boolean_expr ")"
// arithmetic expression
?arithmetic_expr: product
| arithmetic_expr "+" product
| arithmetic_expr "-" product
?product: atom
| product "*" atom
| product "/" atom
?atom: NUMBER
| "-" atom
| ID
| "(" arithmetic_expr ")"
%import common.CNAME -> ID
%import common.NUMBER
""", parser='lalr', start='start')
当我运行它时,我收到以下错误:
lark.exceptions.GrammarError: Reduce/Reduce collision in Terminal('RPAR') between the following rules:
- <bool_atom : ID>
- <atom : ID>
我知道发生这种情况是因为,如果我们想象解析器是在没有错误的情况下构建的,然后写入parser.parse('foo')
,两者arithmetic_expr
和boolean_expr
都是“正确的”派生。此外,如您所见,我使用的是 LALR,它是一种严格确定性的算法,无法处理歧义。
所以我的问题是,我怎样才能使这个语法明确?我似乎找不到解决方案。