2011-06-04 27 views
7

¿Cuál sería la mejor manera de cambiar la precedencia del operador para una expresión concreta?Cambiar la precedencia del operador

Por ejemplo, tengo una clase:

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 

Como la multiplicación tiene mayor precedencia que + y - consigo un AST de forma

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

¿Cuál sería la forma más fácil de convertirlo en un árbol donde * tiene una prioridad menor que + y -. Supongo que los paréntesis están permitidos solo para el grupo - y +, es decir, una expresión (a * b - c) * d no es válida y no debe esperarse como entrada.

+0

Yo tendría cuidado: la sobrecarga de operadores * * puede introducir confusión y cambiar la prioridad de los operadores podría introducir aún más! –

+0

es dsl, así que debería estar bien – Nutel

+0

Usted menciona 'cambio a la derecha' sin identificar el símbolo que lo denota. ¿'' 'Es el símbolo del 'cambio a la derecha'? –

Respuesta

4

Simplemente puede agregar paréntesis a su código. Esto probablemente hará que tu código sea mucho más fácil de entender que usar una transformación AST.

3

Usted podría cambiarlo mediante una transformación AST, pero sería una cosa difícil de hacerlo bien ...

Si carga su script en el GroovyConsole, y luego abrir el navegador AST, se quiere ver este árbol de la misión:

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

Así como se puede ver, los nodos se ejecutan sobre la base de precedencia de operadores predeterminada, y un árbol de org.codehaus.groovy.ast.expr.BinaryExpression y org.codehaus.groovy.ast.expr.VariableExpression nodos AST se crea.

Debería escribir una transformación AST que escaneó el árbol en busca de nodos BinaryExpression y luego volver a ordenar estos árboles para que estén ordenados por su propia precedencia para el campo operation.

O, usted podría utilizar paréntesis en el código como Don sugiere :-)

+0

en realidad es un dsl, por lo que introducirlo añadirá algo de ruido. Además, si el usuario va a usar paréntesis, no podré obtener esta información en AST, ¿verdad? – Nutel

+1

Un AST no suele almacenar paréntesis, a la derecha. –

Cuestiones relacionadas