代码之家  ›  专栏  ›  技术社区  ›  Angel Todorov

具有非贪婪规则的ANTLR

  •  0
  • Angel Todorov  · 技术社区  · 9 年前

    我想要以下语法(部分):

    expression 
    : 
    expression 'AND' expression
    | expression 'OR' expression
    | StringSequence
    ;
    
    StringSequence
    : 
    StringCharacters
    ;
    
    fragment
    StringCharacters
    : StringCharacter+
    ;
    
    fragment
    StringCharacter
    : ~["\]
    | EscapeSequence
    ;
    

    它应该匹配诸如“a b c d f”(不带引号)之类的内容,以及诸如“a AND b AND c”之类的内容。

    问题是我的规则StringSequence是贪婪的,并且也消耗了OR/and。我尝试过不同的方法,但无法使语法以正确的方式工作。ANTLR4有可能吗?注意,我不想在每个字符串周围加引号。放引号很好,因为规则变得不贪婪,即:

    StringSequence
    : '"' StringCharacters? '"'
    ;
    
    2 回复  |  直到 8 年前
        1
  •  2
  •   Mike Lischke    9 年前

    您没有空格规则,因此StringCharacter匹配除引号和反斜杠字符(+转义序列)之外的所有字符。包含一个空白规则,使其与单个AND/OR标记匹配。此外,我建议为字符串文本定义lexer规则( 'AND' , 'OR' )而不是将它们嵌入(解析器)规则中。这样,您不仅可以获得代币的发音名称(而不是自动生成的名称),还可以更好地控制匹配顺序。

        2
  •  1
  •   CoronA    9 年前

    然而,一个天真的解决方案:

    StringSequence : 
      (StringCharacter | NotAnd | NotOr)+
    ;
    fragment NotAnd :
      'AN' ~'D'
    | 'A' ~'N'
    ;
    fragment NotOr:
      'O' ~('R')
    ;
    fragment StringCharacter :
      ~('O'|'A')
    ;
    

    使用空白规则会变得更复杂。另一种解决方案是语义谓词向前看,防止读取关键字。