逆波兰实现中间代码生成
# -*- coding: utf-8 -*-
# @File : exp4.py
# @Author: kimoto
# @Date : 2018/12/21
# @Desc : 编译原理——简单的翻译程序
# 定义优先权
ops_rule = {
'+': 1,
'-': 1,
'*': 2,
'/': 2
}
# expression = []
def middle_to_after(s):
"""
中缀表达式转化后缀表达式.
:param s: 中缀表达式的字符串表示,本程序中采用操作符跟数值之间用空格分开,例如:
"9 + ( 3 - 1 ) * 3 + 10 / 2"
:return: 后缀表达式,数组的形式,每个数值或者操作符占一个数组下标.
"""
expression = []
ops = []
for item in s:
if item in ['+', '-', '*', '/']: # 操作符
while len(ops) >= 0:
if len(ops) == 0:
ops.append(item)
break
op = ops.pop()
if op == '(' or ops_rule[item] > ops_rule[op]:
ops.append(op)
ops.append(item)
break
else:
expression.append(op)
elif item == '(': # 左括号,直接入操作符栈
ops.append(item)
elif item == ')': # 右括号,循环出栈道
while len(ops) > 0:
op = ops.pop()
if op == '(':
break
else:
expression.append(op)
else:
expression.append(item) # 数值,直接入表达式栈
while len(ops) > 0:
expression.append(ops.pop())
return expression
def get_result(expression, i):
"""
:param expression: 表达式栈
:return: 四元式存放栈
"""
ss = [] # 输出栈
tmp = [] # 临时栈
for item in expression:
if(item not in ops_rule.keys()):
tmp.append(item)
else:
# print(tmp)
x = tmp.pop()
y = tmp.pop()
s = "({}, {}, {}, t{})".format(item, x, y, i)
tmp.append("t{}".format(i))
i+=1
ss.append(s)
return ss, i
def mprint(ss):
res = ""
for s in ss:
res += s + "\n"
return res
def app(slist):
i=1
output = []
for s in slist:
frist, later = s.split("=")
exps = middle_to_after(later)
# print(exps)
res, i = get_result(exps, i)
res.append("(=, t{}, -, {})".format(i - 1, frist))
#print(res)
output.extend(res)
# print(output)
return output
if __name__ == '__main__':
slist = ["a=b+c", "d=2*a"]
output = app(slist)
print(mprint(output))