用于 C 风格注释的 ANTLR 词法分析器
ANTLR lexer for C-style comment
我目前正在研究支持 C 风格注释的 ANTLR 词法分析器规则。对于这样的目标,有一个广泛推荐的规则:
C_COMMENT
:
'/*' (options {greedy=false;}: .)* '*/'
{ $channel=HIDDEN; }
;
然而我想要的是另一种选择:“+”不允许成为评论正文的第一个非 space 字符,例如/* +blablabla*/ 不是有效的注释。
然后我尝试了这样的事情:
C_COMMENT
:
'/*' (' '|'\r'|'\t'|'\n')* ~(' '|'\r'|'\t'|'\n'|'+') (options {greedy=false;}: .)* '*/'
{ $channel=HIDDEN; }
;
它几乎成功了,除了空注释 /* */。所以我尝试了这样的事情:
C_COMMENT
:
'/*' (' '|'\r'|'\t'|'\n')*
(
'*/'
|
(~(' '|'\r'|'\t'|'\n'|'+') (options {greedy=false;}: .)* '*/')
)
{ $channel=HIDDEN; }
;
它和我没有列出的一堆类似的东西从来没有用过。 /* */ 中的 * / 总是属于 ~(' '|'\r'|'\t'|'\n'|'+') 部分。
最后我得到了这样的东西:
C_COMMENT
:
'/*' (' '|'\r'|'\t'|'\n')* '*/'
{ $channel=HIDDEN; }
|
'/*' (' '|'\r'|'\t'|'\n')*
(
'*/'
|
(~(' '|'\r'|'\t'|'\n'|'+') (options {greedy=false;}: .)* '*/')
)
{ $channel=HIDDEN; }
;
尽管 ANTLR 警告像 /* */ 这样的模式可以匹配两种选择。
谁能帮我理解这一切?我的意思是,为什么最后一个以上的都不起作用。
提前致谢。
为什么不这样做:
grammar T;
parse
: ( c_comment
| plus_comment
)*
EOF
;
c_comment
: C_COMMENT
;
plus_comment
: PLUS_COMMENT
;
PLUS_COMMENT
: '/*' S* '+' .* '*/'
;
C_COMMENT
: '/*' .* '*/'
;
SPACES
: S+ {skip();}
;
fragment S
: ' ' | '\t' | '\r' | '\n'
;
它将解析输入:
/**/
/* + as*/
/* sdcdcds sdcds */
如下:
这里的技巧是在C_COMMENT
之前定义PLUS_COMMENT
。这样,如果词法分析器遇到 "/* s"
,它会从 PLUS_COMMENT
回落到 C_COMMENT
,因为它无法匹配 +
.
我目前正在研究支持 C 风格注释的 ANTLR 词法分析器规则。对于这样的目标,有一个广泛推荐的规则:
C_COMMENT
:
'/*' (options {greedy=false;}: .)* '*/'
{ $channel=HIDDEN; }
;
然而我想要的是另一种选择:“+”不允许成为评论正文的第一个非 space 字符,例如/* +blablabla*/ 不是有效的注释。 然后我尝试了这样的事情:
C_COMMENT
:
'/*' (' '|'\r'|'\t'|'\n')* ~(' '|'\r'|'\t'|'\n'|'+') (options {greedy=false;}: .)* '*/'
{ $channel=HIDDEN; }
;
它几乎成功了,除了空注释 /* */。所以我尝试了这样的事情:
C_COMMENT
:
'/*' (' '|'\r'|'\t'|'\n')*
(
'*/'
|
(~(' '|'\r'|'\t'|'\n'|'+') (options {greedy=false;}: .)* '*/')
)
{ $channel=HIDDEN; }
;
它和我没有列出的一堆类似的东西从来没有用过。 /* */ 中的 * / 总是属于 ~(' '|'\r'|'\t'|'\n'|'+') 部分。
最后我得到了这样的东西:
C_COMMENT
:
'/*' (' '|'\r'|'\t'|'\n')* '*/'
{ $channel=HIDDEN; }
|
'/*' (' '|'\r'|'\t'|'\n')*
(
'*/'
|
(~(' '|'\r'|'\t'|'\n'|'+') (options {greedy=false;}: .)* '*/')
)
{ $channel=HIDDEN; }
;
尽管 ANTLR 警告像 /* */ 这样的模式可以匹配两种选择。
谁能帮我理解这一切?我的意思是,为什么最后一个以上的都不起作用。
提前致谢。
为什么不这样做:
grammar T;
parse
: ( c_comment
| plus_comment
)*
EOF
;
c_comment
: C_COMMENT
;
plus_comment
: PLUS_COMMENT
;
PLUS_COMMENT
: '/*' S* '+' .* '*/'
;
C_COMMENT
: '/*' .* '*/'
;
SPACES
: S+ {skip();}
;
fragment S
: ' ' | '\t' | '\r' | '\n'
;
它将解析输入:
/**/ /* + as*/ /* sdcdcds sdcds */
如下:
这里的技巧是在C_COMMENT
之前定义PLUS_COMMENT
。这样,如果词法分析器遇到 "/* s"
,它会从 PLUS_COMMENT
回落到 C_COMMENT
,因为它无法匹配 +
.