如何获取antlr4规则匹配的原文?

问题描述 投票:0回答:4

使用Java 7语法https://github.com/antlr/grammars-v4/blob/master/java7/Java7.g4我想找到具有特定名称的方法,然后打印出该方法。我发现我在匹配时可以使用

methodDeclaration
规则。所以我继承了
Java7BaseListener
并重写了这个监听器方法:

@Override public void enterMethodDeclaration(Java7Parser.MethodDeclarationContext ctx) { }

如何取出原文?

ctx.getText()
给了我一个删除了所有空格的字符串。我想要评论和原始格式。

java antlr antlr4
4个回答
61
投票

ANTLR 的

CharStream
类有一个方法
getText(Interval interval)
它将返回给定范围内的原始源。
Context
对象具有获取开始和结束的方法。假设您的侦听器中有一个名为
input
的字段,其中正在解析 CharStream,您可以执行以下操作:

    int a = ctx.start.getStartIndex();
    int b = ctx.stop.getStopIndex();
    Interval interval = new Interval(a,b);
    input.getText(interval);

13
投票

演示:

SqlBaseParser.QueryContext queryContext = context.query();
int a = queryContext.start.getStartIndex();
int b = queryContext.stop.getStopIndex();
Interval interval = new Interval(a,b);
String viewSql = context.start.getInputStream().getText(interval);

1
投票

Python实现:

def extract_original_text(self, ctx):
    token_source = ctx.start.getTokenSource()
    input_stream = token_source.inputStream
    start, stop  = ctx.start.start, ctx.stop.stop
    return input_stream.getText(start, stop)

0
投票

接受的答案在解析过程中出现错误时不起作用,antlr 修复这些错误(这是默认行为)。
默认情况下,antlr 使用

DefaultErrorStrategy
来创建带有
startIndex=endIndex=-1
的标记来缺少标记(这里 是源代码)。
如果存在此类标记,已接受答案中的代码将引发异常。

还有antlr的智能错误处理可以删除一些“额外”的标记。

因此,“匹配的文本”可以由多个原始文本块+一些没有匹配原始文本的标记组成。

此问题的一些可能的解决方案:

  • 要么使用
    ANTLRErrorStrategy
    而不进行智能错误处理(例如
    BailErrorStrategy
  • 或递归地遍历节点的子节点并仅从有效标记中收集文本。
© www.soinside.com 2019 - 2024. All rights reserved.