我正在尝试编写一些javacc语法来解析包含多行注释的文件,例如,以下所有内容均有效:
/**/
/* */
/* This is a comment */
/* This
is
a
multiline
comment
*/
如果有一个/*
没有被*/
关闭,或者关闭*/
而没有打开/*
,我希望解析失败。
我不是要跳过这些评论,我希望这些评论可以用作标记。
到目前为止,我已经尝试过该方法,该方法可以工作,但在未关闭的/*
上不会失败:
options {
STATIC = false;
}
PARSER_BEGIN(BlockComments)
package com.company;
public class BlockComments {}
PARSER_END(BlockComments)
TOKEN : { < START_BLOCK_COMMENT : "/*" > : WITHIN_BLOCK_COMMENT }
<WITHIN_BLOCK_COMMENT> TOKEN: { < BLOCK_COMMENT: (~["*", "/"] | "*" ~["/"])+ > }
<WITHIN_BLOCK_COMMENT> TOKEN: { < END_BLOCK_COMMENT: "*/" > : DEFAULT }
SKIP : {
"\n"
}
我尝试过的另一个选项是这个,它具有相同的问题,并且略有不同,即跳过/*
和*/
而不是将其读取为令牌:
options {
STATIC = false;
}
PARSER_BEGIN(BlockComments)
package com.company;
public class BlockComments {}
PARSER_END(BlockComments)
SKIP : { "/*" : WITHIN_BLOCK_COMMENT }
<WITHIN_BLOCK_COMMENT> TOKEN: { <BLOCK_COMMENT: (~["*", "/"] | "*" ~["/"])+ > }
<WITHIN_BLOCK_COMMENT> SKIP : { "*/" : DEFAULT }
SKIP : {
"\n"
}
我尝试在第二个选项中使用MORE : { "/*" : WITHIN_BLOCK_COMMENT }
,以确保未关闭的/*
解析失败,但是它使所有BLOCK_COMMENT
令牌都以/*
开头我不要。
答案 0 :(得分:1)
我不确定文件的其余部分是什么样子,因此我假设文件应该是一个注释序列,其前后为零个或多个空格和换行符。
我要这样做的是:
$time
现在解析器中有
TOKEN : { < BLOCK_COMMENT_START : "/*" > : WITHIN_BLOCK_COMMENT }
<WITHIN_BLOCK_COMMENT> TOKEN: { <CHAR_IN_COMMENT: ~[] > }
<WITHIN_BLOCK_COMMENT> TOKEN: { < END_BLOCK_COMMENT: "*/" > : DEFAULT }
SKIP : {
"\n" | " "
}
现在您不会因为缺少void start() : {String s ; } {
(
s = comment() {System.out.println(s); }
)*
}
String comment() :
{ Token t ;
StringBuffer b = new StringBuffer() ;
}
{ <START_BLOCK_COMMENT>
(
t=<CHAR_IN_COMMENT> {b.append( t.image ) ; }
)*
<END_BLOCK_COMMENT>
{return b.toString() ; }
}
而遇到词法错误,但是您确实会得到解析异常。