如何使用ANTLR创建建议消息?

时间:2013-11-11 12:10:14

标签: antlr interactive

我想创建一个ANTLR calculator example的交互式版本,告诉用户下一步要键入什么。例如,在开始时,IDINTNEWLINEWS令牌是可能的。忽略WS,建议消息可能是:

Type an identifier, a number, or newline.

解析数字后,该消息应为

Type +, -, *, or newline.

等等。怎么做?

修改

到目前为止我尝试过:

private void accept(String sentence) {
    ANTLRInputStream is = new ANTLRInputStream(sentence);
    OperationLexer l = new OperationLexer(is);
    CommonTokenStream cts = new CommonTokenStream(l);
    final OperationParser parser = new OperationParser(cts);
    parser.addParseListener(new OperationBaseListener() {
        @Override
        public void enterEveryRule(ParserRuleContext ctx) {
            ATNState state = parser.getATN().states.get(parser.getState());
            System.out.print("RULE " + parser.ruleNames[state.ruleIndex] + " ");
            IntervalSet following = parser.getATN().nextTokens(state, ctx);
            for (Integer token : following.toList()) {
                System.out.print(parser.tokenNames[token] + " ");
            }
            System.out.println();
        }
    });
    parser.prog();
}

为第一个令牌打印正确的建议,但对于所有其他令牌,它会打印当前令牌。我想在enterEveryRule()捕捉状态太早了。

1 个答案:

答案 0 :(得分:1)

在LL(k)解析器中准确收集此信息,其中k> 1,需要彻底了解解析器内部。几年前,我遇到了ANTLR 3的这个问题,发现唯一真正的解决方案是如此复杂,导致我成为ANTLR 4 的特别的共同作者,所以我可以处理这个问题。 / p>

ANTLR(包括ANTLR 4)在解析阶段消除解析树的歧义,这意味着如果您的语法不是LL(1),那么在解析树中执行此分析意味着您已经丢失了准确所需的信息。您需要编写自己的ParserATNSimulator版本(或包装它的自定义解释器),它不会丢失信息。