2011-06-04 162 views
7

更改具體表達式的運算符優先級的最佳方法是什麼?更改運算符優先級

比如我有一個類:

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 

乘法的優先級高於+-我得到形式的AST

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

什麼將其轉換爲最簡單的方法*的優先級低於+-。我假設圓括號僅允許將-+組合在一起,即表達式(a * b - c) * d無效並且不應該作爲輸入。

+0

我會小心:操作符重載* *可以引入混亂和改變運算符優先級甚至更多的介紹! – 2011-06-07 08:47:10

+0

它是dsl所以應該沒問題 – Nutel 2011-06-08 02:25:32

+0

你提到'右移'沒有標識表示它的符號。 '*'是'右移'的符號嗎? – 2012-05-13 21:10:59

回答

4

您可以簡單地將括號添加到您的代碼中。這可能會使您的代碼比使用AST轉換更容易理解。

3

可以使用AST轉換改變它,但是這將是一個棘手的事情得到正確的...

如果加載腳本到groovyConsole中,然後打開AST瀏覽器,你會看到這棵樹的分配:

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

所以你可以看到,該節點基於默認運算符優先級執行,並org.codehaus.groovy.ast.expr.BinaryExpressionorg.codehaus.groovy.ast.expr.VariableExpression AST節點樹被創建。

您需要編寫一個AST轉換,掃描樹的BinaryExpression節點,然後重新排序這些樹,以便按照您自己的優先順序對operation字段進行排序。

或者,你可以只用括號中的代碼唐建議:-)

+0

它實際上是一個DSL,所以引入會增加一些噪音。此外,如果用戶將使用括號,我將無法在AST中獲得此信息,對嗎? – Nutel 2011-06-08 02:31:46

+1

AST通常不存儲括號,正確。 – 2012-05-18 09:16:01