之前 模拟生态时 碰到个 python转换木兰的问题,因为影响运算结果且常碰到,打算将其修正。
先用原始木兰可执行文件,对 a=2*(1+3)
-p 转为python
以及 -s 转为木兰,括号都未保留,变为 a=2*1+3
,看来此问题一直都在。
用 木兰/功用/py语法树.py
将 a=2*(1+3)
的语法树输出,如下:
Module(
body=[Assign(
targets=[Name(
id='a'
ctx=Store()
lineno=1
col_offset=0
)]
value=BinOp(
left=Num(
n=2
lineno=1
col_offset=2
)
op=Mult()
right=BinOp(
left=Num(
n=1
lineno=1
col_offset=5
)
op=Add()
right=Num(
n=3
lineno=1
col_offset=7
)
lineno=1
col_offset=5
)
lineno=1
col_offset=2
)
lineno=1
col_offset=0
)]
)
用原始的 ulang -a
以及重现版的 木兰 -树
输出语法树相同,看来解析为语法树这步无误,应该是生成的问题。
语法树里是 BinOp,于是找到 visit_BinOp
,对照 visit_BoolOp
一样首尾加上括号:
def visit_BinOp(self, 节点):
self.编写('(')
self.visit(节点.left)
self.编写(' %s ' % 二元操作符[type(节点.op)])
self.visit(节点.right)
self.编写(')')
测试发现会加很多不必要的括号如:数列[(位置 + 1)]
,于是判断一下左右节点类型:
def visit_BinOp(self, 节点):
if isinstance(节点.left, BinOp):
self.编写('(')
self.visit(节点.left)
self.编写(')')
else:
self.visit(节点.left)
self.编写(' %s ' % 二元操作符[type(节点.op)])
if isinstance(节点.right, BinOp):
self.编写('(')
self.visit(节点.right)
self.编写(')')
else:
self.visit(节点.right)
上面的情况是不加括号了,不过还是有些比如:2 + 3 - 4 * 5
=> (2 + 3) - (4 * 5)
之后可以根据优先级判断是否需要,但至少结果无误了,在之前的生态例程测试也通过。
先到这里。详见 此提交。