Ложные недетерминированные предупреждения от antlr 2.7.6 - PullRequest
3 голосов
/ 18 февраля 2012

Я пытаюсь создать простой синтаксический анализатор выражений с помощью 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     : '&' '&';

1 Ответ

2 голосов
/ 19 февраля 2012

Странно, ANTLR 3 не имеет проблем с такой грамматикой.

Поскольку предупреждение о "выходной ветви блока", попробуйте привязка вашего правила входа с окончаниеммаркер файла (EOF):

expression returns [Expression r = null]
    : r=or_expr EOF
    ;

РЕДАКТИРОВАТЬ

Я бы включил унарное отрицательное выражение, подобное этому:

expression
    : or_expr EOF
    ;

or_expr
    : and_expr (OR and_expr)*
    ;

and_expr
    : unary_expr (AND unary_expr)*
    ;

unary_expr
    : NOT prim_expr
    | prim_expr
    ;

prim_expr
    : BOOL
    | OPEN or_expr CLOSE
    ;
...