使用javacc

时间:2018-10-04 12:53:43

标签: java parsing lexical-analysis 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令牌都以/*开头我不要。

1 个答案:

答案 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() ; } } 而遇到词法错误,但是您确实会得到解析异常。