编译原理实验:错误处理程序(4)

本文介绍了编译原理实验中关于错误处理和语义分析的部分,重点是`Semantic.h`头文件的使用。主函数部分讨论了如何生成和处理输出,包括`output.txt`存放语法分析结果,`out.txt`用于树的可视化,借助Python的graphviz库和`drawtree.py`脚本实现。此外,`error.txt`文件记录错误信息,错误处理涉及错误的重排和去重策略。
摘要由CSDN通过智能技术生成

目录

Semantic.h 用于语义分析错误

主函数

注意点


Semantic.h 用于语义分析错误

#ifndef __SEMANTIC_H__
#define __SEMANTIC_H__
#include <ConstantAndVariable.h>
#include <Error.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 Semantic {
private:
    //树的根节点
public:
    // 全局变量表
    vector<ConstantAndVariable*> ConstantsdAndvariables;
    // 全局函数表
    vector<Function*> Functions;
    KV* root;
    //当前的作用域
    string build_scope = "GLOBAL";

    //错误输出结果
    string errorout = "\0";

    //错误处理
    vector<Error> errors;

    Semantic() { }
    Semantic(KV* tree_root, vector<Error>& x)
    {
        this->root = tree_root;
        errors.assign(x.begin(), x.end());
    }
    ~Semantic() { }
    // 对树进行遍历,对于词法分析的错误已经有了,对于语法分析出的错误,已经在树里了,这里我选择先遍历一遍树,把语法分析的错误提取出来

    void find_grammar_error()
    {
        vector<KV*> stacks;
        stacks.push_back(this->root);
        while (stacks.size() > 0) {
            KV* current = stacks.back();
            stacks.pop_back();
            if (!current->isleaf()) {
                for (int i = current->get_children().size() - 1; i >= 0; i--) {
                    stacks.push_back(current->get_children()[i]);
                }
            }
            //语法报错
            else if (current->isleaf() && current->category_code == "error") {
                Error error = Error(current->get_value(), to_string(current->get_lineindex()));
                errors.push_back(error);
            } else {
                // do nothing
            }
        }
    }
    void find_semantic_error()
    {
        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_Function_definition_with_return_value(current)) {
                }
                //无返回值函数定义
                else if (judge_Function_definition_without_return_value(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";

            // 错误处理 重名b
            if (check_function_Name_redefinition(root->children[1])) {
                // do nothing
            }

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

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

    // 无返回值函数定义 提取参数表,变量名,返回类型
    bool judge_Function_definition_without_return_value(KV* root)
    {
        if (root->category_code == "<无返回值函数定义>") {
            string temp_name = root->children[1]->value;
            string temp_type = root->children[0]->category_code;
            build_scope = temp_type + "_" + temp_name;
            // 错误处理 重名b
            if (check_function_Name_redefinition(root->children[1])) {
                // do nothing
            }

            Function* function = new Function(temp_name, temp_type);

            //处理参数表
            KV* parameter_table = root->children[3];
            string parameter_table_temp_name = "\0";
            string parameter_table_temp_type = "\0";
            for (KV* parameter : parameter_table->children) {
                if (match_INTTK(parameter) || match_CHARTK(parameter)) {
                    parameter_table_temp_type = parameter->category_code;
                    function->add_parameter(parameter->category_code);
                } else if (parameter->category_code == "IDENFR") {
                    string parameter_table_temp_name = parameter->value;
                    ConstantAndVariable* temp_constant = new ConstantAndVariable(parameter_table_temp_name, parameter_table_temp_type, false, 0, false, build_scope);
                    ConstantsdAndvariables.push_back(temp_constant);
                }
            }
            Functions.push_back(function);

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

            check_compound_sentence_in_function_definition_without_return_value(compound_statement, temp_type);
            // for (KV* child : compound_statement->children) {
            //     if (child->category_code == "<常量说明>") {
            //         KV* constant_description = child;
            //         for (KV* constant_description_member : constant_description->children) {
            //             if (judge_constant_definition(constant_description_member)) {
            //                 // do nothing;
            //             }
            //         }
            //     } else if (child->category_code == "<变量说明>") {
            //         KV* variable_description = child;
            //         for (KV* variable_description_member : variable_description->children) {
            //             if (variable_description_member->category_code == "<变量定义>") {
            //                 KV* variable_definition = variable_description_member;
            //                 for (KV* variable_definition_member : variable_definition->children) {
            //                     if (judge_Variable_definition_with_no_initialization(variable_definition_member)) {
            //                     }
            //                     if (judge_Variable_definition_with_initialization(variable_definition_member)) {
            //                     }
            //                 }
            //             }
            //         }
            //     } else if (child->category_code == "<语句列>") {
            //         for (KV* sentence : child->children) {
            //             //处理g类型错误,我的理解是遍历去找返回语句,要么没有,要有的话返回语句的父节点必定只有两个子节点
            //             if (sentence->children[0]->category_code == "<返回语句>" && sentence->children[0]->children.size() > 1) {
            //                 Error error = Error("g", to_string(sentence->children[0]->lineindex));
            //                 errors.push_back(error);
            //             }
            //         }
            //     }
            // }

            return true;
        } else {
            return false;
        }
    }

    // 有返回值函数定义 提取参数表,变量名,返回类型
    bool judge_Function_definition_with_return_value(KV* root)
    {

        bool flag_return = false;
        // 检查有无return语句
        bool& return_flag = flag_return;
        if (root->category_code == "<有返回值函数定义>") {
            string temp_name = root->children[0]->children[1]->value;
            string temp_type = root->children[0]->children[0]->category_code;
            build_scope = temp_type + "_" + temp_name;
            // 错误处理 重名b
            if (check_function_Name_redefinition(root->children[0]->children[1])) {
                // do nothing
            }

            Function* function = new Function(temp_name, temp_type);

            //处理参数表
            KV* parameter_table = root->children[2];
            string parameter_table_temp_name = "\0";
            string parameter_table_temp_type = "\0";
            for (KV* parameter : parameter_table->children) {
                if (match_INTTK(parameter) || match_CHARTK(parameter)) {
                    parameter_table_temp_type = parameter->category_code;
                    function->add_parameter(parameter->category_code);
                } else if (parameter->category_code == "IDENFR") {
                    string parameter_table_temp_name = parameter->value;
                    ConstantAndVariable* temp_constant = new ConstantAndVariable(parameter_table_temp_name, parameter_table_temp_type, false, 0, false, build_scope);
                    ConstantsdAndvariables.push_back(temp_constant);
                }
            }

            Functions.push_back(function);

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

            check_compound_sentence_in_function_definition_with_return_value(compound_statement, return_flag, temp_type);

            // 没有return语句
            if (return_flag == false) {
                Error error = Error("h", to_string(root->children.back()->lineindex));
                errors.push_back(error);
            }

            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;
                    if (check_Name_redefinition(root->children[temp_index])) {
                        // donothing
                    }
                    ConstantAndVariable* temp_constant = new ConstantAndVariable(temp_name, temp_type, true, 0, true, build_scope);
                    ConstantsdAndvariables.push_back(temp_constant);
                    temp_index++;
                    temp_index++;
                    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;
                    if (check_Name_redefinition(root->children[temp_index])) {
                        // donothing
                    }
                    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;
                        } else if (match_COMMA(root->children[temp_index])) {
                            ConstantAndVariable* temp_constant = new ConstantAndVariable(temp_name, temp_type, false, 1, 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, 2, 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, 2, false, build_scope);
                                ConstantsdAndvariables.push_back(temp_constant);
                           
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值