【发布时间】:2011-11-11 23:51:23
【问题描述】:
我正在尝试将 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
;
如果我将中缀表达式规则更改为:
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
;
【问题讨论】:
-
您发布的规则不是左递归的。您能否编辑您的问题并提供一个完整的语法,我或其他人可以在不修改显示您提到的错误的情况下运行?而且我不确定“有条件地创建节点”是什么意思。而且您两次发布了
infixExpression规则(您没有更改任何内容......)。 -
不幸的是,这对语言来说是一个相当关键的早期阶段,所以我不得不对语法的全部细节保密。一旦它有了实现,我将把它开源发布