2016-02-24 32 views
1

我想了解ANTLR4標記,並且我有一個關於標記字符串表示的問題。考慮下面的簡單語法:ANTLR4 TokenStream,getText方法

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

難道你不能解釋爲什麼這個方法被引入。目前,我沒有看到使用它的任何有用的結果。

回答

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