Python 实现极简小编译器编译程序1+2+3到栈式计算机
最近开始学习编译原理的课程:https://www.bilibili.com/video/BV16h411X7JY/
任务一、编译1+2+3到栈式计算机
栈式计算机有俩条指令,push n和add, push n即遇到数字n把数字n推进栈底,
add即遇到+号把栈顶和次栈顶的数字推出,计算俩者的和,计算后将和再推进去。
首先是二叉树
#二叉树
class Node:
def __init__(self,value=None,left=None,rigth=None):
self.value=value
self.left=left
self.rigth=rigth
def __repr__(self) -> str:
return f"TreeNode({self.value},{self.left},{self.rigth})"
我们想要的结构如下:
+ / \ + 3 / \ 1 2
#生成一颗语法树
def get_node_root(expression):
num = ''
root=Node()
for char in expression:
if char.isdigit():
num += char
else:
if root.value==None:
root.value=int(num)
num=''
parent=Node()
parent.value="+"
parent.left=root
root=parent
else:
node =Node()
node.value=int(num)
num=''
if root.left==None:
root.left=node
elif root.rigth==None:
root.rigth=node
parent=Node()
parent.value="+"
parent.left=root
root=parent
else:
parent=Node()
parent.value="+"
parent.left=root
parent.rigth=node
root=parent
if num:
node=Node()
node.value=int(num)
root.rigth=node
#print(root)
return root
这里主要是判断是否是int 类型的。然后设置左节点、和又节点、并且设置值。如果进入到else 中那么此刻就是+ 这里可能会存在一些问题。
例如1+2+3-6 这样的就会存在问题
然后就是一个遍历树的节点了。通常使用的是 树的后序遍历 postOrder
#1+2+3到栈式计算机
# 栈式计算机有两指令 push n 和add push n 碰到数字就进行压栈
# add 遇到+ 就把栈顶的数字推出、计算两者的和、计算后在推入栈中
#二叉树
class Node:
def __init__(self,value=None,left=None,rigth=None):
self.value=value
self.left=left
self.rigth=rigth
def __repr__(self) -> str:
return f"TreeNode({self.value},{self.left},{self.rigth})"
#生成一颗语法树
def get_node_root(expression):
num = ''
root=Node()
for char in expression:
if char.isdigit():
num += char
else:
if root.value==None:
root.value=int(num)
num=''
parent=Node()
parent.value="+"
parent.left=root
root=parent
else:
node =Node()
node.value=int(num)
num=''
if root.left==None:
root.left=node
elif root.rigth==None:
root.rigth=node
parent=Node()
parent.value="+"
parent.left=root
root=parent
else:
parent=Node()
parent.value="+"
parent.left=root
parent.rigth=node
root=parent
if num:
node=Node()
node.value=int(num)
root.rigth=node
#print(root)
return root
#树的后续遍历 从左右中
def GetRoot(root):
instructions = []
def traverse(node):
if node is None:
return
traverse(node.left)
if node.rigth is not None:
# 访问右子节点
traverse(node.rigth)
if isinstance(node.value, int):
instructions.append(f'push {node.value}')
else:
instructions.append('add')
traverse(root)
return instructions
#打印语法数
def print_tree(root, level=0, prefix="", is_left=True):
if root is not None:
# 打印当前节点的值
print(' ' * (level * 10) + prefix + ' ' + str(root.value))
# 递归打印左子树
print_tree(root.left, level + 1, prefix + "", True)
# 递归打印右子树
if root.rigth is not None:
print_tree(root.rigth, level + 1, prefix + "", False)
#执行push n 和add指令
def GetReult(instructions):
stack = []
for instruction in instructions:
if instruction.startswith('push'):
stack.append(int(instruction[5:])) # 将数字推入栈
elif instruction == 'add':
if len(stack) < 2:
#如果不足两个直接返回
return stack[0]
a = stack.pop()
b = stack.pop()
stack.append(a + b) # 执行加法并将结果推回栈
return stack[0] if stack else None
expression = "1+2+4"
root_infos = get_node_root(expression)
print("打印树")
print_tree(root_infos)
instructions=GetRoot(root_infos)
ret=GetReult(instructions)
print("执行结果",ret)
此刻的指令这样的。
push 1 push 2 add push 4 add
任务二:增加一个代码优化的阶段

