所有ANTLR语法都会产生错误“在输入'<eof>'</eof>时没有可行的替代方法

时间:2011-09-07 14:44:14

标签: parsing antlr antlr3

我需要解析一个小的表达式语言(而且,或者,不是,parens改变优先级)所以选择了ANTLR来完成任务,我取得了很好的进展(ANTLRWorks对于新手非常好)。我在antlr网站上使用了一些Getting Starting引用,然后发现了两篇完全适合我想要完成的博客文章:

http://www.codeproject.com/KB/recipes/sota_expression_evaluator.aspx http://www.alittlemadness.com/2006/06/05/antlr-by-example-part-1-the-language

我遇到的问题是无论我输入什么输入我总是得到错误:

第1:29行在输入'EOF'时没有可行的选择

因此,作为我的故障排除的一部分,我决定尝试一种我认为很好的语法,并从第一个链接中找到的ECalc.g语法生成一个词法分析器/解析器。令我惊讶的是,在使用该语法时我遇到了同样的错误!我很生气。我对语法的唯一改变是让它生成Java代码并在@members部分中取出一些CSharp代码。

这是我的测试人员类:

public class ECalcTester {
private final static Logger logger = Logger.getLogger(ECalcTester.class);

public static void main(String[] args) {
    BasicConfigurator.configure();
    ECalcLexer lex = new ECalcLexer(new ANTLRStringStream("false || not (false and true)"));

    Token token;
    while (true) {
        token = lex.nextToken();
        if (token.getType() == Token.EOF) {
            break;
        }

        System.out.println("Token: ‘" + token.getText() + "’");
    }

    CommonTokenStream tokens = new CommonTokenStream(lex);
    lex.nextToken();

    ECalcParser parser = new ECalcParser(tokens);
    try {
        logger.debug(parser.expression().getTree());
    } catch (org.antlr.runtime.RecognitionException e) {
        logger.error("Exception ", e);
    }

}

这是输出:

Token: ‘false’
Token: ‘ ’
Token: ‘||’
Token: ‘ ’
Token: ‘not’
Token: ‘ ’
Token: ‘(’
Token: ‘false’
Token: ‘ ’
Token: ‘and’
Token: ‘ ’
Token: ‘true’
Token: ‘)’
line 1:29 no viable alternative at input '<EOF>'
0 [main] DEBUG ECalcTester  - <unexpected: [@0,29:29='<EOF>',<-1>,1:29], resync=>

如果我能弄清楚为什么这会出现在应该是好的语法中,我应该能够找出为什么同样的事情发生在我的语法中(非常相似的概念)。

任何人都可以提供任何见解吗?

1 个答案:

答案 0 :(得分:5)

打印出令牌后,您将位于令牌流的末尾。您需要通过调用

重置令牌流
lex.reset();

这将使词法分析器返回到令牌流的开头,以便您可以调用解析器。