当前位置: 首页 > 知识库问答 >
问题:

使用ANTLR4识别单行中的多行注释

百里伟
2023-03-14

我想用ANTLR4解析PostScript代码。我完成了语法,但是一个特定的语言扩展(由其他人引入)会给重新识别带来麻烦。

举个简单的例子:

1: % This is a line comment
2: % The next line just pushes the value 10 onto the stack
3: 10
4: 
5: %?description This is the special line-comment in question
6: /procedure {
7:   /var1 30 def %This just creates a variable
8:   /var2 10 def %?description A description associated with var2 %?default 20
9:   /var3 (a string value) def %?description I am even allowed to use % signs %?default (another value)
10: }

可以使用Lexer规则识别行注释,例如第1、2和7行中的注释

LINE_COMMENT: '%' .*? NEWLINE;
NEWLINE: '\r'? '\n';

只需在%之后匹配所有内容,直到行尾。

我的问题是那些特殊的行注释,它们以类似于<代码>%?说明或%?默认值,因为这些值也应该被识别,但与LINE\u注释不同,可以将多个值放在一行中(例如第8行和第9行)。那么第8行包含两条特殊注释?描述与var2和var2%相关的描述?默认值20。

把它想象成这样的东西(尽管这行不通):

SPECIAL_COMMENT: '%?' .*? (SPECIAL_COMMENT|NEWLINE);

现在是真正棘手的部分:应该允许您将任意文本放在%之后?描述包括%,同时仍然能够拆分单个注释。

简而言之,问题可以简化为拆分表单的一行

(%?<keyword> <content with % allowed in it>)+ NEWLINE

例如

%?description descr. with % in in %?default (my default value for 100%) %?rest more

进入

1.) %?description descr. with % in in 
2.) %?default (my default value for 100%)
3.) %?rest more

有什么想法吗,如何制定Lexer或Parser规则来实现这一点?

共有1个答案

拓拔阎宝
2023-03-14

根据这些规则,我认为您必须在lexer中使用谓词来检查输入流中是否出现% 。您还必须确保正常的注释必须以%开头,但后面不能跟着 (或换行符)。

根据语法:

grammar T;

@lexer::members {
  boolean ahead(String text) {
    for (int i = 0; i < text.length(); i++) {
      if (text.charAt(i) != _input.LA(i + 1)) {
        return false;
      }
    }
    return true;
  }
}

parse
 : token* EOF
 ;

token
 : t=SPECIAL_COMMENT {System.out.println("special : " + $t.getText());}
 | t=COMMENT         {System.out.println("normal  : " + $t.getText());}
 ;

SPECIAL_COMMENT
 : '%?' ( {!ahead("%?")}? ~[\r\n] )*
 ;

COMMENT
 : '%' ( ~[?\r\n] ~[\r\n]* )?
 ;

SPACES
 : [ \t\r\n]+ -> skip
 ;

可进行如下测试:

String source = "% normal comment\n" +
    "%?description I am even allowed to use % signs %?default (another value)\n" +
    "% another normal comment (without a line break!)";
TLexer lexer = new TLexer(new ANTLRInputStream(source));
TParser parser = new TParser(new CommonTokenStream(lexer));
parser.parse();

并将打印以下内容:

normal  : % normal comment
special : %?description I am even allowed to use % signs 
special : %?default (another value)
normal  : % another normal comment (without a line break!)

零件<代码>({!ahead(“%?”)}~[\r\n]*可以如下读取:如果没有“%”在前面,匹配除\r和\n以外的任何字符,并执行此操作零次或多次。

 类似资料:
  • 本文向大家介绍Perl中的单行注释和多行注释语法,包括了Perl中的单行注释和多行注释语法的使用技巧和注意事项,需要的朋友参考一下 同其他大多数编程语言一样,Perl中的单行注释也是#开头,例如: 但多行注释,不同的语言有不同的注释方式,比如说: Java,C/C++: Python: Ruby: Shell: Perl: 多行注释为: 说明:第一个等号必须紧跟一个字符! 比如说:

  • 本文向大家介绍Ruby单行和多行注释,包括了Ruby单行和多行注释的使用技巧和注意事项,需要的朋友参考一下 示例 注释是程序员可读的注释,在运行时将被忽略。它们的目的是使源代码更易于理解。 单行注释 该#字符用于添加单行注释。 执行后,上述程序将输出 你好,世界! 多行注释 可以使用=begin和=end语法(也称为注释块标记)添加多行注释,如下所示: 执行后,上述程序将输出 你好,世界!

  • 本文向大家介绍PowerShell单行注释、多行注释、块注释的方法,包括了PowerShell单行注释、多行注释、块注释的方法的使用技巧和注意事项,需要的朋友参考一下 PowerShell的注释符分为行注释符和块注释符。行注释符使用井号(#)引起一行;块注释符使用“<#”和 “#>”来引起一段注释。 行注释符 举例如下: 块注释符、多行注释 举例如下: 这是小编每次写脚本之前,都会定义的一段关于脚

  • 我正在尝试创建一个语法来解析Solr查询(只需要稍微相关,您不需要了解任何关于Solr的信息来回答这个问题--只需要比我了解更多关于ANTLR4.7的信息就可以了)。我将它建立在Solr6中的QueryParser.jj文件的基础上。我找了一个现存的,但似乎没有一个不是旧的和过时的。 我被困住了,因为当我尝试运行解析器时,我得到了“token recognition error”。 我创建的lex

  • 本文向大家介绍python使用opencv进行人脸识别,包括了python使用opencv进行人脸识别的使用技巧和注意事项,需要的朋友参考一下 环境 ubuntu 12.04 LTS python 2.7.3 opencv 2.3.1-7 安装依赖 示例代码 转换效果 原图: 转换后 使用感受 对于大部分图像来说,只要是头像是正面的,没有被阻挡,识别基本没问题,准确性还是很高的。 识别效率有点低,

  • Hi识别专家, 我有很多的mp3文件(原创音源流采样是11.025千赫)包含数字(0-9)。 不同的说话者(男性/女性)说“一”、“七”、“三”等,中间有停顿(约2-2.5秒) 我要用CMU Sphinx来识别语音(桌面应用程序)。所以我有一些问题: > 声学模型:如果不对流进行上采样/下采样,如何找到支持11025 kHz的声学模型。如果我这样做,什么是最好的数字模型? 识别模式:我发现转录有两