我正在尝试了解 ANTLR4 token ,但我对 token 字符串表示有疑问。考虑以下简单语法:
grammar Test;
init: integer IDENTIFIER;
integer: INT;
IDENTIFIER: [a-zA-Z]+;
INT: [0-9]+;
生成的解析器得到了这个:
public static class InitContext extends ParserRuleContext {
public IntegerContext integer() {
return getRuleContext(IntegerContext.class,0);
}
public TerminalNode IDENTIFIER() { return getToken(TestParser.IDENTIFIER, 0); }
public InitContext(ParserRuleContext parent, int invokingState) {
super(parent, invokingState);
}
@Override public int getRuleIndex() { return RULE_init; }
@Override
public void enterRule(ParseTreeListener listener) {
if ( listener instanceof TestListener ) ((TestListener)listener).enterInit(this);
}
@Override
public void exitRule(ParseTreeListener listener) {
if ( listener instanceof TestListener ) ((TestListener)listener).exitInit(this);
}
}
现在,在生成的监听器中,如果我们将其作为参数传递给构造函数,我们就可以使用解析器本身,如下所示:
public class TestListener extneds TestBaseListener{
private final TestParser parser;
public TestListener(TestParser parser){
this.parser = parser;
}
@Override
public void enterInit(TestParser.InitContext ctx) {
TokenStrem stream = parser.getTokenStream();
String str = stream.getText(ctx.init());
//do some with str
}
}
这个问题可能很愚蠢,但我没有看到使用 TokenStream::getText(RuleContext)
方法有任何好处。我们可以在不引入对解析器的依赖的情况下做同样的事情。只需调用 ctx.init().getText()
。
你能解释一下为什么要引入这种方法吗?目前,我没有看到使用它的任何有用结果。
最佳答案
涉及parser.getTokenStream()
然后调用stream.getText(ctx.init())
只是为了性能。与解析器关联的 token 流是一个缓存,并直接记住 InitContext
的文本。然而,通过 ctx.init().getText()
,这是从所有后代构建文本,如下面的 inplementation 所示。 :
@Override
public String getText() {
if (getChildCount() == 0) {
return "";
}
StringBuilder builder = new StringBuilder();
for (int i = 0; i < getChildCount(); i++) {
builder.append(getChild(i).getText());
}
return builder.toString();
}
关于java - ANTLR4 TokenStream,getText方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35597416/