我在 ANTLR 的输出中遇到了一个小问题。 我有一个非常小的语法,如下所示:
test : states;
states : '.states' state+;
state : stateID=ID {
System.out.println("state: " + $stateID.text);
| stateID=ID '{' state* '}' {
System.out.println("SubState: " + $stateID.text);};
我想要解析的内容如下所示:
a{
b
c{
d
}
}
好吧,问题是,我得到的第一个标记是“b”,然后是“d”,然后是“c”。 但我的目的是将其解析到我的数据结构中,我需要了解他们的 parent 。 通过这个顺序我知道 c 是 d 的父级,但是 b 呢? 如果我将示例重写为这种形式:
a{
c{
d
}
b
}
一切都很好。那么有没有一种方法可以知道谁是 b 的父级,而无需在最后一个示例中编写它?
最佳答案
在 ANTLR 4 中,不再建议使用语法操作。解析器可能会以意外的顺序访问和测试不同的规则和替代方案,因此除非您添加错误处理代码,否则最好让进程正常运行,然后检查结果。
因此,您让解析器创建其树,然后编写一个自定义监听器,该监听器将在每一步发出 println
调用。例如,假设您正在使用名为 Foo
的语法,以便 ANTLR 自动生成一个 FooBaseListener
类。
所以首先你要做一些类似的事情:
public class PrintingFooListener extends FooBaseListener {
@Override
public void enterState(FooParser.StateContext ctx)
{
// It is possible to get all sorts of token/subrule/text
// information from the ctx input, especially if you labeled
// the parser/lexer rules.
System.out.println("I entered State");
}
}
然后使用 ParseTreeWalker
实用程序类与您的访问者一起在解析树中导航:
// Assume lexing, etc. already done before this point
ParserRuleContext<Token> tree = parser.myMainRule(); // Do parse
ParseTreeWalker walker = new ParseTreeWalker(); // Premade utility class
PrintingFooListener listener = new PrintingFooListener(); // Your customized subclass
walker.walk(listener, tree);
关于java - ANTLR 输出及其顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19197118/