Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Parsing 如何使用ANTLRv4只解析一些注释_Parsing_Comments_Antlr_Antlr4 - Fatal编程技术网

Parsing 如何使用ANTLRv4只解析一些注释

Parsing 如何使用ANTLRv4只解析一些注释,parsing,comments,antlr,antlr4,Parsing,Comments,Antlr,Antlr4,我使用ANTLRv4开发分析Java源代码的应用程序。我声明将所有单行注释与第一个标记TODO(例如//TODO)以及直接下面的语句匹配 示例代码: class Simple { public static void main(String[] args) { // TODO develop cycle for (int i = 0; i < 5; i++) { // unmatched comment

我使用ANTLRv4开发分析Java源代码的应用程序。我声明将所有单行注释与第一个标记
TODO
(例如
//TODO
)以及直接下面的语句匹配

示例代码:

class Simple {
    public static void main(String[] args) {
        // TODO develop cycle
        for (int i = 0; i < 5; i++) {
            // unmatched comment
            System.out.println("hello");
        }
        // TODO atomic
        int a;

        // TODO revision required
        {
            int b = a+4;
            System.out.println(b);
        }
    }
}
下面是关于stackoverflow(,)的类似主题,我尝试了几种方法

起初,我希望看到如和中所述的特殊注释通道,但错误
规则“LINE_COMMENT”包含一个带有无法识别的常量值的lexer命令;lexer解释器可能产生不正确的输出

我想最好是以忽略所有单行注释的方式解析源代码,但以
TODO
开头的注释除外。我希望可以将todo注释直接添加到AST中,以便使用侦听器/漫游器。然后,我只需要注册listener/walker进行TODO注释,并提取以下语句,将这两个语句添加到所需的映射中

我已经修改官方文件两天了,但没有成功。编译器抱怨或AST不匹配

这是我所做的更新:

// ...
COMMENT
    :   '/*' .*? '*/' -> skip
    ;

TODO_COMMENT
    :   '// TODO' ~[\r\n]*
    ;

LINE_COMMENT
    :   '//' ~[\r\n]* -> skip
    ;
有人能帮我吗?语法不是我喜欢的。提前谢谢

EDIT1:

class Simple {
    public static void main(String[] args) {
        // TODO develop cycle
        for (int i = 0; i < 5; i++) {
            // unmatched comment
            System.out.println("hello");
        }
        // TODO atomic
        int a;

        // TODO revision required
        {
            int b = a+4;
            System.out.println(b);
        }
    }
}
上面发布的语法修改没有错误,但生成了以下树(请注意红色标记的节点,包括
int

EDIT2:

class Simple {
    public static void main(String[] args) {
        // TODO develop cycle
        for (int i = 0; i < 5; i++) {
            // unmatched comment
            System.out.println("hello");
        }
        // TODO atomic
        int a;

        // TODO revision required
        {
            int b = a+4;
            System.out.println(b);
        }
    }
}
假设上面的代码示例,同时调用
parser.compilationUnit()生成以下错误

line 3:2 extraneous input '// TODO develop cycle;' expecting {'abstract', 'assert', 'boolean', 'break', 'byte', 'char', 'class', 'continue', 'do', 'double', 'enum', 'final', 'float', 'for', 'if', 'int', 'interface', 'long', 'new', 'private', 'protected', 'public', 'return', 'short', 'static', 'strictfp', 'super', 'switch', 'synchronized', 'this', 'throw', 'try', 'void', 'while', IntegerLiteral, FloatingPointLiteral, BooleanLiteral, CharacterLiteral, StringLiteral, 'null', '(', '{', '}', ';', '<', '!', '~', '++', '--', '+', '-', Identifier, '@'}
line 8:2 extraneous input '// TODO atomic;' expecting {'abstract', 'assert', 'boolean', 'break', 'byte', 'char', 'class', 'continue', 'do', 'double', 'enum', 'final', 'float', 'for', 'if', 'int', 'interface', 'long', 'new', 'private', 'protected', 'public', 'return', 'short', 'static', 'strictfp', 'super', 'switch', 'synchronized', 'this', 'throw', 'try', 'void', 'while', IntegerLiteral, FloatingPointLiteral, BooleanLiteral, CharacterLiteral, StringLiteral, 'null', '(', '{', '}', ';', '<', '!', '~', '++', '--', '+', '-', Identifier, '@'}
line 11:2 extraneous input '// TODO revision required;' expecting {'abstract', 'assert', 'boolean', 'break', 'byte', 'char', 'class', 'continue', 'do', 'double', 'enum', 'final', 'float', 'for', 'if', 'int', 'interface', 'long', 'new', 'private', 'protected', 'public', 'return', 'short', 'static', 'strictfp', 'super', 'switch', 'synchronized', 'this', 'throw', 'try', 'void', 'while', IntegerLiteral, FloatingPointLiteral, BooleanLiteral, CharacterLiteral, StringLiteral, 'null', '(', '{', '}', ';', '<', '!', '~', '++', '--', '+', '-', Identifier, '@'}

第3行:2个无关输入'//TODO开发周期;'期望{'abstract','assert','boolean','break','byte','char','class','continue','do','double','enum','final','float','for','if','int','interface','long','new','private','protected','public','return short','static','stricfp','super','switch','synchronized','this','throw','tLiteral、BooleanLiteral、CharacterLiteral、StringLiteral、'null'、'('、'{'、'}'、';'、'原因是您不希望在任何解析器规则中使用特殊注释,即没有解析器会匹配它

您可以(至少)执行以下操作:

  • 在每个解析器规则前面添加可选的
    TODO_注释
  • TODO_COMMENT
    标记添加到单独的通道中,例如
    ToDoCommentChannel
    (不要忘记定义此通道的常量!),并在树遍历中选择注释后面的每个构造
  • 大致概述我将要做的事情:

    • 为待办事项注释使用单独的频道
    • lex和parse都像往常一样
    • 从令牌流中获取所有令牌,并找到所需通道的令牌,在默认通道上获取以下令牌,并将其存储在列表中
    • 如果起始标记在列表中,则遍历分析并检查每个输入的规则。如果是,则将规则文本复制到结果列表中,否则将递归(如果
      TODO_COMMENT
      可以嵌套,甚至在起始标记在列表中时递归)
    更新:

    关于
    规则“LINE\u COMMENT”包含具有无法识别的常量值的lexer命令;lexer解释器可能会产生不正确的输出
    错误:

    这可以忽略,因为它只影响Antlrworks2或插件使用的解释器。您也可以这样做:

    "develop cycle" -> for(...){...}
    "atomic" -> int a
    "revision required" -> {...}
    
    //Instead of
    TODO_COMMENT
        :   '// TODO' ~[\r\n]*  -> channel(ToDoCommentChannel)
        ;    
    
    // do this (assuming the channel value is indeed 42):
    TODO_COMMENT
        :   '// TODO' ~[\r\n]*  -> channel(42 /*ToDoCommentChannel*/)
        ;    
    

    这将在Antlrworks2和代码中都起作用(您仍然可以在java运行时代码中使用通道的常量值).

    你从上面的语法摘录中得到的确切错误是什么?出现了什么类型的不匹配?@U编辑完成后,请查看提供的方案-为什么还标记了
    int
    ?@ptrbel对我来说这看起来非常正确。int不是
    //TODO xxx
    的一部分,而是在下一个块语句子段中直接跟随它ree.据我所知,这似乎是我想要的结果。你期望的结果是什么?@UweAllner例如,ANTLR没有生成
    Java8BaseVisitor::visitTODO_注释
    -我如何在没有visitor的情况下直接匹配下面的语句?我怎么只标记int,因为它直接跟在“extra”后面<代码> TodoyPosie。我会忽略这个错误,特别是因为错误消息没有报告<代码> int <代码>的错误。通道工作正常,但我打算与TODOs一起作为AST节点工作。但是,我认为这个问题是关闭的,谢谢大家的帮助:)如果你想要它们作为节点(我真的不知道为什么你应该这样做),使用选项1并将它们放在可能出现的每个位置的前面。