У меня есть грамматика, которая может анализировать выражения типа 1+2-4
или 1+x-y
, создавая соответствующую структуру «на лету», которая позже дала Map<String, Integer>
с соответствующим контентом, может быть оценена численно (после завершения синтаксического анализа, то есть для x
или y
, известных только позже).Параметр antlr rule boolean появляется в синтаксическом предикатном коде на один уровень выше, вызывая ошибки компиляции
Внутри грамматики есть также места, где должно выполняться выражение, которое может быть оценено на месте, то есть не содержит переменных. Я полагал, что я мог разобрать их с той же логикой, добавив булево значение variablesAllowed
правилу, например, так:
grammar MiniExprParser;
INT : ('0'..'9')+;
ID : ('a'..'z'| 'A'..'Z')('a'..'z'| 'A'..'Z'| '0'..'9')*;
PLUS : '+';
MINUS : '-';
numexpr returns [Double val]:
expr[false] {$val = /* some evaluation code */ 0.;};
varexpr /*...*/:
expr[true] {/*...*/};
expr[boolean varsAllowed] /*...*/:
e=atomNode[varsAllowed] {/*...*/}
(PLUS e2=atomNode[varsAllowed] {/*...*/}
|MINUS e2=atomNode[varsAllowed] {/*...*/}
)* ;
atomNode[boolean varsAllowed] /*...*/:
(n=INT {/*...*/})
|{varsAllowed}?=> ID {/*...*/}
;
result:
(numexpr) => numexpr {System.out.println("Numeric result: " + $numexpr.val);}
|varexpr {System.out.println("Variable expression: " + $varexpr.text);};
Однако сгенерированный Java код не компилируется. В части, явно ответственной за синтаксический предикат окончательного правила, происходит varsAllowed
, хотя переменная никогда не определяется на этом уровне.
/* ... */
else if ((LA3_0==ID) && ((varsAllowed))) {
int LA3_2 = input.LA(2);
if (((synpred1_MiniExprParser()&&(varsAllowed)))) {
alt3=1;
}
else if (((varsAllowed))) {
alt3=2;
}
/* ... */
Я использую его неправильно? (Я использую Eclipse 'AntlrIDE 2.1.2 с Antlr 3.5.2.)
Я бы рекомендовал против написания действий. Если вы хотите сделать оптимизацию, выполните дополнительный проход в дереве обозревателя синтаксического анализа, возможно, создав промежуточный код. – Mephy