当前位置: 首页 > 知识库问答 >
问题:

如何标记块(注释、字符串等)以及块间(块外的任何字符)?

隆飞宇
2023-03-14

我需要标记任何评论“之外”的所有内容,直到行尾。例如:

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 lexer完成吗?如果可以,那么如何实现?

共有2个答案

宗政洋
2023-03-14

尝试以下操作:

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()}? . )+
 ;
毋城
2023-03-14

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

根据上面所述,您需要嵌套注释。这些只能在lexer中实现,无需Action、Predicate或任何代码。为了拥有嵌套注释,如果您不使用贪心/非贪心ANTLR选项会更容易。您需要将其指定/编码到lexer语法中。以下是您需要的三个lexer规则...带有STR定义。

我添加了一个用于测试的解析器规则。我还没有测试过这个,但它应该可以满足您提到的所有要求。此外,它不限于“行结束”,如果需要,您可以进行修改。

/*
    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
        : '//'
          ( ~[\n\r*/]          // 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
        ;
 类似资料:
  • 问题内容: str 和 string有 什么区别或关系? 问题答案: 是一个内置函数(实际上是一个class),它将其参数转换为字符串。是提供常见字符串操作的模块。 换句话说,对象是某些对象的文本表示形式,通常是通过调用创建的。这些对象具有在其上定义的某些 方法 。该模块提供了其他 功能 和 常量 ,这些 功能 和 常量 在处理字符串时非常有用。

  • 在catch块中,如果有人输入一个字符串或一个小于13或大于16的数字,我想打印输入有效的卡片no。

  • 本文向大家介绍racket 块注释,包括了racket 块注释的使用技巧和注意事项,需要的朋友参考一下 示例            

  • 问题内容: 我希望能够对文本框中的输入字符串进行标记化以进行查询。示例:用户在文本框中输入“ abc xyz 123”。我想做这个: 谢谢。 问题答案: 使用一个字符串拆分函数,您可能会得到如下所示的内容:

  • 问题内容: 什么时候在方法开始时使用块注释,什么时候使用Javadoc风格的注释? 在Java样式指南的“注释”部分中,我发现了这一点: Java程序可以有两种注释:实现注释和文档注释。实现注释是在C ++中发现的,由,和// 分隔。文档注释(称为“文档注释”)仅适用于Java,并以分隔。可以使用javadoc工具将Doc注释提取到HTML文件中。 实现注释用于注释掉代码或有关特定实现的注释。Do

  • 问题内容: 是否可以注释代码块?例如循环还是大括号?如果是这样,怎么办? 第一.java ForCycle.java 根据http://www.javacodegeeks.com/2012/11/java-annotations-tutorial-with-custom- annotation.html @Target –指示注释类型适用的程序元素的种类。一些可能的值是TYPE,METHOD,CO