【问题标题】:Spurious nondeterminism warnings from antlr 2.7.6来自 antlr 2.7.6 的虚假非确定性警告
【发布时间】:2012-02-18 18:44:17
【问题描述】:

我正在尝试使用 antlr 2.7.6 创建一个简单的表达式解析器,并且在编译期间收到了一些不确定性警告。生成的 java 源代码似乎完全按照我的意愿工作,但我想知道是否可以抑制此警告,或者我是否在语法上做错了什么。

解析器将用于已经依赖此旧 antlr 版本的项目,因此升级到 3.4 可能不是一个选项。语法本身与this answer 中的语法相似。

这是编译过程中的输出:

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     : '&' '&';

【问题讨论】:

    标签: parsing antlr antlr2


    【解决方案1】:

    奇怪,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
        ;
    

    【讨论】:

    • 谢谢,添加 EOF 修复了警告,如果允许 antlr 不消耗所有输入,那么我会看到不确定性在哪里。在 OR 令牌之前添加 options {greedy=true;}: 也会关闭警告,但您的解决方案要好得多。词法分析器规则的赋值似乎需要冒号。
    • @JörnHorstmann,啊,我明白了,不知道 v2.7 中 x:TERMINALy=production 之间的区别。
    • 嗯,我说得太早了,如果我只是添加EOF,那么表达式!(0) 将不再被解析,如果我将规则更改为NOT e=or_expr,则会返回警告。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-10-13
    • 1970-01-01
    • 1970-01-01
    • 2015-07-26
    • 1970-01-01
    • 2018-09-21
    • 2020-03-09
    相关资源
    最近更新 更多