ANTLR4 TokenStream,getText方法

时间:2016-02-24 08:54:49

标签: java token antlr4

我正在尝试理解ANTLR4令牌,我有一个关于令牌字符串表示的问题。请考虑以下简单语法:

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()

你不能解释为什么引入这种方法。目前,我认为没有任何有用的使用方法。

1 个答案:

答案 0 :(得分:3)

涉及parser.getTokenStream()然后调用stream.getText(ctx.init())只是为了提高性能。与解析器关联的令牌流是缓存,并直接记住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();
}