Algorithm 更改运算符优先级
更改具体表达式的运算符优先级的最佳方法是什么 例如,我有一门课:Algorithm 更改运算符优先级,algorithm,abstract-syntax-tree,operator-precedence,Algorithm,Abstract Syntax Tree,Operator Precedence,更改具体表达式的运算符优先级的最佳方法是什么 例如,我有一门课: 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形
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
无效,不应作为输入。您可以简单地将括号添加到代码中。这可能会使您的代码比使用AST转换更容易理解。您可以使用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.BinaryExpression
和org.codehaus.groovy.ast.expr.VariableExpression
ast节点树
您需要编写一个AST转换,扫描树中的BinaryExpression节点,然后对这些树重新排序,以便它们按照您自己的优先级对操作
字段进行排序
或者,您可以按照Don的建议在代码中使用括号:-)我会小心:运算符重载可能会导致混淆,更改运算符优先级可能会导致更多混淆!这是dsl,所以如果你提到“右移”而没有识别表示它的符号,应该是OK。
*
是“右移”的符号吗?最好的方法是在语法中简单地声明其他运算符的前导,并将规则放在括号中。显然,这意味着使用您自己的解析器,但是更改某些语言中的基本语法规则只是让人困惑。并不是说我可以从你的问题中推断出你实际使用的是什么解析器或语言。它实际上是一种dsl,所以引入它会增加一些噪音。另外,若用户使用括号,我将无法在AST中获取此信息,对吗?