在使用侦听器迭代令牌时,我想知道如何使用 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++);
}
}
但我得到的输出是:
.
.
.
.
.
[@-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]
.
.
.
.
我们看到,尽管我能够在EOF之前遍历所有令牌,但我无法获得令牌的实际内容或类型。我想知道是否有一种巧妙的方法可以使用侦听器遍历来做到这一点。
很难
确定,但是
tok = tokSrc.nextToken() ;
似乎正在重新运行词法分析器,从假定的正确标记边界开始,但没有重置词法分析器。词法分析器抛出错误可能会解释观察到的行为。
不过,更好的方法是简单地恢复现有的令牌流:
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());