⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chksupport.cpp

📁 一个用C++实现的C的Compiler。 代码风格良好。 原作者自己写了这个编译器
💻 CPP
📖 第 1 页 / 共 3 页
字号:
#ifndef __CHKSUPPORT_CPP__
#define __CHKSUPPORT_CPP__

#include <cstdio>
#include <iostream>
#include <algorithm>

#include "common.cpp"
#include "CHKsymtable.cpp"
#include "IDHash.cpp"

extern int PROGRAM_LineNumber;
extern char* PROGRAM_FileName;

struct Tmsg {
	int lineno;
	int sourcecount;
	string msgtxt;
};

vector <Tmsg> error_msgs;

void errormsg(int code, string str1, string str2, string str3);
bool compare_msg(const Tmsg& k1, const Tmsg& k2);
int errormsg_print();
string __int2str(int num);
string __vartype2str(int var_type);
string __vartype2str(TSymbolListVariableEntry& Ventry);

void errormsg(int code, int lineno, string str1 = "UNKNOWN", string str2 = "UNKNOWN", string str3 = "UNKNOWN")
{
	string str = "";
	for (int i = 0; error_message[code][i]; i++)
	{
		if (error_message[code][i] == '%')
		{
			i ++;
			switch (error_message[code][i])
			{
				case	'1'	:		str += str1;
									break;
				case	'2'	:		str += str2;
									break;
				case	'3'	:		str += str3;
									break;
				default		:		str += error_message[code][i];
			}
		}
		else
		{
			str += error_message[code][i];
		}
	}

	Tmsg tmpmsg;
	tmpmsg.lineno = lineno;
	tmpmsg.msgtxt = str;
	tmpmsg.sourcecount = error_msgs.size();
	error_msgs.push_back(tmpmsg);
}

bool compare_msg(const Tmsg& k1, const Tmsg& k2)
{
	if (k1.lineno != k2.lineno)
	{
		return (k1.lineno < k2.lineno);
	}
	else
	{
		return (k1.sourcecount < k2.sourcecount);
	}
}

int errormsg_print()
{
	sort(error_msgs.begin(), error_msgs.end(), compare_msg);
	for (unsigned int i = 0; i < error_msgs.size(); i++)
	{
		cout << PROGRAM_FileName << ":" << error_msgs[i].lineno << ": Compilation Error " << error_msgs[i].msgtxt << endl;
	}
	if (error_msgs.size() == 0)
	{
		return 1;
	}
	else
	{
		return 0;
	}
}

string __int2str(int num)
{
	char s[20];
	sprintf(s, "%d", num);
	return s;
}

string __vartype2str(int var_type)
{
	string res = "null type";
	if (var_type == var_type_void) res = "void";
	else if (var_type == var_type_int) res = "int";
	else if (var_type == var_type_bool) res = "bool";
	else if (var_type == var_type_double) res = "double";
	else if (var_type == var_type_char) res = "char";
	else if (var_type == var_type_notfound) res = "unknown type";
	else if (SymbolListType[var_type].type_number == type_number_struct) res = "struct " + IDHash_int2ID(var_type);
	else if (SymbolListType[var_type].type_number == type_number_pointer) res = __vartype2str(SymbolListType[var_type].ret_type_id) + "*";
	else if (SymbolListType[var_type].type_number == type_number_function)
	{
		res = __vartype2str(SymbolListType[var_type].ret_type_id) + "()(";
		for (list <TSymbolListVariableEntry> :: iterator p = SymbolListType[var_type].field_var.begin(); p != SymbolListType[var_type].field_var.end(); p ++)
		{
			if (p != SymbolListType[var_type].field_var.begin())
			{
				res += ",";
			}
			res += __vartype2str(p->var_type);
		}
		res += ")";
	}
	else if (SymbolListType[var_type].type_number == type_number_array)
	{
		res = __vartype2str(SymbolListType[var_type].ret_type_id);
		int i = res.length();
		for ( ; i >= 0; i --)
		{
			if ((i == (int)res.length() || res[i] == '[') && res[i - 1] != ']') break;
		}
		char buf[20];
		sprintf(buf, "[%d]", SymbolListType[var_type].array_size);
		res.insert(i, buf);
	}
	return res;
}

string __vartype2str(TSymbolListVariableEntry& Ventry)
{
	return __vartype2str(Ventry.var_type);
}

int __chk_bool_type(TSymbolListVariableEntry& Ventry)
{
	return (Ventry.var_type == var_type_bool || Ventry.var_type == var_type_int || Ventry.var_type == var_type_char ||
				Ventry.var_type >= 0 && SymbolListType[Ventry.var_type].type_number == type_number_pointer ||
				Ventry.var_type >= 0 && SymbolListType[Ventry.var_type].type_number == type_number_function);
}

int __chk_int_type(TSymbolListVariableEntry& Ventry)
{
	return (Ventry.var_type == var_type_bool || Ventry.var_type == var_type_int || Ventry.var_type == var_type_char ||
				Ventry.var_type >= 0 && SymbolListType[Ventry.var_type].type_number == type_number_pointer ||
				Ventry.var_type >= 0 && SymbolListType[Ventry.var_type].type_number == type_number_function);
}

int __chk_comparable_type(TSymbolListVariableEntry& var)
{
	return (__chk_int_type(var));
}

int __chk_logical_type(TSymbolListVariableEntry& var)
{
	return (__chk_bool_type(var));
}

int __chk_calculational_type(TSymbolListVariableEntry& var)
{
	return (__chk_int_type(var));
}

void CheckExprBinaryRelational(TSymbolListVariableEntry& var1, TSymbolListVariableEntry& var2, int op_type, TSymbolListVariableEntry& var)
{
	var.var_type = var_type_bool;
	var.const_sign = 0;
	var.lvalue = 0;
	if (var1.var_type == var_type_notfound || var2.var_type == var_type_notfound) return;
	if (op_type == SRC_relational_EQL || op_type == SRC_relational_NEQ)
	{
		if (__chk_bool_type(var1) && __chk_bool_type(var2))
		{
			var.var_type = var_type_bool;
			var.const_sign = 0;
			var.lvalue = 0;
			return;
		}
	}
	if (op_type == SRC_relational_LES || op_type == SRC_relational_LEQ || op_type == SRC_relational_GTR || op_type == SRC_relational_GEQ ||
			op_type == SRC_relational_EQL || SRC_relational_NEQ)
	{
		if ((var1.var_type >= 0 && SymbolListType[var1.var_type].type_number == type_number_pointer || var1.var_type == var_type_NULL) && 
			(var2.var_type >= 0 && SymbolListType[var2.var_type].type_number == type_number_pointer || var2.var_type == var_type_NULL))
		{
			var.var_type = var_type_bool;
			var.const_sign = 0;
			var.lvalue = 0;
			return;
		}
	}

	if (!__chk_comparable_type(var1) || !__chk_comparable_type(var2))
	{
		errormsg(7, PROGRAM_LineNumber, __vartype2str(var1), SRC_OP_name[op_type], __vartype2str(var2));
//		var.var_type = var_type_notfound;
		return;
	}
	var.var_type = var_type_bool;
	var.lvalue = 0;
	var.const_sign = 0;
}

void CheckExprBinaryLogical(TSymbolListVariableEntry& var1, TSymbolListVariableEntry& var2, int op_type, TSymbolListVariableEntry& var)
{
	var.var_type = var_type_bool;
	var.const_sign = 0;
	var.lvalue = 0;
	if (var1.var_type == var_type_notfound || var2.var_type == var_type_notfound) return;
	if (!__chk_logical_type(var1) || !__chk_logical_type(var2))
	{
		errormsg(7, PROGRAM_LineNumber, __vartype2str(var1), SRC_OP_name[op_type], __vartype2str(var2));
//		var.var_type = var_type_notfound;
		return;
	}
	var.var_type = var_type_bool;
	var.const_sign = 0;
	var.lvalue = 0;
}

void CheckPerformBinaryCalc(TSymbolListVariableEntry& var1, TSymbolListVariableEntry& var2, int op_type, TSymbolListVariableEntry& var)
{
	var.var_type = var_type_int;
	var.const_sign = 1;
	var.lvalue = 0;
	if (op_type == SRC_calculational_ADD) var.const_val = var1.const_val + var2.const_val;
	else if (op_type == SRC_calculational_MINUS) var.const_val = var1.const_val - var2.const_val;
	else if (op_type == SRC_calculational_MUL) var.const_val = var1.const_val * var2.const_val;
	else if (op_type == SRC_calculational_DIV) 
	{
		if (var2.const_val == 0) 
		{
			errormsg(37, PROGRAM_LineNumber);
			var.var_type = var_type_notfound;
			var.const_sign = 0;
			return;
		}
		var.const_val = var1.const_val / var2.const_val;
	}
	else if (op_type == SRC_calculational_MOD) 
	{
		if (var2.const_val == 0) 
		{
			errormsg(37, PROGRAM_LineNumber);
			var.var_type = var_type_notfound;
			var.const_sign = 0;
			return;
		}
		var.const_val = var1.const_val % var2.const_val;
	}
	else if (op_type == SRC_calculational_AND) var.const_val = var1.const_val & var2.const_val;
	else if (op_type == SRC_calculational_OR) var.const_val = var1.const_val | var2.const_val;
	else if (op_type == SRC_calculational_XOR) var.const_val = var1.const_val ^ var2.const_val;
	else if (op_type == SRC_calculational_SHL) var.const_val = var1.const_val << var2.const_val;
	else if (op_type == SRC_calculational_SHR) var.const_val = var1.const_val >> var2.const_val;
}

void CheckExprBinaryCalculational(TSymbolListVariableEntry& var1, TSymbolListVariableEntry& var2, int op_type, TSymbolListVariableEntry& var)
{
	var.var_type = var_type_notfound;
	var.const_sign = 0;
	var.lvalue = 0;
	if (var1.var_type == var_type_notfound || var2.var_type == var_type_notfound) return;
	if (op_type == SRC_calculational_ADD || op_type == SRC_calculational_MINUS)
	{
		if (var1.var_type >= 0 && 
			(SymbolListType[var1.var_type].type_number == type_number_pointer || SymbolListType[var1.var_type].type_number == type_number_array) &&
			__chk_int_type(var2))
		{
			var = var1;
			if (SymbolListType[var.var_type].type_number == type_number_array) 
			{
				var.var_type = SymbolListTypeADDStar(SymbolListType[var.var_type].ret_type_id);
			}
			var.lvalue = 0; var.const_sign = 0;
			return;
		}
	}
	if (!__chk_calculational_type(var1) || !__chk_calculational_type(var2))
	{
		errormsg(7, PROGRAM_LineNumber, __vartype2str(var1), SRC_OP_name[op_type], __vartype2str(var2));
		var.var_type = var_type_notfound;
		return;
	}
	if (op_type == SRC_calculational_MOD && (!__chk_int_type(var1) || !__chk_int_type(var2)))
	{
		errormsg(7, PROGRAM_LineNumber, __vartype2str(var1), SRC_OP_name[op_type], __vartype2str(var2));
		var.var_type = var_type_notfound;
		return;
	}
	if (var1.const_sign && var2.const_sign)
	{
		CheckPerformBinaryCalc(var1, var2, op_type, var);
		return;
	}

	var.var_type = var_type_int;
	var.const_sign = 0;
	var.lvalue = 0;
}

void CheckExprUnaryNOT(TSymbolListVariableEntry& var1, int op_type, TSymbolListVariableEntry& var)
{
	var.var_type = var_type_int;
	var.const_sign = 0;
	var.lvalue = 0;
	if (var1.var_type == var_type_notfound) return;
	if (!__chk_logical_type(var1) && !__chk_int_type(var1))
	{
		errormsg(8, PROGRAM_LineNumber, SRC_OP_name[op_type], __vartype2str(var1));
//		var.var_type = var_type_notfound;
		return;
	}
	var.var_type = var1.var_type;
	var.lvalue = 0;
	if (var1.const_sign)
	{
		var.const_sign = 0;
		var1.const_val = !var.const_val;
	}
	else
	{
		var.const_sign = 0;
	}
}

void CheckExprUnaryLogical(TSymbolListVariableEntry& var1, int op_type, TSymbolListVariableEntry& var)
{
	var.var_type = var_type_bool;
	var.const_sign = 0;
	var.lvalue = 0;
	if (var1.var_type == var_type_notfound) return;
	if (!__chk_logical_type(var1))
	{
		errormsg(8, PROGRAM_LineNumber, SRC_OP_name[op_type], __vartype2str(var1));
//		var.var_type = var_type_notfound;
		return;
	}
	var.var_type = var_type_bool;
	var.const_sign = 0;
	var.lvalue = 0;
}

void CheckPerformUnaryCalc(TSymbolListVariableEntry& var1, int op_type, TSymbolListVariableEntry& var)
{
	var.var_type = var_type_int;
	var.const_sign = 1;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -