2010-08-24 3 views
3

La règle 'expr' dans la grammaire ANTLR ci-dessous évidemment réciproquement à gauche. En tant que débutant ANTLR, il m'est difficile de résoudre ce problème. J'ai lu "Résoudre les conflits non-LL (*)" dans le livre de référence ANTLR, mais je ne vois toujours pas la solution. Des pointeurs?Résoudre ANTLR Règles récurrentes mutuellement à gauche

 
LPAREN : ('(') ; 
RPAREN : (')'); 
AND : ('AND' | '&' | 'EN') ; 
OR : ('OR' | '|' | 'OF'); 
NOT : ('-' | 'NOT' | 'NIET'); 
WS : (' ' | '\t' | '\r' | '\n') {$channel=HIDDEN;} ; 
WORD : (~(' ' | '\t' | '\r' | '\n' | '(' | ')' | '"'))*; 

input : expr EOF; 
expr : (andexpr | orexpr | notexpr | atom); 
andexpr : expr AND expr; 
orexpr : expr OR expr; 
notexpr : NOT expr; 
phrase : '"' WORD* '"'; 
atom : (phrase | WORD); 

Répondre

5

Je suggérerais d'examiner les exemples de grammeurs sur le site antlr. La grammaire java fait ce que vous voulez.

Basiquement vous pouvez faire quelque chose comme ceci:

expr : andexpr; 
andexpr : orexpr (AND andexpr)*; 
orexpr : notexpr (OR orexpr)*; 
notexpr : atom | NOT expr; 

La clé est que chaque expression peut finir d'être un atome.

+0

Merci pour votre réponse. Mon problème avec cette solution est que l'arbre d'analyse semble étrange: chaque atome a un notexpr comme parent, même si ce n'est pas vraiment un notexpr. Peut-être que les analyseurs LL (*) ne sont pas la meilleure solution pour ce genre d'analyse? –

+0

Il n'y a rien de mal avec les parseurs LL pour ce genre de grammaire (il est très courant d'utiliser ce genre d'expression). Si vous générez un AST, vous pouvez utiliser des règles de réécriture pour créer un AST qui n'inclut pas les parents "superflues". – Arne

+0

@Arne Je suis tombé sur votre réponse tout en cherchant une solution au même problème qu'avait l'affiche originale. J'ai trouvé une légère faute de frappe dans votre code: la première ligne devrait lire 'expr: andexpr' au lieu de' expr: andexp'. Je ne peux pas l'éditer moi-même, puisque SO pour certaines raisons demande que je change plus de 6 caractères pour qu'un montage soit accepté. Pouvez-vous le changer vous-même afin que les copieurs-copieurs inconscients comme moi puissent rencontrer les mêmes erreurs de compilation? – phuibers