以下规则集是相互左递归的 [valeur booleene, valeur]
我知道ANTLR可以很好地处理左递归规则,但只能在一个规则中处理,而不是在规则之间。
我必须重写我的规则来解决相互左递归的问题,但我看不出如何......
grammar minimal;
constante:
bool = BOOLEAN
| intgr = INTEGER
;
valeurBooleene:
'(' val = valeurBooleene ')'
| bool = BOOLEAN
| 'non' not = valeur
| leftValue = valeur '=' rightValue = valeur
;
valeur:
'(' val = valeur ')'
| cst = constante
| booleanValue = valeurBooleene
| '|' absolute = valeur '|'
| '-' opposite = valeur
;
condition:
'(' cond = condition ')'
| bool = valeurBooleene
;
si:
'Si' cond = condition 'alors' ( thenActions += action )+
( 'sinon' ( elseActions += action )+ )?
;
system:
( actions += action )+
EOF
;
action:
ifClause = si
;
BOOLEAN:
'false'
| 'true'
| 'faux'
| 'vrai'
;
INTEGER:
[0-9]+
;
WS:
[ ntr]+ -> skip
;
最后,我遵循 sepp2k 提供的建议,如下所示:
grammar minimal;
value:
'(' val = value ')' # Parenthesis
| b = BOOLEAN # Boolean
| 'non' not = value # Boolean
| l = value '=' r = value # Boolean
| i = INTEGER # Numeric
| '|' abs = value '|' # Numeric
| '-' opposite = value # Numeric
;
condition:
'(' condition ')'
| cond = value
;
ifStmnt:
'IF' condition 'THEN' ( actionsThen += action )+
( 'ELSE' ( actionsElse += action )+ )?
;
system:
( actions += action )+
EOF
;
print:
'print' val = value
;
action:
ifs = ifStmnt
| pr = print
;
BOOLEAN:
'false'
| 'true'
;
INTEGER:
[0-9]+
;
WS:
[ ntr]+ -> skip
;
标签创建扩展 ValueContext 的类,我像这样使用它们:
package com.thalesgroup.dms.stimulus.factories;
import minimal.minimalParser.BooleanContext;
import minimal.minimalParser.ConditionContext;
import minimal.minimalParser.NumericContext;
import minimal.minimalParser.ParenthesisContext;
import minimal.minimalParser.ValueContext;
public class Sample {
void analyze( ValueContext ctxt ) {
if( ctxt instanceof ParenthesisContext ) {
analyze(((ParenthesisContext)ctxt).val );
}
else if( ctxt instanceof BooleanContext ) {
final BooleanContext bc = (BooleanContext)ctxt;
analyze( bc );
}
else if( ctxt instanceof NumericContext ) {
final NumericContext nc = (NumericContext)ctxt;
analyze( nc );
}
}
void analyze( ConditionContext ctxt ) {
if( ctxt.cond instanceof BooleanContext ) {
final BooleanContext boolCtxt = (BooleanContext)ctxt.cond;
// build a condition from a BooleanContext
analyze( boolCtxt );
}
else {
throw new IllegalStateException();
}
}
void analyze( BooleanContext ctxt ) {
if( ctxt.b != null ) {
final String literal = ctxt.b.getText();
if( literal.equals( "true" )) {
// deal with a boolean literal 'true'
}
else if( literal.equals( "false" )) {
// deal with a boolean literal 'false'
}
}
else if( ctxt.not != null ) {
final BooleanContext bCtxt = (BooleanContext)ctxt.not;
// deal with a 'not' operation
}
else if( ctxt.l != null ) {
final ValueContext left = ctxt.l;
final ValueContext right = ctxt.r;
// deal with 'equals'
}
else {
// ???
}
}
void analyze( NumericContext ctxt ) {
if( ctxt.abs != null ) {
// deal with abs( x )
}
else if( ctxt.opposite != null ) {
// deal with - x
}
else if( ctxt.i != null ) {
// deal with literal integer
}
}
}