What would be the best way to change operator precedence for a concrete expression?
For example I have a class:
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
As multiplication has higher precedence than +
and -
I get an AST of form
+
/ \
a *
/ \
- d
/ \
b c
What would be the easiest way to convert it to a tree where *
has lower precedence than +
and -
. I assume that parentheses are allowed only to group -
and +
, i.e. an expression (a * b - c) * d
is not valid and should be not expected as an input.
You could simply add parentheses to your code. This will likely make your code a lot more easily understood than using an AST transformation.
You could change it using an AST transformation, but it would be a tricky thing to get right...
If you load your script into the GroovyConsole, and then open the AST browser, you will see this tree for the assignment:
Binary - ( d = ( a & ( b >> c ) ) )
Variable - d
Binary - ( a & ( b >> c ) )
Variable - a
Binary - ( b >> c )
Variable - b
Variable - c
So as you can see, the nodes are executed based on default operator precedence, and a tree of org.codehaus.groovy.ast.expr.BinaryExpression
and org.codehaus.groovy.ast.expr.VariableExpression
AST nodes is created.
You would need to write an AST transform that scanned the tree for BinaryExpression nodes and then re-order these trees so that they are sorted by your own precedence for the operation
field.
Or, you could just use parentheses in your code as Don suggests :-)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With