Я пытаюсь создать простой синтаксический анализатор выражений с помощью antlr 2.7.6 и получаю некоторые предупреждения недетерминированности во время компиляции. Сгенерированный java-источник работает точно так, как я хочу, но я хотел бы знать, возможно ли подавить это предупреждение или я делаю что-то не так в грамматике.
Парсер должен использоваться в проекте, который уже зависит от этой старой версии antlr, поэтому обновление до 3.4, вероятно, не вариант. Сама грамматика выглядит так же, как в этом ответе .
Вот вывод во время компиляции:
Using Antlr grammar: expr.g
ANTLR Parser Generator Version 2.7.6 (2005-12-22) 1989-2005
expr.g:15: warning:nondeterminism upon
expr.g:15: k==1:OR
expr.g:15: between alt 1 and exit branch of block
expr.g:19: warning:nondeterminism upon
expr.g:19: k==1:AND
expr.g:19: between alt 1 and exit branch of block
А вот упрощенная грамматика, демонстрирующая проблему:
header {
package net.jhorstmann.i18n.tools;
import net.jhorstmann.i18n.tools.*;
import net.jhorstmann.i18n.tools.expr.*;
}
class ExprParser extends Parser;
expression returns [Expression r = null]
: r=or_expr
;
or_expr returns [Expression r = null] { Expression e = null; }
: r=and_expr (OR e=and_expr { r = new OrExpression(r, e); })*
;
and_expr returns [Expression r = null] { Expression e = null; }
: r=prim_expr (AND e=prim_expr { r = new AndExpression(r, e); })*
;
prim_expr returns [Expression r = null] { Expression e = null; }
: b:BOOL { r = new ConstantExpression(Integer.parseInt(b.getText())); }
| NOT e=expression { r = new NotExpression(e); }
| OPEN e=expression CLOSE { r = e; }
;
class ExprLexer extends Lexer;
options {
k=2;
}
WS : (' ' | '\t')+ { $setType(Token.SKIP); };
BOOL : '0' | '1';
NOT : '!';
OPEN : '(';
CLOSE : ')';
OR : '|' '|';
AND : '&' '&';