parsing - 将算术表达式树转换为字符串而没有不必要的括号?
问题描述
假设我构建了一个简单算术运算符的抽象语法树,例如Div(left,right), Add(left,right), Prod(left,right),Sum(left,right), Sub(left,right)
.
但是,当我想将 AST 转换为字符串时,我发现很难删除那些不必要的括号。
请注意,输出字符串应遵循正常的数学运算符优先级。
例子:
Prod(Prod(1,2),Prod(2,3))
让我们将其表示为((1*2)*(2,3))
使其成为字符串,它应该是1*2*2*3
更多示例:
(((2*3)*(3/5))-4) ==> 2*3*3/5 - 4
(((2-3)*((3*7)/(1*5))-4) ==> (2-3)*3*7/(1*5) - 4
(1/(2/3))/5 ==> 1/(2/3)/5
((1/2)/3))/5 ==> 1/2/3/5
((1-2)-3)-(4-6)+(1-3) ==> 1-2-3-(4-6)+1-3
解决方案
我在这个问题中找到了答案。
尽管问题与上面的链接有点不同,但该算法仍然适用。
规则是:如果节点的子节点的优先级较低,则需要一对括号。如果一个节点的运算符 -
, /
, %
, 和右操作数等于其父节点的优先级,它也需要括号。
我给出了伪代码(类似scala的代码):
def toString(e:Expression, parentPrecedence:Int = -1):String = {
e match {
case Sub(left2,right2) =>
val p = 10
val left = toString(left2, p)
val right = toString(right, p + 1) // +1 !!
val op = "-"
lazy val s2 = left :: right :: Nil mkString op
if (parentPrecedence > p )
s"($s2)"
else s"$s2"
//case Modulus and divide is similar to Sub except for p
case Sum(left2,right2) =>
val p = 10
val left = toString(left2, p)
val right = toString(right, p) //
val op = "-"
lazy val s2 = left :: right :: Nil mkString op
if (parentPrecedence > p )
s"($s2)"
else s"$s2"
//case Prod is similar to Sum
....
}
}
推荐阅读
- google-bigquery - 使 BigQuery 表数据保持最新
- javascript - Javascript - 在for循环中根据条件分配变量
- python - 无论如何使用存储在变量中的值作为搜索类的另一个变量的键?
- python - 使用子进程模块时如何更改目录
- sql - 在 SQL 中替代 IN 以在更短的时间内执行它
- javascript - Q-Unit 全局故障
- java - N叉树的迭代复制(克隆)
- c - 如何在 xv6 系统调用中返回结构?
- ros - 如何将rviz中的机器人位置[amcl_pose(x,y)]设置为左上角的(0.0000,0.00000)
- amazon-web-services - 重启 nginx:未知指令“listen”