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

编程入门 行业动态 更新时间:2024-10-09 07:25:37

编译<a href=https://www.elefans.com/category/jswz/34/1770123.html style=原理实验:错误处理程序(5)"/>

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

目录

希冀平台提交版本


作者lmx

希冀平台提交版本

#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#include <fstream>
#include <iostream>
#include <map>
#include <vector>
#include<queue>using namespace std;template<typename T>
void saveTree(T node,string path)
{ofstream ofile;ofile.open(path);queue<T> q_node;q_node.push(node);while (!q_node.empty()) {T tmp_node = q_node.front();q_node.pop();if (!tmp_node->isleaf()) {for (T child : tmp_node->get_children()) {if (!child->isleaf()) {q_node.push(child);ofile << tmp_node->get_category_code()<<" : "<<tmp_node->get_value()<<" "<<tmp_node->get_lineindex()<< "<_>" << tmp_node->get_id()<< "<->>" << child->get_category_code() <<" : "<<child->get_value() <<" "<<child->get_lineindex()<<"<_>" << child->get_id() << endl;}else {ofile << tmp_node->get_category_code() <<" : "<<tmp_node->get_value()<<" "<<tmp_node->get_lineindex()<< "<_>" << tmp_node->get_id()<< "<->>" << child->get_category_code() <<" : "<<child->get_value()<<" "<<child->get_lineindex() << "<_>" << child->get_id() << "<_>leaf"<< endl;}}}}ofile.close();
}static int CUR_ID = 0;class Error {
private:
public:string error_type = "\0";string error_lineindex = "\0";Error(string error_type, string error_lineindex){this->error_type = error_type;this->error_lineindex = error_lineindex;}~Error() { }bool operator==(const Error& other){if(this->error_type == other.error_type&&this->error_lineindex == other.error_lineindex){return true;}else{return false;}}bool operator<(const Error& other){if(atoi(this->error_lineindex.c_str()) <atoi(other.error_lineindex.c_str()) ){return true;}else{return false;}}
};//键值对
class KV {
public:int id = 0;string category_code="<空>";string value="\0";int lineindex = 0;vector<KV*> children;//构造函数KV() { }KV(string category_code, string value, int lineindex){this->id = CUR_ID++;this->category_code = category_code;this->value = value;this->lineindex = lineindex;}KV(string category_code){this->id = CUR_ID++;this->category_code = category_code;}KV(string category_code,int lineindex){this->id = CUR_ID++;this->category_code = category_code;this->lineindex= lineindex;}//构造函数~KV() { }// void set_KV(KV other)// {//     this->value = other-value;//     this->lineindex = other.lineindex;//     this->category_code = other->category_code;// }// 添加孩子void addchildren(KV* child){children.push_back(child);}// 弹出孩子void popchildren(){children.pop_back();}bool isleaf(){if(children.size() == 0){return true;}else{return false;}}vector<KV*> get_children(){return children;}string get_category_code(){return category_code;}int get_lineindex(){return lineindex;}string get_value(){return value;}int get_id(){return id;}//重载运算符// KV operator=(const KV& other) {//         KV kv;//         kv.category_code = other.category_code;//         kv.lineindex= other.lineindex;//         kv.value=other.value;//         return KV(other.category_code,other.value,other.lineindex);// }
};class Token {
private:string filename;map<string, string> Category_code = { { "identifier", "IDENFR" },{ "else", "ELSETK" },{ "-", "MINU" },{ "=", "ASSIGN" },{ "int_constant", "INTCON" },{ "switch", "SWITCHTK" },{ "*", "MULT" },{ ";", "SEMICN" },{ "char_constant", "CHARCON" },{ "case", "CASETK" },{ "/", "DIV" },{ ",", "COMMA" },{ "character_string", "STRCON" },{ "default", "DEFAULTTK" },{ "<", "LSS" },{ "(", "LPARENT" },{ "const", "CONSTTK" },{ "while", "WHILETK" },{ "<=", "LEQ" },{ ")", "RPARENT" },{ "int", "INTTK" },{ "for", "FORTK" },{ ">", "GRE" },{ "[", "LBRACK" },{ "char", "CHARTK" },{ "scanf", "SCANFTK" },{ ">=", "GEQ" },{ "]", "RBRACK" },{ "void", "VOIDTK" },{ "printf", "PRINTFTK" },{ "==", "EQL" },{ "{", "LBRACE" },{ "main", "MAINTK" },{ "return", "RETURNTK" },{ "!=", "NEQ" },{ "}", "RBRACE" },{ "if", "IFTK" },{ "+", "PLUS" },{ ":", "COLON" } };public://存放键值对vector<KV> KVS;//行号int lineindex = 0;//错误处理vector <Error> errors;//构造函数Token() { }//构造函数~Token() { }//压入tokemvoid push_KV(string category_code, string value, int lineindex){KV temp = KV(category_code, value, lineindex);KVS.push_back(temp);}bool isdigit(char x) //判断数字{return x >= '0' && x <= '9';}bool isletter(char x) //判断字母{return (x >= 'a' && x <= 'z') || (x >= 'A' && x <= 'Z');}string to_lower(string str) //大写转小写{int i = 0;while (str[i]) {if (str[i] > 'A' && str[i] < 'Z') {str[i] += 32;}i++;}return str;}// 词法分析string lexical_analysis(string filename){//词法分析输出结果string out = "";// 类别码初始化fstream fin;fin.open(filename);if (!fin.is_open()) {cout << "Could not find the file\n";cout << "Program terminating\n";system("pause");exit(EXIT_FAILURE);}string temp = "\0";//每次读一行while (getline(fin, temp)) {//记录行号lineindex++;// curr指针,初始指向0int curr = 0;// FDA状态int state = 0;//临时拼接字符串string temp_concat = "\0";while (curr < temp.length() || temp_concat != "\0") {switch (state) {case 0://去除非常见字符if (temp[curr] - '\0' <= 32) {// do nothing}//如果是字母或者是下划线进入状态1,标识符或者是基本类型else if (isletter(temp[curr]) || temp[curr] == '_') {state = 1;temp_concat += temp[curr];}//如果是数字那么进入状态2,整形常量else if (isdigit(temp[curr])) {state = 2;temp_concat += temp[curr];} else {string curr_char = "\0";curr_char += temp[curr];switch (temp[curr]) {case '+':push_KV(Category_code[curr_char], string(1, temp[curr]),lineindex);break;case '-':push_KV(Category_code[curr_char], string(1, temp[curr]),lineindex);break;case '*':push_KV(Category_code[curr_char], string(1, temp[curr]),lineindex);break;case '/':push_KV(Category_code[curr_char], string(1, temp[curr]),lineindex);break;case ';':push_KV(Category_code[curr_char], string(1, temp[curr]),lineindex);break;case ',':push_KV(Category_code[curr_char], string(1, temp[curr]),lineindex);break;case '(':push_KV(Category_code[curr_char], string(1, temp[curr]),lineindex);break;case ')':push_KV(Category_code[curr_char], string(1, temp[curr]),lineindex);break;case '[':push_KV(Category_code[curr_char], string(1, temp[curr]),lineindex);break;case ']':push_KV(Category_code[curr_char], string(1, temp[curr]),lineindex);break;case '{':push_KV(Category_code[curr_char], string(1, temp[curr]),lineindex);break;case '}':push_KV(Category_code[curr_char], string(1, temp[curr]),lineindex);break;case ':':push_KV(Category_code[curr_char], string(1, temp[curr]),lineindex);break;case '\'': // 表明字符常量state = 3;break;case '"': // 表明字符串常量state = 4;break;case '<': //<= ? <state = 5;break;case '>': //>= ? >state = 6;break;case '=': //== ? =state = 7;break;case '!': //! ? !=state = 8;break;default: //錯誤借口state = -1;break;}}break;//标识符或者基本类型case 1://如果继续跟数字或字母继续拼接标识符或者基本类型if (isalnum(temp[curr]) || temp[curr] == '_') {temp_concat += temp[curr];state = 1;}//否则标识符拼装完成else {//先去判断是不是基本类型,并清空拼接字符串,指针回退if (Category_code.find(to_lower(temp_concat)) != Category_code.end()) {push_KV(Category_code[to_lower(temp_concat)], temp_concat, lineindex);temp_concat = "";curr--;state = 0;}// 否则就是标识符,刷新字符拼接,返回状态0else {push_KV(Category_code["identifier"], temp_concat, lineindex);state = 0;temp_concat = "";curr--;}}break;//整型常量case 2://如果还是数字,继续拼接整形常量if (isdigit(temp[curr])) {temp_concat += temp[curr];state = 2;}//否则整形常量拼接完成,指针回退,返回状态0else {push_KV(Category_code["int_constant"], temp_concat, lineindex);state = 0;temp_concat = "";curr--;}break;// 字符常量case 3://如果没有碰到',继续拼接字符常量if (temp[curr] != '\'') {//错误处理if((temp[curr]-'\0'== 42)||(temp[curr]-'\0'== 43)||(temp[curr]-'\0'== 45)||(temp[curr]-'\0'== 47)||(temp[curr]-'\0'<=57&&temp[curr]-'\0'>=48)||(temp[curr]-'\0'<='z'&&temp[curr]-'\0'>='a')||(temp[curr]-'\0'<='Z'&&temp[curr]-'\0'>='A')||temp[curr]=='_'){}else{Error error = Error("a",to_string(lineindex));errors.push_back(error);}temp_concat += temp[curr];state = 3;}//如果碰到',转回状态0,清空拼接字符串,但注意这里不需要回退指针else {push_KV(Category_code["char_constant"], temp_concat, lineindex);state = 0;temp_concat = "";}break;// 字符串常量case 4://如果没有碰到',继续拼接字符常量if (temp[curr] != '"') {//错误处理if((temp[curr]-'\0'== 32)||(temp[curr]-'\0'== 33)||(temp[curr]-'\0'<=126&&temp[curr]-'\0'>=35)){}else{   Error error = Error("a",to_string(lineindex));errors.push_back(error);}temp_concat += temp[curr];state = 4;}//如果碰到',转回状态0,清空拼接字符串,但注意这里不需要回退指针else {push_KV(Category_code["character_string"], temp_concat,lineindex);state = 0;temp_concat = "";}break;//<= ? <case 5:// <= 回退状态0if (temp[curr] == '=') {push_KV(Category_code["<="], "<=",lineindex);state = 0;}//< 回退状态0,回退指针else {push_KV(Category_code["<"], "<",lineindex);state = 0;curr--;}break;case 6:// >= 回退状态0if (temp[curr] == '=') {push_KV(Category_code[">="],">=",lineindex);state = 0;}//> 回退状态0,回退指针else {push_KV(Category_code[">"],">",lineindex);state = 0;curr--;}break;case 7:// == 回退状态0if (temp[curr] == '=') {push_KV(Category_code["=="],"==",lineindex);state = 0;}//< 回退状态0,回退指针else {push_KV(Category_code["="],"=",lineindex);state = 0;curr--;}break;case 8:// != 回退状态0if (temp[curr] == '=') {push_KV(Category_code["!="],"!=",lineindex);state = 0;}//! 报错else {state = -1;}break;case -1:cout << "wrong answer skip" << endl;curr--;break;}//移动指针curr++;}}out = "\0";for (int i = 0; i < KVS.size(); i++) {out += KVS[i].category_code + " " + KVS[i].value + "\n";}return out;}//读入验证文件,返回字符串string lexical_analysis_Verification(string filename){string vout = "";fstream fin;fin.open(filename);if (!fin.is_open()) {cout << "Could not find the file\n";cout << "Program terminating\n";system("pause");exit(EXIT_FAILURE);}string tempout = "";while (getline(fin, tempout)) {vout += tempout + "\n";}return vout;}//输入需要验证的文件夹序号进行验证void lexical_analysis_Verificate(int number){string out = "";for (int i = 1; i <= 10; i++) {string filename1 = "lexical_analysis\\" + to_string(number) + "\\testfile" + to_string(i) + ".txt";string filename2 = "lexical_analysis\\" + to_string(number) + "\\output" + to_string(i) + ".txt";string testout = lexical_analysis(filename1);string verificationout = lexical_analysis_Verification(filename2);out += ((verificationout == testout) ? "right" : "wrong");out += " ";KVS.clear();KVS.clear();}cout << out << endl;}
};class ConstantAndVariable{private:public://变量名string name;//变量的类型string type;//作用域string scope;//是否为常量bool isConstant=false;//维度int dim=0;// 有无初始化bool initialization=false;ConstantAndVariable() {}ConstantAndVariable(string name, string type,bool isConstant,int dim ,bool initialization ,string scope) {this->name = name;this->type = type;this->isConstant = isConstant;this->dim = dim;this->initialization = initialization;this->scope = scope;}~ConstantAndVariable(){}};class Grammar {
private:
public://键值对vector<KV> KVS;//语法分析结果vector<KV> outputKVS;//分辨有返回值还是无返回值的函数//(标识符,类型标识符)map<string, string> function_with_or_without_return_map;//指针int index = 0;//行号int lineindex = 0;//树的根节点KV* root = new KV();Grammar() { }~Grammar() { }Grammar(vector<KV>& x){KVS.assign(x.begin(), x.end());index = 0;}void display(){for (int i = 0; i < KVS.size(); i++) {cout << KVS[i].category_code << " " << KVS[i].value << " " << endl;}}//程序主入口 [<常量说明>][<变量说明>]{<有返回值函数定义>|<无返回值函数定义>}<主函数>void procedure(KV* parent){KV* current = new KV("<程序>",KVS[index].lineindex);parent->addchildren(current);// [<常量说明>]if (constant_description(current)) {}// [<变量说明>]if (variable_description(current)) {}// {<有返回值函数定义>|<无返回值函数定义>}while (index < KVS.size()) {if (function_definition_with_return_value(current) || function_definition_without_return_value(current)) {} else {break;}}// <主函数>if (main_function(current)) {}push_Grammatical_definition("<程序>");}// <主函数>    ::= void main‘(’‘)’ ‘{’<复合语句>‘}’bool main_function(KV* parent){KV* current = new KV("<主函数>");parent->addchildren(current);bool flag = false;if (match_VOIDTK(current)) {push_token();if (match_MAINTK(current)) {push_token();if (match_LPARENT(current)) {push_token();if (match_RPARENT(current)) {push_token();if (match_LBRACE(current)) {push_token();if (compound_statement(current)) {if (match_RBRACE(current)) {push_token();push_Grammatical_definition("<主函数>");flag = true;}}}}//缺少)else {if (match_LBRACE(current)) {push_token();if (compound_statement(current)) {if (match_RBRACE(current)) {push_token();push_Grammatical_definition("<主函数>");flag = true;}}}}}}}return flag;}// <无返回值函数定义>  ::= void<标识符>'('<参数表>')''{'<复合语句>'}'bool function_definition_without_return_value(KV* parent){KV* current = new KV("<无返回值函数定义>",KVS[index].lineindex);parent->addchildren(current);bool flag = false;if (match_VOIDTK(current)) {push_token();if (match_IDENFR(current)) {push_token();if (match_LPARENT(current)) {//到这里一定是<无返回值函数定义>function_with_or_without_return_map[KVS[index - 1].value] = KVS[index - 2].category_code;push_token();if (parameter_table(current)) {if (match_RPARENT(current)) {push_token();if (match_LBRACE(current)) {push_token();if (compound_statement(current)) {if (match_RBRACE(current)) {push_token();push_Grammatical_definition("<无返回值函数定义>");flag = true;return flag;}}}}//缺少)else {if (match_LBRACE(current)) {push_token();if (compound_statement(current)) {if (match_RBRACE(current)) {push_token();push_Grammatical_definition("<无返回值函数定义>");flag = true;return flag;}}}}}}}//和void main 区别else {outputKVS.pop_back();index--;current->popchildren();flag = false;}}// 树节点弹出<无返回值函数定义>if (flag == false) {parent->popchildren();}return flag;}// <有返回值函数定义>  ::=  <声明头部>'('<参数表>')' '{'<复合语句>'}'bool function_definition_with_return_value(KV* parent){KV* current = new KV("<有返回值函数定义>",KVS[index].lineindex);parent->addchildren(current);bool flag = false;if (declaration_header(current)) {if (match_LPARENT(current)) {//到这里一定是<有返回值函数定义>function_with_or_without_return_map[KVS[index - 1].value] = KVS[index - 2].category_code;push_token();if (parameter_table(current)) {if (match_RPARENT(current)) {push_token();if (match_LBRACE(current)) {push_token();if (compound_statement(current)) {if (match_RBRACE(current)) {push_token();push_Grammatical_definition("<有返回值函数定义>");flag = true;return flag;}}}}// 缺少)else {if (match_LBRACE(current)) {push_token();if (compound_statement(current)) {if (match_RBRACE(current)) {push_token();push_Grammatical_definition("<有返回值函数定义>");flag = true;return flag;}}}}}}}// 树节点弹出<有返回值函数定义>if (flag == false) {parent->popchildren();}return flag;}// <复合语句>   ::=  [<常量说明>][<变量说明>]<语句列>bool compound_statement(KV* parent){KV* current = new KV("<复合语句>",KVS[index].lineindex);parent->addchildren(current);// [<常量说明>]if (constant_description(current)) {}// [<变量说明>]if (variable_description(current)) {}// <语句列>if (statement_column(current)) {push_Grammatical_definition("<复合语句>");return true;}return false;}// <语句列>   ::= {<语句>}bool statement_column(KV* parent){KV* current = new KV("<语句列>",KVS[index].lineindex);parent->addchildren(current);bool flag = false;while (index < KVS.size()) {//以}为终结符,如果匹配到},说明这时候<语句列>闭合,需要注意的是这里的树节点还是要把}弹出,因为他是在上一级调用的匹配的终结符if (match_RBRACE(current)) {current->popchildren();flag = true;break;} else if (sentence(current)) {flag = true;continue;} else {flag = true;break;}}if (flag == true) {push_Grammatical_definition("<语句列>");}// 树节点弹出<语句列>if (flag == false) {parent->popchildren();}return flag;}// <语句>    ::= <循环语句>|<条件语句>| <有返回值函数调用语句>;  |<无返回值函数调用语句>;|<赋值语句>;|<读语句>;|<写语句>;|<情况语句>|<空>;|<返回语句>; | '{'<语句列>'}'bool sentence(KV* parent){KV* current = new KV("<语句>",KVS[index].lineindex);parent->addchildren(current);bool flag = false;// <循环语句>if (circular_statement(current)) {flag = true;}//<条件语句>else if (conditional_statement(current)) {flag = true;}// 第一层筛查,判断函数名else if (function_with_or_without_return_map.find(KVS[index].value) != function_with_or_without_return_map.end()) {//第二层筛查,判断是不是void类型if (function_with_or_without_return_map[KVS[index].value] != "VOIDTK") {// <有返回值函数调用语句>;if (function_call_statement_with_return_value(current)) {if (match_SEMICN(current)) {push_token();flag = true;}// 缺少;,但为了继续执行并能存入树,这里还是要有flag=true的else {flag = true;}}} else {if (function_call_statement_without_return_value(current)) {if (match_SEMICN(current)) {push_token();flag = true;}// 缺少;,但为了继续执行并能存入树,这里还是要有flag=true的else {flag = true;}}}}//<赋值语句>;else if (assignment_statement(current)) {if (match_SEMICN(current)) {push_token();flag = true;}// 缺少;,但为了继续执行并能存入树,这里还是要有flag=true的else {flag = true;}}//<读语句>;else if (read_statement(current)) {if (match_SEMICN(current)) {push_token();flag = true;}// 缺少;,但为了继续执行并能存入树,这里还是要有flag=true的else {flag = true;}}//<写语句>else if (write_statement(current)) {if (match_SEMICN(current)) {push_token();flag = true;}// 缺少;,但为了继续执行并能存入树,这里还是要有flag=true的else {flag = true;}}// <情况语句>else if (situation_statement(current)) {flag = true;}// <返回语句>;else if (return_statement(current)) {if (match_SEMICN(current)) {push_token();flag = true;}// 缺少;,但为了继续执行并能存入树,这里还是要有flag=true的else {flag = true;}}//'{'<语句列>'}'else if (match_LBRACE(current)) {push_token();if (statement_column(current)) {if (match_RBRACE(current)) {push_token();flag = true;}} else {if (match_RBRACE(current)) {push_token();flag = true;}}}// <空>;else if (match_SEMICN(current)) {push_token();flag = true;} else {flag = false;}if (flag == true) {push_Grammatical_definition("<语句>");}// 树节点弹出<语句>if (flag == false) {parent->popchildren();}return flag;}// <返回语句>   ::=  return['('<表达式>')']bool return_statement(KV* parent){KV* current = new KV("<返回语句>",KVS[index].lineindex);parent->addchildren(current);bool flag = false;if (match_RETURNTK(current)) {push_token();flag = true;if (match_LPARENT(current)) {push_token();if (expression(current)) {if (match_RPARENT(current)) {push_token();flag = true;}// 缺少),但为了程序正常执行flag= trueelse {flag = true;}}}push_Grammatical_definition("<返回语句>");return flag;}// 树节点弹出<返回语句>if (flag == false) {parent->popchildren();}return flag;}// <情况语句>  ::=  switch ‘(’<表达式>‘)’ ‘{’<情况表><缺省>‘}’bool situation_statement(KV* parent){KV* current = new KV("<情况语句>",KVS[index].lineindex);parent->addchildren(current);bool flag = false;if (match_SWITCHTK(current)) {push_token();if (match_LPARENT(current)) {push_token();if (expression(current)) {if (match_RPARENT(current)) {push_token();if (match_LBRACE(current)) {push_token();while (index < KVS.size()) {if (situation_table(current)) {if (default_situation(current)) {continue;}// 缺少缺省语句,但是为了程序继续执行,这里跳过else {continue;}} else {break;}}if (match_RBRACE(current)) {push_token();flag = true;push_Grammatical_definition("<情况语句>");return flag;}}}// 缺少)else {if (match_LBRACE(current)) {push_token();while (index < KVS.size()) {if (situation_table(current)) {if (default_situation(current)) {continue;}// 缺少缺省语句,但是为了程序继续执行,这里跳过else {continue;}} else {break;}}if (match_RBRACE(current)) {push_token();flag = true;push_Grammatical_definition("<情况语句>");return flag;}}}}}}// 树节点弹出情况语句if (flag == false) {parent->popchildren();}return flag;}// <缺省>   ::=  default :<语句>bool default_situation(KV* parent){KV* current = new KV("<缺省>",KVS[index].lineindex);parent->addchildren(current);bool flag = false;if (match_DEFAULTTK(current)) {push_token();if (match_COLON(current)) {push_token();if (sentence(current)) {push_Grammatical_definition("<缺省>");flag = true;}}}// 树节点弹出<缺省> 压入缺少缺省语句树节点if (flag == false) {parent->popchildren();KV* temp = new KV("error", "p", KVS[index].lineindex);parent->addchildren(temp);}return flag;}// <情况表>   ::=  <情况子语句>{<情况子语句>}bool situation_table(KV* parent){KV* current = new KV("<情况表>",KVS[index].lineindex);parent->addchildren(current);bool flag = false;while (index < KVS.size()) {if (case_sub_statement(current)) {flag =

更多推荐

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

本文发布于:2024-02-06 05:52:31,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1746853.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:原理   错误   程序

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!