我是新来的,所以我希望你们能给我解释清楚。
我在ANTLR中有一个/*注释*/(BC)词法分析器,我希望它是这样的:
/* sample */ => BC
/* s
a
m
p
l
e */ => BC
"" => STRING
" " => STRING
"a" => STRING
"hello world 1" => STRING
但是我得到了这个:
/* sample */
/* s
a
m
p
l
e */ => BC
""
" "
"a"
"hello world 1" => STRING
只接受第一个/*和最后一个*/,与我的String标记相同。下面是注释的代码:
BC: '/*'.*'*/';
和字符串:
STRING: '"'(~('"')|(' '|'b'|'f'|'r'|'n'|'t'|'"'|'\'))*'"';
Lexer规则在默认情况下是贪婪的,这意味着它们试图消耗最长的匹配序列。因此,它们在最后一个结束分隔符处停止。
要使规则非贪婪,请使用非贪婪规则:
BC: '/*' .*? '*/';
这将在第一个关闭*/
时停止,这正是您需要的。
STRING也一样。请参阅The Definitive ANTLR4 Reference,第285页
您还可以使用以下代码片段而不使用非贪婪语法(更一般的解决方案):
MultilineCommentStart: '/*' -> more, mode(COMMENTS);
mode COMMENTS;
MultilineComment: '*/' -> mode(DEFAULT_MODE);
MultilineCommentNotAsterisk: ~'*'+ -> more;
MultilineCommentAsterisk: '*' -> more;