Java 在listener-ANTLR4中使用ParserRuleContext遍历令牌

Java 在listener-ANTLR4中使用ParserRuleContext遍历令牌,java,antlr,abstract-syntax-tree,antlr4,static-analysis,Java,Antlr,Abstract Syntax Tree,Antlr4,Static Analysis,在使用侦听器迭代令牌时,我想知道如何使用ParserRuleContext查看令牌流中的下一个令牌或下几个令牌 在下面的代码中,我试图查看当前令牌之后的所有令牌,直到EOF: @Override public void enterSemicolon(JavaParser.SemicolonContext ctx) { Token tok, semiColon = ctx.getStart(); int currentIndex = semiColon.getStartIn

在使用侦听器迭代令牌时,我想知道如何使用ParserRuleContext查看令牌流中的下一个令牌或下几个令牌

在下面的代码中,我试图查看当前令牌之后的所有令牌,直到EOF:

@Override 
public void enterSemicolon(JavaParser.SemicolonContext ctx) {

    Token tok, semiColon = ctx.getStart();  
    int currentIndex = semiColon.getStartIndex();
    int reqInd = currentIndex+1;
    TokenSource tokSrc= semiColon.getTokenSource();
    CharStream srcStream = semiColon.getInputStream();
    srcStream.seek(currentIndex);

    while(true){

        tok = tokSrc.nextToken() ;
        System.out.println(tok);
        if(tok.getText()=="<EOF>"){break;}
        srcStream.seek(reqInd++);
    }
}
@覆盖
public void enterSemicolon(JavaParser.SemicolonContext ctx){
令牌tok,分号=ctx.getStart();
int currentIndex=分号.getStartIndex();
int REQUIND=当前索引+1;
TokenSource tokSrc=分号。getTokenSource();
CharStream srcStream=分号.getInputStream();
srcStream.seek(currentIndex);
while(true){
tok=tokSrc.nextToken();
系统输出打印项次(tok);
if(tok.getText()==“”){break;}
seek(Requind++);
}
}
但我得到的结果是:

            .
            .
            .
            .
            .
[@-1,131:130='',<-1>,13:0]
[@-1,132:131='',<-1>,13:0]
[@-1,133:132='',<-1>,13:0]
[@-1,134:133='',<-1>,13:0]
[@-1,135:134='',<-1>,13:0]
[@-1,136:135='',<-1>,13:0]
[@-1,137:136='',<-1>,13:0]
[@-1,138:137='',<-1>,13:0]
[@-1,139:138='',<-1>,13:0]
[@-1,140:139='',<-1>,13:0]
[@-1,141:140='',<-1>,13:0]
[@-1,142:141='',<-1>,13:0]
[@-1,143:142='',<-1>,13:0]
[@-1,144:143='',<-1>,13:0]
[@-1,145:144='',<-1>,13:0]
[@-1,146:145='',<-1>,13:0]
[@-1,147:146='',<-1>,13:0]
[@-1,148:147='',<-1>,13:0]
[@-1,149:148='',<-1>,13:0]
[@-1,150:149='',<-1>,13:0]
[@-1,151:150='',<-1>,13:0]
[@-1,152:151='',<-1>,13:0]
[@-1,153:152='',<-1>,13:0]
[@-1,154:153='',<-1>,13:0]
[@-1,155:154='',<-1>,13:0]
[@-1,156:155='',<-1>,13:0]
[@-1,157:156='',<-1>,13:0]
[@-1,158:157='',<-1>,13:0]
[@-1,159:158='',<-1>,13:0]
[@-1,160:159='',<-1>,13:0]
[@-1,161:160='<EOF>',<-1>,13:0]
[@-1,137:136='',<-1>,13:0]
[@-1,138:137='',<-1>,13:0]
[@-1,139:138='',<-1>,13:0]
[@-1,140:139='',<-1>,13:0]
[@-1,141:140='',<-1>,13:0]
[@-1,142:141='',<-1>,13:0]
[@-1,143:142='',<-1>,13:0]
[@-1,144:143='',<-1>,13:0]
[@-1,145:144='',<-1>,13:0]
[@-1,146:145='',<-1>,13:0]
[@-1,147:146='',<-1>,13:0]
[@-1,148:147='',<-1>,13:0]
[@-1,149:148='',<-1>,13:0]
[@-1,150:149='',<-1>,13:0]
[@-1,151:150='',<-1>,13:0]
[@-1,152:151='',<-1>,13:0]
[@-1,153:152='',<-1>,13:0]
[@-1,154:153='',<-1>,13:0]
[@-1,155:154='',<-1>,13:0]
[@-1,156:155='',<-1>,13:0]
[@-1,157:156='',<-1>,13:0]
[@-1,158:157='',<-1>,13:0]
[@-1,159:158='',<-1>,13:0]
[@-1,160:159='',<-1>,13:0]
[@-1,161:160='<EOF>',<-1>,13:0]
            .
            .
            .
            .
。
.
.
.
.
[@-1,131:130='',,13:0]
[@-1,132:131='',,13:0]
[@-1,133:132='',,13:0]
[@-1,134:133='',,13:0]
[@-1,135:134='',,13:0]
[@-1,136:135='',,13:0]
[@-1,137:136='',,13:0]
[@-1,138:137='',,13:0]
[@-1,139:138='',,13:0]
[@-1,140:139='',,13:0]
[@-1,141:140='',,13:0]
[@-1,142:141='',,13:0]
[@-1,143:142='',,13:0]
[@-1,144:143='',,13:0]
[@-1,145:144='',,13:0]
[@-1,146:145='',,13:0]
[@-1,147:146='',,13:0]
[@-1,148:147='',,13:0]
[@-1,149:148='',,13:0]
[@-1,150:149='',,13:0]
[@-1,151:150='',,13:0]
[@-1,152:151='',,13:0]
[@-1,153:152='',,13:0]
[@-1,154:153='',,13:0]
[@-1,155:154='',,13:0]
[@-1,156:155='',,13:0]
[@-1,157:156='',,13:0]
[@-1,158:157='',,13:0]
[@-1,159:158='',,13:0]
[@-1,160:159='',,13:0]
[@-1,161:160='',,13:0]
[@-1,137:136='',,13:0]
[@-1,138:137='',,13:0]
[@-1,139:138='',,13:0]
[@-1,140:139='',,13:0]
[@-1,141:140='',,13:0]
[@-1,142:141='',,13:0]
[@-1,143:142='',,13:0]
[@-1,144:143='',,13:0]
[@-1,145:144='',,13:0]
[@-1,146:145='',,13:0]
[@-1,147:146='',,13:0]
[@-1,148:147='',,13:0]
[@-1,149:148='',,13:0]
[@-1,150:149='',,13:0]
[@-1,151:150='',,13:0]
[@-1,152:151='',,13:0]
[@-1,153:152='',,13:0]
[@-1,154:153='',,13:0]
[@-1,155:154='',,13:0]
[@-1,156:155='',,13:0]
[@-1,157:156='',,13:0]
[@-1,158:157='',,13:0]
[@-1,159:158='',,13:0]
[@-1,160:159='',,13:0]
[@-1,161:160='',,13:0]
.
.
.
.

我们看到,尽管我能够遍历所有令牌直到EOF,但我无法获得令牌的实际内容或类型。我想知道是否有一种使用侦听器遍历的简洁方法。

很难确定,但是

tok = tokSrc.nextToken() ;
似乎正在重新运行lexer,从假定的正确令牌边界开始,但没有重置lexer。lexer抛出错误可以解释观察到的行为

不过,更好的方法是简单地恢复现有令牌流:

public class Walker implements YourJavaListener {

    CommonTokenStream tokens;

    public Walker(JavaParser parser) {
        tokens = (CommonTokenStream) parser.getTokenStream()
    }
然后访问流以获取所需的令牌:

@Override 
public void enterSemicolon(JavaParser.SemicolonContext ctx) {
    TerminalNode semi = ctx.semicolon(); // adjust as needed for your impl.
    Token tok = semi.getSymbol();
    int idx = tok.getTokenIndex();

    while(tok.getType() != IntStream.EOF) {
        System.out.println(tok);
        tok = tokens.get(idx++);
    }
}
一种完全不同的方法可能会满足您的最终目的,即直接从父上下文获取有限的令牌集:

ParserRuleContext pctx = ctx.getParent();
List<TerminalNode> nodes = pctx.getTokens(pctx.getStart(), pctx.getStop());
ParserRuleContext pctx=ctx.getParent();
列表节点=pctx.getTokens(pctx.getStart(),pctx.getStop());

备注:ANTLRv4中没有签名为
ParserRuleContext::getTokens(令牌,令牌)
的方法。