2017-10-10 6 views
1

Je suis relativement nouveau à la théorie des compilateurs et je voulais juste créer une grammaire pour analyser certaines comparaisons afin de les évaluer plus tard. J'ai trouvé antlr qui est un outil puissant pour spécifier la grammaire. D'après ce que j'ai appris dans la théorie, je sais que les opérateurs ayant une priorité supérieure doivent être déclinés dans des niveaux plus profonds que les opérateurs ayant une priorité inférieure. De plus, si je veux qu'une règle reste associative, je sais que je dois définir la récursivité à gauche de la règle. Sachant que j'ai créé une grammaire de base pour utiliser & &, ||,! =, ==, <,>, < =,> =, (,) et!antlr grammaire définition

start 
: orExpr 
; 

orExpr 
: orExpr OR andExpr 
| andExpr 
; 

andExpr 
: andExpr AND eqNotEqExpr 
| eqNotEqExpr 
; 

eqNotEqExpr 
: eqNotEqExpr NEQ compExpr 
| eqNotEqExpr EQ compExpr 
| compExpr 
; 

compExpr 
: compExpr LT compExpr 
| compExpr GT compExpr 
| compExpr LTEQ compExpr 
| compExpr GTEQ compExpr 
| notExpr 
; 

notExpr 
: NOT notExpr 
| parExpr 
; 

parExpr 
: OPAR orExpr CPAR 
| id 
; 

id 
: INT 
| FLOAT 
| TRUE 
| FALSE 
| ID 
| STRING 
| NULL 
; 

Cependant la recherche dans Internet, j'ai trouvé une autre façon de spécifier ci-dessus la grammaire qui ne suit pas les règles ci-dessus je l'ai mentionné au sujet de la priorité des opérateurs et associativité gauche: quelqu'un

start 
: expr 
; 

expr 
: NOT expr        //notExpr 
| expr op=(LTEQ | GTEQ | LT | GT) expr //relationalExpr 
| expr op=(EQ | NEQ) expr    //equalityExpr 
| expr AND expr      //andExpr 
| expr OR expr       //orExpr 
| atom         //atomExpr 
; 

atom 
: OPAR expr CPAR //parExpr 
| (INT | FLOAT) //numberAtom 
| (TRUE | FALSE) //booleanAtom 
| ID    //idAtom 
| STRING   //stringAtom 
| NULL   //nullAtom 
; 

peut-il expliquer pourquoi cette façon de définir la grammaire fonctionne également? Est-ce parce que certains traitements spécifiques d'antlr ou d'un autre type de définition de la grammaire?

Ci-dessous, il y a les opérateurs et ids définis pour la grammaire:

OR : '||'; 
AND : '&&'; 
EQ : '=='; 
NEQ : '!='; 
GT : '>'; 
LT : '<'; 
GTEQ : '>='; 
LTEQ : '<='; 
NOT : '!'; 

OPAR : '('; 
CPAR : ')'; 

TRUE : 'true'; 
FALSE : 'false'; 
NULL : 'null'; 

ID 
: [a-zA-Z_] [a-zA-Z_0-9]* 
; 

INT 
: [0-9]+ 
; 

FLOAT 
: [0-9]+ '.' [0-9]* 
| '.' [0-9]+ 
; 

STRING 
: '"' (~["\r\n] | '""')* '"' 
; 

COMMENT 
: '//' ~[\r\n]* -> skip 
; 

SPACE 
: [ \t\r\n] -> skip 
; 

OTHER 
: . 
; 

Répondre

0

Ceci est spécifique à ANTLR v4.

Sous le capot, une règle comme celle-ci sera réécrite pour correspondre à ce que vous avez fait manuellement dans le cadre de l'étape d'élimination de la récursivité gauche. ANTLR le fait par commodité car les grammaires LL ne peuvent pas contenir de règles récursives à gauche, car une conversion directe d'une telle règle en code parser produirait une récursion infinie dans le code (une fonction qui s'appelle inconditionnellement).

Il y a plus d'informations et un exemple de transformation dans the docs page about left-recursion.