2009-09-20 16 views
5

Comment la priorité de l'opérateur est-elle implémentée dans ANTLR? J'utilise le paquet XText/Antlr pour le moment.ANTLR Operator Precedence

Edit:

Je l'ai fait ce que sepp2k a suggéré, et la priorité des opérateurs fonctionne maintenant, mais des choses comme 3 + * aussi travailler maintenant. Les opérateurs sont en train de "tomber" dans l'arbre.

En outre, j'ai essayé la grammaire C sur le site Web d'ANTLR et la même chose s'est produite dans ANTLRworks.

Quelqu'un sait quel est le problème?

BinaryExpression: 
    'or'? AndOp; //or op 

AndOp: 
    'and'? ComparisonOp; 

ComparisonOp: 
    ('>'|'<'|'>='|'<='|'=='|'~=')? ConcatOp; 

ConcatOp: 
    '..'? AddSubOp; 

AddSubOp: 
    ('+' | '-')? MultDivOp; 

MultDivOp: 
    ('*' | '/')? ExpOp; 

ExpOp: 
    '^'? expr=Expression; 
+0

L'appel à l'expression devrait probablement être entre '(' et ')'. Vos opérateurs semblent également tous manquer un opérande de gauche. – sepp2k

+0

Je l'ai corrigé en utilisant la méthode trouvée dans mon commentaire. De plus, l'opérande de gauche a été déplacé à la première expression pour éviter la récursion à gauche. – jameszhao00

Répondre

9

Avec ANTLR vous codez la précédence dans les règles de grammaire. Comme:

expr: mult ('+' mult)* ; 
mult: atom ('*' atom)* ; 
atom: INT | '(' expr ')' ; 

Cela analyser "1 + 2 * 3 + (4 * 5 + 6)" comme "(1 + (2 * 3)) + ((4 * 5) + 6)"

+0

S'il vous plaît lire ma mise à jour :) – jameszhao00

+0

Peut-être que je pourrais faire des choses comme AndOp: ('et' Expression) | ComparisonOp – jameszhao00

+0

Pour clarifier la plus détaillée, une règle de grammaire correspondra à sa plus grande priorité. Dans l'exemple ci-dessus, "expr -> multi -> atom *" est plus détaillé que le chemin vers le signe plus. Par conséquent, le chemin * a la priorité. –

2

Puisque vous utilisez Xtext, je vous recommande d'utiliser le concept d'action de Xtext. Ce est, une grammaire simple expression regarderait généralement semblable à celui-ci:

Sum: Product ({Sum.left=current} operator=('+'|'-') right=Product)*; 
Product: Atom ({Product.left=current} operator=('+'|'-') right=Atom)*; 
Atom: Number | Paren; 
Paren: '(' Sum ')'; 
Number: value=INT; 

S'il vous plaît jeter un oeil à la documentation pour les détails.