2011-11-27 18 views

risposta

23

negando può verificarsi all'interno lexer and parser rules.

All'interno lexer regole si può negare personaggi, e dentro le regole del parser si può negare gettoni (regole lexer). Ma entrambe le regole lesser e parser possono solo negare o singoli caratteri, o singoli token, rispettivamente.

Un paio di esempi:

regole lexer

per abbinare uno o più caratteri, eccetto le lettere ASCII minuscoli, si può fare:

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

(la negazione-meta-char, ~, ha una precedenza maggiore rispetto allo +, quindi la regola precedente è uguale a (~('a'..'z'))+)

Nota che 'a'..'z' corrisponde a un singolo carattere (e possono Perciò essere negato), ma la seguente regola non è valido:

ANY_EXCEPT_AB : ~('ab') ; 

Perché 'ab' (ovviamente) partite 2 caratteri, non può essere negata. Per abbinare un token che si compone di 2 carattere, ma non 'ab', che avrebbe dovuto effettuare le seguenti operazioni:

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 
    ; 

regole parser

regole parser All'interno, ~ nega un certo modo, o più di uno gettone. Per esempio, avete i seguenti token definiti:

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

Se ora si vuole per adattarsi a qualsiasi gettone tranne il A, si fa:

p : ~A ; 

E se si vuole per adattarsi a qualsiasi gettone tranne B e D, si può fare:

p : ~(B | D) ; 

Tuttavia, se si desidera far corrispondere ogni due token diversi A seguiti da B, è non può fare:

p : ~(A B) ; 

Proprio come con le regole lexer, non si può negare più di un singolo token. Per realizzare quanto sopra, è necessario fare:

P 
    : A ~B 
    | ~A . 
    ; 

Nota che il . (DOT) char in regole parser non non partita qualsiasi carattere come avviene all'interno di regole lexer. All'interno regole parser, che corrisponde a qualsiasi gettone (A, B, C, D o E, in questo caso).

Nota che non si può negare le regole del parser. Quanto segue è illegale:

p : ~a ; 
a : A ; 
+0

Grazie per il chiarimento. Non ero a conoscenza del fatto che l'operatore '~' si sarebbe applicato ai token quando si verificava in una regola parser. – Gunther

+0

@ Gunther, nessun problema. Spesso lo cito brevemente nelle mie risposte, quindi da ora in poi posso collegarmi a questo Q & A. W.r.t. il tuo convertitore, forse lo stai già usando, ma forse no: la classe 'org.antlr.tool.Strip' rimuove tutto il codice personalizzato dai file di grammatica ANTLR che potrebbero semplificarti la vita quando analizzi le grammatiche ANTLR. –