【问题标题】:Negating inside lexer- and parser rules否定词法分析器和解析器规则
【发布时间】:2021-12-03 04:23:59
【问题描述】:

如何在 ANTLR 的词法分析器规则中使用否定元字符 ~

【问题讨论】:

    标签: antlr antlr4 antlr3 parser-generator


    【解决方案1】:

    否定可以发生在lexer and parser rules内部。

    在词法分析器规则中,您可以否定字符,在解析器规则中,您可以否定标记(词法分析器规则)。但是词法分析器和解析器规则都只能分别否定单个字符或单个标记。

    几个例子:

    词法分析器规则

    要匹配除小写 ascii 字母以外的一个或多个字符,您可以:

    NO_LOWERCASE : ~('a'..'z')+ ;
    

    (否定元字符~的优先级高于+,所以上面的规则等于(~('a'..'z'))+

    注意'a'..'z'匹配单个字符(因此可以取反),但以下规则无效:

    ANY_EXCEPT_AB : ~('ab') ;
    

    因为'ab'(显然)匹配2个字符,所以不能取反。要匹配包含 2 个字符但不包含 'ab' 的令牌,您必须执行以下操作:

    ANY_EXCEPT_AB 
      :  'a' ~'b' // any two chars starting with 'a' followed by any other than 'b'
      |  ~'a' .   // other than 'a' followed by any char
      ;
    

    解析器规则

    在解析器规则中,~ 否定某个标记或多个标记。例如,您定义了以下标记:

    A : 'A';
    B : 'B';
    C : 'C';
    D : 'D';
    E : 'E';
    

    如果您现在想要匹配除A 之外的任何令牌,您可以:

    p : ~A ;
    

    如果你想匹配除BD 之外的任何令牌,你可以这样做:

    p : ~(B | D) ;
    

    但是,如果您想匹配除 A 后跟 B 之外的任何两个令牌,您不能这样做:

    p : ~(A B) ;
    

    就像词法分析器规则一样,您不能否定多个标记。要完成上述操作,您需要:

    P
      :  A ~B
      |  ~A .
      ; 
    

    请注意,解析器规则中的. (DOT) 字符 匹配任何字符,就像它在词法分析器规则中那样。在解析器规则中,它匹配任何标记(ABCDE,在这种情况下)。

    请注意,您不能否定解析器规则。以下是非法的:

    p : ~a ;
    a : A  ;
    

    【讨论】:

    • 感谢您的澄清。我不知道 ~ 运算符在解析器规则中出现时会应用于令牌。
    • @Gunther,没问题。我经常在我的回答中简短地提到它,所以从现在开始我可以链接到这个 Q&A。 W.r.t.您的转换器,也许您已经在使用它,但也许没有:org.antlr.tool.Strip 类从 ANTLR 语法文件中删除所有自定义代码,这可能使您在解析 ANTLR 语法时更轻松。
    猜你喜欢
    • 2013-04-29
    • 1970-01-01
    • 2012-03-04
    • 1970-01-01
    • 1970-01-01
    • 2013-01-31
    • 1970-01-01
    • 2020-09-14
    • 1970-01-01
    相关资源
    最近更新 更多