从 ParserRuleContext 中检索标记列表

Retrieve token list from ParserRuleContext

主要问题

有没有简单的方法从解析器规则 class ParserRuleContext 中获取标记列表(最好是 TokenStream 的形式)?

相关回答

在问题的回答中出现了这个解决方案:

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 的一系列索引start/stop 个代币。

附加问题

有没有办法以另一个 TokenStream 的形式从 TokenStream 获取令牌子集?

所以,我在 ANTLRv4 API.

中忽略了一些 classes 和它们的接口

主要问题的答案

以上建议的解决方案是正确的。 BufferedTokenStreamCommonTokenStream classes 有方法 public List<Token> getTokens(int start, int stop) 允许从给定范围(特别是从 [= 的开始标记和停止标记之间的范围)检索标记列表14=] class)

附加问题的答案

您可以利用 ListTokenSource class 实现了 TokenSource 接口。然后你可以通过 ListTokenSource.

创建 CommonTokenStream class

ParserRuleRewriter 代码示例

我将上述想法封装到具有 ParserRuleRewriter 的小代码示例中 - TokenStreamRewriter 仅重写给定的解析器规则。代码中tokenStream参数是完整程序的token流

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