Parsing 来自antlr 2.7.6的虚假不确定性警告

Parsing 来自antlr 2.7.6的虚假不确定性警告,parsing,antlr,antlr2,Parsing,Antlr,Antlr2,我正在尝试使用Antlr2.7.6创建一个简单的表达式解析器,并且在编译过程中收到一些不确定性警告。生成的java源代码似乎完全按照我所希望的那样工作,但我想知道是否有可能抑制此警告,或者我是否在语法中做了一些错误的事情 解析器将用于已经依赖于这个旧antlr版本的项目中,因此升级到3.4可能不是一个选项。语法本身看起来与中的语法相似 以下是编译期间的输出: Using Antlr grammar: expr.g ANTLR Parser Generator Version 2.7.6 (2

我正在尝试使用Antlr2.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     : '&' '&';

奇怪的是,ANTLR3对这种语法没有问题

由于它警告“块的退出分支”,请尝试使用文件结束标记(
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
    ;

谢谢,添加了
EOF
修复了警告,如果允许antlr不使用所有输入,那么我就知道不确定性在哪里了。在
标记之前添加
选项{greedy=true;}:
也会关闭警告,但您的解决方案要好得多。lexer规则中的赋值似乎需要冒号。@JörnHorstmann,啊,我明白了,不知道
x:TERMINAL
y=production
之间的区别。在v2.7.Hm中,我说得太快了,如果我简单地添加
EOF
,那么表达式
!(0)
将不再被解析,如果我将规则更改为
NOT e=或_expr
将返回警告。
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
    ;