如何让这个生产更"模块化"



我有以下表达式组,其中所有内容都被抛出到同一个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;

相关内容

  • 没有找到相关文章

最新更新