如何在ANTLR的词法分析器和解析器规则中使用否定元字符~
?
答案 0 :(得分:29)
lexer and parser rules内可能会出现否定。
在lexer规则中你可以否定字符,在解析器规则中你可以否定标记(词法规则)。但是lexer和parser规则只能分别否定单个字符或单个标记。
几个例子:
要匹配除小写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 ;
如果你想匹配除B
和D
之外的任何令牌,你可以这样做:
p : ~(B | D) ;
但是,如果您要匹配A
后跟B
以外的任何两个令牌,则 不能 执行:
p : ~(A B) ;
与词法规则一样,您不能否定多个令牌。要完成上述任务,您需要执行以下操作:
P
: A ~B
| ~A .
;
请注意,解析器规则中的.
(DOT)字符 不 匹配任何字符,就像在lexer规则中一样。在解析器规则内部,它匹配任何令牌(A
,B
,C
,D
或E
,在这种情况下)。
请注意,您无法否定解析器规则。以下是非法的:
p : ~a ;
a : A ;