我需要解析一个小的表达式语言(而且,或者,不是,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=>
如果我能弄清楚为什么这会出现在应该是好的语法中,我应该能够找出为什么同样的事情发生在我的语法中(非常相似的概念)。
任何人都可以提供任何见解吗?
答案 0 :(得分:5)
打印出令牌后,您将位于令牌流的末尾。您需要通过调用
重置令牌流lex.reset();
这将使词法分析器返回到令牌流的开头,以便您可以调用解析器。