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

与以#开头的注释行匹配的ANTLR语法

卫烨烁
2023-03-14

我正在尝试将下面的文本与ANTLR语法匹配:

ANTLR语法是:

grammar header;


start : commentBlock
        EOF;

commentBlock : CommentLine+;
CommentLine  : '#' AsciiChars+;
AsciiChars : [a-zA-Z];

fragment CR : '\r';
fragment LF : '\n';
EOL : CR?LF ->skip;

fragment Tab : '\t';
fragment Space : ' ';
TS : (Tab|Space)+ ->skip;

我得到的错误是:

line 1:0 token recognition error at: '# '
line 2:0 token recognition error at: '# '
line 3:0 token recognition error at: '# '
[@0,2:2='a',<AsciiChars>,1:2]
[@1,7:7='b',<AsciiChars>,2:2]
[@2,12:12='c',<AsciiChars>,3:2]
[@3,15:14='<EOF>',<EOF>,4:0]
line 1:2 mismatched input 'a' expecting CommentLine

我猜语法是合理的,但为什么会出现错误呢?

grammar header;

start : commentBlock
        EOF;

commentBlock : commentLine+;
commentLine  : '#' AsciiChars+; // <=== here CommentLine -> commentLine
AsciiChars : [a-zA-Z];

fragment CR : '\r';
fragment LF : '\n';
EOL : CR?LF ->skip;

fragment Tab : '\t';
fragment Space : ' ';
TS : (Tab|Space)+ ->skip; 
    null

要匹配的文档:

#   abc

语法1:

grammar test;

t : T2;
p : t
    EOF;

Char : [a-z];

T2 : '#' T1+ Char+; // <<<< Here T2 reference the so-skipped T1.

fragment Tab : '\t';
fragment Space : ' ';
T1 : (Tab|Space)+ ->skip; //<<<<< T1 is to be skipped.

在语法1中,跳过了T1,但不跳过T2中的T1部分。T2将在lexer阶段匹配输入文本。(即使我们把T2放在T1之后,T2还是会匹配的。我认为ANTLR为了最长的令牌做了一些贪婪的匹配。)

grammar test;

t : '#' T1+ Char+; // <<<<<<<<<<<< HERE
p : t
    EOF;

Char : [a-z];

fragment Tab : '\t';
fragment Space : ' ';
T1 : (Tab|Space)+ ->skip; //<<<<< T1 is to be skipped.
[@0,0:0='#',<'#'>,1:0]
[@1,4:4='a',<Char>,1:4]
[@2,5:5='b',<Char>,1:5]
[@3,6:6='c',<Char>,1:6]
[@4,7:6='<EOF>',<EOF>,1:7]
line 1:4 mismatched input 'a' expecting T1

因此,正如@macmoonshine所说,我确实必须将ts添加到commentline令牌中。

共有1个答案

充高扬
2023-03-14

您的语法在注释中不包含空格,但您的注释包含空格。

编辑:您是否尝试将commentline:“#'TS asciichars;作为注释规则?

 类似资料:
  • 我正在为每个测试方法构建一个模块,该模块在测试方法开始执行之前侦听TestNG测试并执行某些操作。我只想知道测试(方法)何时开始执行,方法的名称和测试类的可选名称。 我成功地为testNG的调用程序调用编写了切入点。它成功了。 相反,我想知道的是,每个测试方法都用org注释。测试NG。注释。Test,我如何编写切入点来捕捉用org注释的每个测试方法的执行连接点。测试NG。注释。测试? 这是我的测试

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

  • 我得到了这个解析器语法,我还想用它来使用类似于Javascript模板的东西-字符串。 这个lexer语法 我不明白,为什么甚至可以匹配一些像空映射或像“world`”这样的映射,因为映射需要在中间有一个“:”。并且为什么规则模板字符串不匹配整个“Hello World”从一个滴答到另一个滴答? 编辑: 当我注意到Lexer没有被重新生成时,我得到了这样的错误:“不能为string literal

  • 问题内容: 我有一个在Java 6 / Spring 3中实现的服务类,该服务类需要注释以按角色限制访问。 我定义了一个名为RequiredPermission的注释,该注释具有一个名为OperationType的枚举中的一个或多个值作为其value属性: 我还具有以下方面定义: 参数对象包含一个用户名,在允许访问该方法之前,我想为用户查找所需的角色。 当我将注释放在MyServiceImpl中的

  • 我为计算表达式编写了一个非常简单的语法定义: 我尝试了无效表达式by,但它通过了。看起来字符被忽略了。这里有什么问题?

  • 问题内容: 我有一个带有某些配置值的文本文件。以#开头的注释我试图找到一个正则表达式模式,该模式将找出以#开头的所有行。 因此,示例文件: 我想找到 因为只有这两行以#开头,所以我尝试了以下代码: 但是它总是输出空数组。有人可以帮忙吗? 问题答案: 你忘了多修饰符(你应该 不 使用单线改性剂;也是不区分大小写的修饰符是不必要的,因为还有ungreedy修改): 说明: 允许and 在行的开头/结尾