Синтаксический анализ комментариев с помощью javacc - PullRequest
0 голосов
/ 04 октября 2018

Я пытаюсь написать некоторую грамматику 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 голосов
/ 09 октября 2018

Я не уверен, как выглядит остальная часть вашего файла, поэтому я предполагаю, что файл, как ожидается, будет представлять собой последовательность комментариев, перед которыми следуют и разделяются нулем или несколькими пробелами и символами новой строки.

Что бы я сделал, это:

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

Теперь вы не получите лексическую ошибку для пропущенного */,но вы получаете исключение синтаксического анализа.

...