我正在尝试将 EBNF 形式的 scala 中的后缀、中缀和前缀规则转换为 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
如果解析的表达式是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
;