我正在尝试为我的自定义语言intellij插件编写BNF文件。我对嵌套表达式的规则感到困惑。我的自定义语言包含二进制运算符表达式和数组引用表达式。所以我写了这样的BNF文件:
{
extends(".*_expr")=expr
tokens=[
id="regexp:[a-zA-Z_][a-zA-Z0-9_]*"
number="regexp:[0-9]+"
]
}
expr ::= binary_expr| array_ref_expr | const_expr
const_expr ::= number
binary_expr ::= expr '+' expr
array_ref_expr ::= id '[' expr ']'
但当我试图评估像"a[1+1]"这样的表达式时,我得到了一个错误:
']'应为,得到'+'
调试生成的解析器代码时,我发现在分析像这样的表达式时
a[expr]
,括号中的表达式的优先级必须低于array_ref_expr
,因此不会包括binary_expr
。如果我交换了这两个表达式的优先级,解析器将不会分析像这样的表达式
a[1]+1
我还试图使它们具有相同的优先级,或者使一个表达式具有正确的关联性,但每个表达式都不适用于某些特定的表达式。
我需要做什么?
非常感谢
去掉加号中的左递归应该可以解决这个问题。
file ::= expr*
expr ::= plus_expr | expr_
expr_ ::= array_ref_expr | const_expr
plus_expr ::= expr_ '+' expr
const_expr ::= number
array_ref_expr ::= id '[' expr ']'
expr ::= plus_expr | expr_
也可以是expr_ ('+' expr)?
,但对我来说,使用plus_expr
更有意义,这样它就可以在Psi树中获得自己的节点。