【问题标题】:Can ANTLR return Lines of Code when lexing?词法分析时,ANTLR 可以返回代码行吗?
【发布时间】:2012-03-30 00:00:13
【问题描述】:

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

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

【问题讨论】:

  • 如果您只想知道文件中的行,您可以只运行 unix/cygwin wc。这显然与“代码行”不同,但这个数字是出了名的不稳定;每个源代码行一个标记的文件可能具有巨大的“源代码行”计数,但它不是真实的。您最好实际解析和计算类似于“语句”之类的内容,这与布局无关。
  • @IraBaxter 谢谢。 “代码行”还应包括类声明、导入语句等。我目前正在计算 LoC 在另一个传递中。我想知道我是否可以在ANTLR传递中直接轻松获得它。

标签: antlr lexical-analysis lines-of-code


【解决方案1】:

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

grammar ExistingGrammar;

// ...

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

// ...

someParserRule
 : SomeLexerRule someOtherParserRule {loc++;}
 ;

// ...

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

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

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

someParserRule
 : SomeLexerRule someOtherParserRule {loc++;}
 ;

编辑

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

    • LoC 可能不仅仅是行号:如果要求只是计算新行的数量,她/他为什么还要打扰解析器?
    • 正确的@BartKiers 但您上面给出的语法似乎不适用于 antlr4 语法。你有什么东西可以给我们准确的源代码行并忽略注释行和空白行。 ?
    【解决方案3】:

    使用访问者访问 CompilationUnit 上下文,然后 context.stop.getLine() 会给你编译单元上下文的最后行号。

    @Override public Integer visitCompilationUnit(@NotNull JAVAParser.CompilationUnitContext ctx) {
        return ctx.stop.getLine();
    }
    

    【讨论】:

    • 不,那永远不会是代码行。它也会有空行和注释行。
    猜你喜欢
    • 2015-07-20
    • 1970-01-01
    • 1970-01-01
    • 2022-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-14
    • 1970-01-01
    相关资源
    最近更新 更多