0

我正在尝试使用 ANTLR 来分析使用完整 Java 语法的大量代码。由于 ANTLR 需要打开所有源文件并扫描它们,我想知道它是否也可以返回代码行。

我检查了 Lexer 和 Parser 的 API,似乎它们没有返回 LoC。使用语法规则来获得 LoC 是否容易?完整的 Java 规则很复杂,我真的不想弄乱它的大部分。

4

3 回答 3

0

如果你有一个现有的 ANTLR 语法,并且想在解析过程中计算某些东西,你可以这样做:

grammar ExistingGrammar;

// ...

@parser::members {
  public int loc = 0;
}

// ...

someParserRule
 : SomeLexerRule someOtherParserRule {loc++;}
 ;

// ...

因此,每当您的 oparser 遇到 a 时someParserRule,您可以loc通过放置{loc++;}在规则之后(或之前)来增加 1。

因此,无论您对代码行的定义是什么,只需将{loc++;}其放入规则中即可增加计数器。注意不要增加两次:

statement
 : someParserRule {loc++;}
 | // ...
 ;

someParserRule
 : SomeLexerRule someOtherParserRule {loc++;}
 ;

编辑

我刚刚注意到,在您的问题标题中,您询问这是否可以在词法分析期间完成。那是不可能的。假设 LoC 总是以';'. 在词法分析期间,您将无法区分';'之后的赋值(即单个 LoC)和语句中的 2 ';'for(int i = 0; i < n; i++) { ... }不会是 2 LoC)。

于 2012-03-30T07:57:45.947 回答
0

在 C 目标中,数据结构 ANTLR3_INPUT_STREAM 有一个 getLine() 函数,它从输入流中返回当前行。这似乎是 CharStream.getLine() 的 Java 版本。您应该可以随时调用它并获取输入流中的当前行。

于 2012-03-30T20:39:46.667 回答
0

使用访问者访问 CompilationUnit 上下文,然后 context.stop.getLine() 将为您提供编译单元上下文的最后行号。

@Override public Integer visitCompilationUnit(@NotNull JAVAParser.CompilationUnitContext ctx) {
    return ctx.stop.getLine();
}
于 2015-08-18T06:34:02.373 回答