否定词法分析器和解析器规则

Bar*_*ers 16 antlr parser-generator antlr3

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

Bar*_*ers 30

词法分析器和解析器规则中可能会出现否定.

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

几个例子:

词法规则

要匹配除小写ascii字母之外的一个或多个字符,您可以执行以下操作:

NO_LOWERCASE : ~('a'..'z')+ ;
Run Code Online (Sandbox Code Playgroud)

(negation-meta-char,~优先级高于+,所以上面的规则等于(~('a'..'z'))+)

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

ANY_EXCEPT_AB : ~('ab') ;
Run Code Online (Sandbox Code Playgroud)

因为'ab'(显然)匹配2个字符,所以不能否定.要匹配包含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
  ;
Run Code Online (Sandbox Code Playgroud)

解析器规则

在解析器规则内部,~否定某个令牌或多个令牌.例如,您定义了以下标记:

A : 'A';
B : 'B';
C : 'C';
D : 'D';
E : 'E';
Run Code Online (Sandbox Code Playgroud)

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

p : ~A ;
Run Code Online (Sandbox Code Playgroud)

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

p : ~(B | D) ;
Run Code Online (Sandbox Code Playgroud)

但是,如果你想匹配除了A后面的任何两个令牌B,你不能这样做:

p : ~(A B) ;
Run Code Online (Sandbox Code Playgroud)

与词法分析器规则一样,您不能否定多个令牌.要完成上述任务,您需要:

P
  :  A ~B
  |  ~A .
  ; 
Run Code Online (Sandbox Code Playgroud)

请注意,.解析器规则中的(DOT)字符与lexer规则中的任何字符都不匹配.里面的语法规则,它匹配任何记号(A,B,C,DE,在这种情况下).

请注意,您无法否定解析器规则.以下是非法的:

p : ~a ;
a : A  ;
Run Code Online (Sandbox Code Playgroud)