使用 javacc 解析块注释
Parsing block comments with javacc
我正在尝试编写一些 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
标记都以 [=13= 开头] 我不想要。
我不确定您的文件的其余部分是什么样子,所以我假设文件应该是一系列注释,前后由零个或多个空格和换行符分隔。
我会做的是:
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() ; }
}
现在您不会因缺少 */
而收到词法错误,但会收到解析异常。
我正在尝试编写一些 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
标记都以 [=13= 开头] 我不想要。
我不确定您的文件的其余部分是什么样子,所以我假设文件应该是一系列注释,前后由零个或多个空格和换行符分隔。
我会做的是:
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() ; }
}
现在您不会因缺少 */
而收到词法错误,但会收到解析异常。