编译原理实验:代码生成作业(2)

目录Code.h 生成mips中间代码主函数Code.h 生成mips中间代码在之前实验三的基础上改的,有冗余代码,我也不想删了#ifndef __CODE_H__#define __CODE_H__#include <ConstantAndVariable.h>#include <Function.h>#include <KV.h>#include <algorithm>#include <ctype.h&..
摘要由CSDN通过智能技术生成

目录

Code.h 生成mips中间代码

 主函数


Code.h 生成mips中间代码

在之前实验三的基础上改的,有冗余代码,我也不想删了

#ifndef __CODE_H__
#define __CODE_H__
#include <ConstantAndVariable.h>
#include <Function.h>
#include <KV.h>
#include <algorithm>
#include <ctype.h>
#include <fstream>
#include <iostream>
#include <map>
#include <queue>
#include <string.h>
#include <utility>
#include <vector>
using namespace std;
class Code {
private:
public:
    // 全局变量表
    vector<ConstantAndVariable*> ConstantsdAndvariables;
    // 全局函数表
    vector<Function*> Functions;
    //树的根节点
    KV* root;
    //当前的作用域
    string build_scope = "GLOBAL";
    // mips .data输出结果,先存一个临时的字符串进去
    string mips_data_out = ".data\n\tendline : .asciiz \"\\n\"\n";
    // mips .text输出结果
    string mips_text_out = ".text\n";
    Code() { }
    Code(KV* tree_root)
    {
        this->root = tree_root;
    }
    ~Code() { }

    // 对树进行遍历
    void mips_code_generate()
    {
        vector<KV*> stacks;
        stacks.push_back(this->root);
        while (stacks.size() > 0) {
            KV* current = stacks.back();
            stacks.pop_back();
            if (!current->isleaf()) {
                //主函数
                if (judge_main_function(current)) {
                }
                //常量定义
                else if (judge_constant_definition(current)) {
                    // do nothing
                }
                //变量定义无初始化
                else if (judge_Variable_definition_with_no_initialization(current)) {
                    for (int i = current->get_children().size() - 1; i >= 0; i--) {
                        stacks.push_back(current->get_children()[i]);
                    }
                    //变量定义及初始化
                } else if (judge_Variable_definition_with_initialization(current)) {
                    for (int i = current->get_children().size() - 1; i >= 0; i--) {
                        stacks.push_back(current->get_children()[i]);
                    }
                } else {
                    for (int i = current->get_children().size() - 1; i >= 0; i--) {
                        stacks.push_back(current->get_children()[i]);
                    }
                }
            }

            else {
                // do nothing
            }
        }
    }

    //主函数
    bool judge_main_function(KV* root)
    {

        if (root->category_code == "<主函数>") {

            string temp_name = root->children[1]->value;
            string temp_type = root->children[0]->category_code;
            build_scope = "void_main";

            KV* compound_statement = root->children[5];

            check_compound_sentence_in_main(compound_statement);
            return true;
        } else {
            return false;
        }
    }

    // <常量定义> judge_constant_definition(),用于建立变量表
    bool judge_constant_definition(KV* root)
    {

        if (root->category_code == "<常量定义>") {
            string temp_name = "\0";
            string temp_type = root->children[0]->category_code;
            int temp_index = 1;
            while (temp_index < root->get_children().size()) {
                if (match_IDENFR(root->children[temp_index])) {
                    temp_name = root->children[temp_index]->value;

                    // 生成常量的mips .data代码
                    if (temp_type == "INTTK") {
                        mips_data_out += "\t" + temp_name + " : .word ";
                    } else if (temp_type == "CHARTK") {
                        mips_data_out += "\t" + temp_name + " : .asciiz ";
                    } else {
                        // do nothing
                    }

                    ConstantAndVariable* temp_constant = new ConstantAndVariable(temp_name, temp_type, true, 0, true, build_scope);
                    ConstantsdAndvariables.push_back(temp_constant);
                    temp_index++;
                    temp_index++;
                    // 生成常量的mips .data代码,我就不考虑字符串了
                    if (root->children[temp_index]->category_code == "<整数>") {
                        KV* temp_int = root->children[temp_index];
                        for (KV* temp_int_member : temp_int->children) {
                            if (temp_int_member->category_code == "<无符号整数>") {
                                mips_data_out += temp_int_member->children[0]->value + "\n";
                            } else {
                                mips_data_out += temp_int_member->value;
                            }
                        }
                    }
                    temp_index++;
                }
                if (temp_index == root->get_children().size()) {
                    break;
                } else if (match_COMMA(root->children[temp_index])) {
                    temp_index++;
                    continue;
                }
            }
            return true;

        } else {
            return false;
        }
    }

    // <变量定义无初始化> judge_Variable_definition_with_no_initialization(),用于建立变量表,只需要记录维度就好
    bool judge_Variable_definition_with_no_initialization(KV* root)
    {
        if (root->category_code == "<变量定义无初始化>") {
            string temp_name = "\0";
            string temp_type = root->children[0]->category_code;
            int temp_index = 1;
            while (temp_index < root->get_children().size()) {
                if (match_IDENFR(root->children[temp_index])) {
                    temp_name = root->children[temp_index]->value;

                    // 生成变量定义无初始化的mips .data代码
                    if (temp_type == "INTTK") {
                        mips_data_out += "\t" + temp_name + " : .word 0\n";
                    } else if (temp_type == "CHARTK") {
                        mips_data_out += "\t" + temp_name + " : .asciiz \"init\"\n";
                    } else {
                        // do nothing
                    }
                    temp_index++;
                    if (temp_index == root->get_children().size()) {
                        ConstantAndVariable* temp_constant = new ConstantAndVariable(temp_name, temp_type, false, 0, false, build_scope);
                        ConstantsdAndvariables.push_back(temp_constant);
                        break;
                    } else if (match_COMMA(root->children[temp_index])) {
                        ConstantAndVariable* temp_constant = new ConstantAndVariable(temp_name, temp_type, false, 0, false, build_scope);
                        ConstantsdAndvariables.push_back(temp_constant);
                        temp_index++;
                        continue;
                    }
                    //<类型标识符> <标识符>'['<无符号整数>']'
                    else if (match_LBRACK(root->children[temp_index])) {
                        temp_index++;
                        temp_index++;
                        temp_index++;
                        if (temp_index == root->get_children().size()) {
                            ConstantAndVariable* temp_constant = new ConstantAndVariable(temp_name, temp_type, false, 1, false, build_scope);
                            ConstantsdAndvariables.push_back(temp_constant);
                            break;
              
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实验为实现一个小型的 C 语言MIPS 汇编语言编译器,需要完成以上所有步骤并验证测试正确。实验需要选择一个合适的 C 语言子集,能够体现 C 语言基本语法,特有关键字等,同时要能在这个子集的基础上写出具有特色的测试程序。在通过本实验所做编译器编译完成后,通过 MARS 汇编器将汇编代码汇编为汇编语言后测试运行结果需和 C 程序功能预期结果相符。 实验分为四次,依次完成词法和语法分析,静态语义分析、中间代码生成和代码优化,目标代码生成。同时为了体现课程之间的关联性,测试程序最终生成的机器代码将在计算机组成原理课程设计所设计的 CPU 中执行。 词法和语法分析器分别利用现有工具,Flex,Bison 完成,根据输入的文法和语法树构建规则自动生成分析源程序的 C 语言程序,生成抽象语法树并打印之。 语义分析器需要一个 C 语言程序,通过遍历抽象语法树构造符号表并检验上下文是否有语义错误。 中间代码生成器在语义分析器的基础上,在同一遍遍历语法树的基础上,利用当下的符号表生成中间代码。优化器需要一个新的 C 程序,接收中间代码, 利用DAG 算法生成图,并在此基础上进行代码重构和优化,输出优化后的代码。目标代码生成器需要一个单独的 C 程序,接收中间代码序列在中间代码的基 础上,根据中间代码节点的类型,为临时变量,以及存储器变量的值和地址分配寄存器,并生成目标代码。 实验的任务主要是通过对简单编译器的完整实现,加深课程中关键算法的理解,提高学生系统软件研发技术。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值