如何处理antlr4词法分析器中的嵌套注释? 即我需要计算此令牌中的"/*"数量,并在收到相同数量的"*/"后关闭。例如,D 语言具有诸如"/+ ... +/"之类的嵌套注释
。例如,以下行应被视为一个注释块:
/* comment 1
comment 2
/* comment 3
comment 4
*/
// comment 5
comment 6
*/
我当前的代码如下,它不适用于上面的嵌套注释:
COMMENT : '/*' .*? '*/' -> channel(HIDDEN)
;
LINE_COMMENT : '//' ~('n'|'r')* 'r'? 'n' -> channel(HIDDEN)
;
Terence Parr 在他的 Swift Antlr4 语法中有这两行词法分析器,用于谱写嵌套注释:
COMMENT : '/*' (COMMENT|.)*? '*/' -> channel(HIDDEN) ;
LINE_COMMENT : '//' .*? 'n' -> channel(HIDDEN) ;
我正在使用:
COMMENT: '/*' ('/'*? COMMENT | ('/'* | '*'*) ~[/*])*? '*'*? '*/' -> skip;
这会强制注释中的任何/*
成为嵌套注释的开头,与 */
类似。换句话说,除了在规则COMMENT
的开头和结尾之外,没有办法识别/*
和*/
。
这样,像 /* /* /* */ a */
这样的东西就不会像使用 COMMENT: '/*' (COMMENT|.)*? '*/' -> skip;
那样被完全识别为(错误(注释(/*
s 和 */
s 不匹配(,而是 /
,后跟 *
,后跟正确的嵌套注释/* /* */ a */
。
适用于Antlr3。
允许在注释中使用嵌套注释和"*"。
fragment
F_MultiLineCommentTerm
:
( {LA(1) == '*' && LA(2) != '/'}? => '*'
| {LA(1) == '/' && LA(2) == '*'}? => F_MultiLineComment
| ~('*')
)*
;
fragment
F_MultiLineComment
:
'/*'
F_MultiLineCommentTerm
'*/'
;
H_MultiLineComment
: r= F_MultiLineComment
{ $channel=HIDDEN;
printf(stder,"F_MultiLineComment[%s]",$r->getText($r)->chars);
}
;
我可以给你一个ANTLR3解决方案,你可以调整它以在ANTLR4中工作:
我认为您可以使用递归规则调用。为/* ... */创建一个非贪婪的注释规则,该规则调用自身。这应该允许无限嵌套,而不必计算开始+结束注释标记:
COMMENT option { greedy = false; }:
('/*' ({LA(1) == '/' && LA(2) == '*'} => COMMENT | .) .* '*/') -> channel(HIDDEN)
;
甚至可能:
COMMENT option { greedy = false; }:
('/*' .* COMMENT? .* '*/') -> channel(HIDDEN)
;
我不确定 ANTLR 是否根据任何字符或评论介绍人正确选择了正确的路径。试试吧。
- 这将处理:"/*/*/"和"/*.../*/">
- ,其中注释正文分别为"/"和".../"。 多行注释不会嵌套在单行注释中
- ,因此不能在单行注释中开始或开始多行注释。
- 这不是一个有效的注释:"/*//*/"。
- 您需要一个换行符来结束单行注释,然后才能使用"*/"来结束多行注释。
- 这是一个有效的注释:"/*//*//*/"。
- 注释正文为: '//*//'。 如您所见,完整的单行注释包含在多行注释的正文中。
尽管如果前面的字符是"*",则"/*/"可以结束多行注释,但注释将在第一个"/"> - 结束,其余的"*/"将需要结束嵌套注释,否则会出现错误。 最短路径获胜,这是不贪婪!
- 这不是一个有效的评论/****/*/ 这是一个有效的注释/*/****/
- */,注释正文是/****/,它本身就是一个嵌套注释。
- 前缀和后缀在多行注释正文中永远不会匹配。
- 如果要为"D"语言实现此功能,请将"*"更改为"+"。
COMMENT_NEST
: '/*'
( ('/'|'*'+)? ~[*/] | COMMENT_NEST | COMMENT_INL )*?
('/'|'*'+?)?
'*/'
;
COMMENT_INL
: '//' ( COMMENT_INL | ~[nr] )*
;