如何标记块(注释,字符串,…)以及块间(块外的任何字符)



我需要标记任何注释"外面"的所有内容,直到行尾。例如:

take me */ and me /* but not me! */ I'm in! // I'm not...

标记为(STR是"外部"字符串,BC是块注释,LC是单行注释):

{
    STR: "take me */ and me ", // note the "*/" in the string!
    BC : " but not me! ",
    STR: " I'm in! ",
    LC : " I'm not..."
}

:

/* starting with don't take me */ ...take me...

标记:

{
    BC : " starting with don't take me ",
    STR: " ...take me..."
}

问题是,STR可以是任何除了的评论,因为评论打开器不是单个字符令牌,我不能使用STR的否定规则。

我想也许可以这样做:

STR : { IsNextSequenceTerminatesThe_STR_rule(); }?;

但是我不知道如何在lexer操作中查找字符

是否有可能用ANTLR4词法分析器完成,如果是,那么如何完成?

是,可以执行您正在尝试的标记化。

根据上面的描述,您需要嵌套注释。这些可以在词法分析器中实现,而不需要Action、Predicate或任何代码。为了有嵌套注释,如果你不使用贪心/非贪心ANTLR选项会更容易。您需要将其指定/编码到词法分析器语法中。以下是您将需要的三个词法分析器规则:

我添加了一个用于测试的解析器规则。我没有测试过这个,但它应该做你提到的所有事情。此外,它并不局限于'end of line',如果你需要的话,你可以做这个修改。
/*
    All 3 COMMENTS are Mutually Exclusive
 */
DOC_COMMENT
        : '/**'
          ( [*]* ~[*/]         // Cannot START/END Comment
            ( DOC_COMMENT
            | BLK_COMMENT
            | INL_COMMENT
            | .
            )*?
          )?
          '*'+ '/' -> channel( DOC_COMMENT )
        ;
BLK_COMMENT
        : '/*'
          (
            ( /* Must never match an '*' in position 3 here, otherwise
                 there is a conflict with the definition of DOC_COMMENT
               */
              [/]? ~[*/]       // No START/END Comment
            | DOC_COMMENT
            | BLK_COMMENT
            | INL_COMMENT
            )
            ( DOC_COMMENT
            | BLK_COMMENT
            | INL_COMMENT
            | .
            )*?
          )?
          '*/' -> channel( BLK_COMMENT )
        ;
INL_COMMENT
        : '//'
          ( ~[nr*/]          // No NEW_LINE
          | INL_COMMENT        // Nested Inline Comment
          )* -> channel( INL_COMMENT )
        ;
STR       // Consume everthing up to the start of a COMMENT
        : ( ~'/'      // Any Char not used to START a Comment
          | '/' ~[*/] // Cannot START a Comment
          )+
        ;
start
        : DOC_COMMENT
        | BLK_COMMENT
        | INL_COMMENT
        | STR
        ;

试试这样:

grammar T;
@lexer::members {
  // Returns true iff either "//" or "/*"  is ahead in the char stream.
  boolean startCommentAhead() {
    return _input.LA(1) == '/' && (_input.LA(2) == '/' || _input.LA(2) == '*');
  }
}
// other rules
STR
 : ( {!startCommentAhead()}? . )+
 ;

相关内容

  • 没有找到相关文章

最新更新