我有以下表达式组,其中所有内容都被抛出到同一个expr
规则中:
grammar MyGrammar;
expr
: '(' expr ')'
// BoolExressions -- cannot move these out or else get Left-Recursion
| expr ('=' | '!=') expr
| expr 'AND' expr
| expr 'OR' expr
| ATOM
;
ATOM: [a-z]+ | [0-9]+;
WHITESPACE: [ trn] -> skip;
它是有效的,但我想提取boolExpression
的内容,这样我就可以单独使用它,因为我的一些其他规则必须使用布尔表达式,而不是任何表达式。然而,一旦我这样做,我就会得到一个左递归错误。
有什么好方法可以把它分解开来,这样我就可以把BooleanExpression的东西分开了?理想情况下,我希望它";看起来像这样":
grammar MyGrammar;
expr
: '(' expr ')'
| boolExpr
| ATOM
;
boolExpr
: expr ('=' | '!=') expr
| expr 'AND' expr
| expr 'OR' expr
;
ATOM: [a-z]+ | [0-9]+;
WHITESPACE: [ trn] -> skip;
// error(119): The following sets of rules are
// mutually left-recursive [expr, boolExpr]
它并不能为您提供一个boolExpr
,但您应该考虑标记的替代方案:
grammar MyGrammar;
expr
: '(' expr ')'
// BoolExressions -- cannot move these out or else get Left-Recursion
| expr ('=' | '!=') expr # compareExpr
| expr 'AND' expr # andExpr
| expr 'OR' expr # orExpr
| ATOM
;
ATOM: [a-z]+ | [0-9]+;
WHITESPACE: [ trn] -> skip;
这为每个备选方案创建了单独的*Context类,这大大降低了听众和访问者将要处理的上下文的复杂性(不过,显然会有更多的上下文(。符号也适用于每个备选方案,因此您可以执行以下操作:
grammar MyGrammar;
expr
: '(' expr ')'
// BoolExressions -- cannot move these out or else get Left-Recursion
| lhs=expr ('=' | '!=') rhs=expr # compareExpr
| lhs=expr 'AND' rhs=expr # andExpr
| lhs=expr 'OR' rhs=expr # orExpr
| ATOM
;
ATOM: [a-z]+ | [0-9]+;
WHITESPACE: [ trn] -> skip;