2011-06-04 3 views
7

Quelle serait la meilleure façon de changer la priorité de l'opérateur pour une expression concrète?Modifier la priorité de l'opérateur

Par exemple, j'ai une classe:

class A(){ 
    def multiply(a) { 
     ... 
    } 

    def plus(a) { 
     ... 
    } 

    def minus(b) { 
     ... 
    } 

} 

a = new A() 
b = new A() 
c = new A() 

d = a + (b - c) * d 

Comme multiplication a une priorité supérieure + et - je reçois un AST de forme

+ 
/\ 
a * 
/\ 
    - d 
/\ 
b c 

Quelle serait la meilleure façon de le convertir en un arbre où * a une priorité inférieure à + et -. Je suppose que les parenthèses sont autorisées uniquement à grouper - et +, c'est-à-dire qu'une expression (a * b - c) * d n'est pas valide et ne doit pas être attendue en tant qu'entrée.

+0

je serais prudent: la surcharge opérateur * peut * introduire la confusion et de modifier la priorité de l'opérateur pourrait introduire encore plus! –

+0

c'est dsl donc ça devrait aller ok – Nutel

+0

Vous parlez de "décalage droit" sans identifier le symbole qui le désigne. Est-ce que '*' est le symbole du 'shift droit'? –

Répondre

4

Vous pouvez simplement ajouter des parenthèses à votre code. Cela rendra probablement votre code beaucoup plus facile à comprendre que d'utiliser une transformation AST.

3

Vous pouvez changer à l'aide d'une transformation AST, mais ce serait une chose difficile à obtenir le droit ...

Si vous chargez votre script dans le GroovyConsole, puis ouvrez le navigateur AST, vous allez voir cet arbre pour l'affectation:

Binary - (d = (a & (b >> c))) 
    Variable - d 
    Binary - (a & (b >> c)) 
    Variable - a 
    Binary - (b >> c) 
     Variable - b 
     Variable - c 

comme vous pouvez le voir, les noeuds sont exécutées en fonction de la priorité des opérateurs par défaut, et un arbre de org.codehaus.groovy.ast.expr.BinaryExpression et org.codehaus.groovy.ast.expr.VariableExpression nœuds AST est créé.

Vous auriez besoin d'écrire une transformation AST qui a analysé l'arborescence pour les nœuds BinaryExpression, puis de réorganiser ces arbres afin qu'ils soient triés par votre propre priorité pour le champ operation.

Ou, vous pouvez simplement utiliser des parenthèses dans votre code comme Don suggère :-)

+0

c'est en fait un dsl, donc l'introduction va ajouter du bruit. Aussi, si l'utilisateur utilisera des parenthèses je ne serai pas en mesure d'obtenir cette information dans AST, non? – Nutel

+1

Un AST ne stocke généralement pas de parenthèses, à droite. –

Questions connexes