2011-11-27 36 views

Odpowiedz

23

Negowanie może wystąpić wewnątrz lexer and parser rules.

Wewnątrz reguł leksykalnych można negować postacie, a wewnątrz reguł parsera można negować żetony (zasady lexera). Jednak obie reguły lexer i parser mogą negować tylko pojedyncze znaki lub pojedyncze tokeny.

Kilka przykładów:

zasad Lexer

dopasować jeden lub więcej znaków, z wyjątkiem małych liter ASCII, można zrobić:

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

(negacja-meta-char, ~, ma wyższy priorytet niż +, więc powyższa reguła jest równa (~('a'..'z'))+)

Zauważ, że 'a'..'z' dopasowuje pojedynczy znak (i ​​może być zatem zostać zanegowana), ale następująca reguła jest nieprawidłowy:

ANY_EXCEPT_AB : ~('ab') ; 

Ponieważ 'ab' (oczywiście) pasuje 2 znaki, to nie może być zanegowany. Pasujące token, który składa się z 2 znaków, ale nie 'ab', trzeba wykonać następujące czynności:

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 
    ; 

zasad parsera

wewnętrzne zasady parser, ~ neguje pewien znak, lub więcej niż jeden znak. Na przykład, masz następujące tokeny zdefiniowane:

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

Jeśli teraz chcesz dopasować dowolny znak z wyjątkiem A, robisz:

p : ~A ; 

A jeśli chcesz, aby dopasować dowolny znak z wyjątkiem B i D, można zrobić:

p : ~(B | D) ; 

Jednakże, jeśli chcesz dopasować dowolne dwa znaki inne niż A następnie B, ty nie można zrobić:

p : ~(A B) ; 

Podobnie jak w przypadku zasad Lexer, nie można negować więcej niż jeden znak. Aby zrealizować powyższe, trzeba zrobić:

P 
    : A ~B 
    | ~A . 
    ; 

Zauważ, że (DOT) char w ciągu zasad parsera . robi nie dowolny znak jak ma to miejsce w środku zasad Lexer. Wewnątrz reguł parsera pasuje do dowolnego tokena (w tym przypadku: A,, D lub lub lub .

Należy pamiętać, że nie można zanegować reguł parsera. Poniższe informacje są niezgodne z prawem:

p : ~a ; 
a : A ; 
+0

Dziękujemy za wyjaśnienia. Nie wiedziałem, że operator '~' będzie stosować tokeny, gdy występuje w regule parsera. – Gunther

+0

@Gunther, bez problemu. Często wspominam o tym krótko w moich odpowiedziach, więc od teraz mogę linkować do tego pytania i odpowiedzi. W.r.t. Twój konwerter, być może już go używasz, ale może nie: klasa 'org.antlr.tool.Strip' usuwa cały kod niestandardowy z plików gramatycznych ANTLR, co może ułatwić życie podczas analizowania gramatyk ANTLR. –