Python 实现极简小编译器编译程序1+2+3到栈式计算机

作者: print("") 分类: 编译原理 发布时间: 2024-12-12 22:45

最近开始学习编译原理的课程: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

任务二:增加一个代码优化的阶段


如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注