从ParserRuleContext中检索令牌列表



主要问题

是否有一种简单的方法可以从解析器规则类ParserRuleContext中获得令牌列表(理想情况下是TokenStream的形式)?

相关答案

在listener - ANTLR4中使用ParserRuleContext遍历令牌的问题的答案中出现了这个解决方案:

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

但在ANTLRv4中没有ParserRuleContext::getTokens(Token, Token)签名的方法。

我的解决方案

我考虑通过使用TokenStream:get(index: int)方法从TokenStream检索令牌列表,其中index值将设置为给定ParserRuleContext启动/停止令牌的一系列索引。

附加问题

是否有一种方法可以从TokenStream中获得另一个TokenStream形式的令牌子集?

所以,我忽略了ANTLRv4 API中的一些类和它们的接口。

回答主要问题

上述方案是正确的。BufferedTokenStreamCommonTokenStream类也有方法public List<Token> getTokens(int start, int stop),它允许从给定范围(特别是从ParserRuleContext类的开始令牌和停止令牌之间的范围)检索令牌列表

回答附加问题

可以利用ListTokenSource类实现TokenSource接口。然后通过ListTokenSource创建CommonTokenStream类。

ParserRuleRewriter代码示例

我将上面的想法封装到ParserRuleRewriter的小代码示例中——TokenStreamRewriter只重写给定的解析器规则。代码中的tokenStream参数是一个完整程序的令牌流。

import org.antlr.v4.runtime.*;
import java.util.List;
public class ParserRuleRewriter {
    private TokenStreamRewriter rewriter;
    public ParserRuleRewriter(ParserRuleContext parserRule, CommonTokenStream tokenStream) {
        Token start = parserRule.getStart();
        Token stop = parserRule.getStop();
        List<Token> ruleTokens = tokenStream.getTokens(start.getTokenIndex(), stop.getTokenIndex());
        ListTokenSource tokenSource = new ListTokenSource(ruleTokens);
        CommonTokenStream commonTokenStream = new CommonTokenStream(tokenSource);
        commonTokenStream.fill();
        rewriter = new TokenStreamRewriter(commonTokenStream);
    }
    public void replace(Token token, ParserRuleContext rule) {
        rewriter.replace(token, rule.getText());
    }
    @Override
    public String toString() {
        return rewriter.getText();
    }
}

相关内容

  • 没有找到相关文章

最新更新