使用 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() ; }
}

现在您不会因缺少 */ 而收到词法错误,但会收到解析异常。