我试图将EBNF格式的scala中的后缀,中缀和前缀规则转换为ANTLR,但是我看到与infixExpression规则上的左递归有关的错误。Antlr左递归
有问题的规则是:
public symbolOrID
: ID
| Symbol
;
public postfixExpression
: infixExpression symbolOrID? -> ^(R__PostfixExpression infixExpression symbolOrID?)
;
public infixExpression
: prefixExpression
| infixExpression (symbolOrID infixExpression)? -> ^(R__InfixExpression infixExpression symbolOrID? infixExpression?)
;
public prefixExpression
: prefixCharacter? simpleExpression -> ^(R__PrefixExpression prefixCharacter? simpleExpression)
;
public prefixCharacter
: '-' | '+' | '~' | '!' | '#'
;
public simpleExpression
: constant
;
如果我改变infixExpression规则:
public infixExpression
: prefixExpression (symbolOrID infixExpression)? -> ^(R__InfixExpression prefixExpression symbolOrID? infixExpression?)
;
然后它,而不是抱怨:
warning(200): Hydra.g3:108:26: Decision can match input such as "{ID, Symbol} {'!'..'#', '+', '-', '~'} String" using multiple alternatives: 1, 2
As a result, alternative(s) 2 were disabled for that input
warning(200): Hydra.g3:108:26: Decision can match input such as "{ID, Symbol} {'!'..'#', '+', '-', '~'} Number" using multiple alternatives: 1, 2
As a result, alternative(s) 2 were disabled for that input
warning(200): Hydra.g3:108:26: Decision can match input such as "{ID, Symbol} {'!'..'#', '+', '-', '~'} Boolean" using multiple alternatives: 1, 2
As a result, alternative(s) 2 were disabled for that input
warning(200): Hydra.g3:108:26: Decision can match input such as "{ID, Symbol} {'!'..'#', '+', '-', '~'} Regex" using multiple alternatives: 1, 2
As a result, alternative(s) 2 were disabled for that input
warning(200): Hydra.g3:108:26: Decision can match input such as "{ID, Symbol} {'!'..'#', '+', '-', '~'} Null" using multiple alternatives: 1, 2
As a result, alternative(s) 2 were disabled for that input
最后,有什么办法在AST中有条件地创建节点,这样如果只有规则的左边部分为真,那么它不会添加该节点级别在?例如:
conditional_or_expression:
conditional_and_expression ('||' conditional_or_expression)?
;
如,可以说我创造出如下就像一个层次的语法:
conditional_and_expression
conditional_or_expression
null_coalescing_expression
如果被解析的expresion为a || b
,目前创建的AST是这个表达式将
conditional_and_expression
conditional_or_expression
我怎么能得到它,所以它只是得到了部分conditional_or_expression
?
在JavaCC中,你可以只设置节点元数,例如:#ConditionalOrExpression(>1)
编辑:这是一个有点晚了,昨晚,现在缀表达式属性格式修改!
最后编辑:我得到它的工作进行到底的方式有以下几条规则:
public symbolOrID
: ID
| Symbol
;
public postfixExpression
: infixExpression (symbolOrID^)?
;
public infixExpression
: (prefixExpression symbolOrID)=> prefixExpression symbolOrID^ infixExpression
| prefixExpression
;
public prefixExpression
: prefixCharacter^ simpleExpression
| simpleExpression
;
public prefixCharacter
: '-' | '+' | '~' | '!' | '#'
;
public simpleExpression
: constant
;
您发布的规则不是左递归。你可以编辑你的问题,并提供一个完整的语法,我或其他人,可以运行而不修改,显示你提到的错误?我不确定“有条件地创建节点”是什么意思。你发布了'infixExpression'规则两次(你没有改变任何事情......)。 –
不幸的是,这是一个相当重要的但语言的早期阶段,所以我不得不保留语法秘密的全部细节。一旦它有一个实现,我将会释放它的开源,但是 – Darkzaelus