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

📄 c2asm.cpp

📁 将C语言转换成汇编语言
💻 CPP
📖 第 1 页 / 共 5 页
字号:
		
		//Lexeme is an ERROR CHARACTIER
	case 100:
			//Enter into TOKEN's TABLE!
			tok.clas="error";
			tok.index=-10;
			tokens.push_back(tok);
			break;
	}//End Switch
}

///**********************///
///**********************///
///						 ///
/// SYNTAX BOX STARTED.	 ///
///						 ///
///**********************///
///**********************///

//////////////////////
//
//Syntax Box's Globals
//
//////////////////////

to input;	//Used To read in Token Generated by LEXICAL BOX

//Structure Of Identifier Table,For Details Of FIELDs CONSULT the DOCUMETATION of C2ASM,
//Provided with it.

struct id{
	string name;
	int datatype;
	int scope;
	int binding;
	bool func_or_not;
	int type;
	int offset;
	int xtra;
}ident;

//This Vector will hold Main()/Fucntion/Temporary Variables and Function Names Also.
vector<id> syn_identifier;	

//This Vector will hold Fucntion's Parameters
vector<id> args_identifier;

int syn_index=0;	//Counter to Iterate through TOKEN's Vector

ofstream error("parser_log.txt");	//Parser Log File

int scopecount=-10;
stack <int> scopestack;		// Stack For Scope Handling

int func_index=-10;
bool main_func=false;
bool isreturn=false;

//Used in Making ATOMS or INTERMEDIATE CODE
struct expr{
	int index;
	int datatype;
	int whichtable;
}dump;

int table=-10;		// 0 for syn_identifier
					// 1 for args_identifier

//Each ATOM has following structure.
struct atom{
	string op;
	int type;
	expr arg1;
	expr arg2;
	expr result;
}atm;

vector<atom> atoms;	//This Vector will hold All ATOMS or INTERMEDIATE CODE generated

vector<string> labels;	//This Vector will Hold all LABELS generated

long init_arg=-10,fin_arg=-10;

/////////////////////////////////////
//
//Syntax Box's Fucntions Declaration
//
/////////////////////////////////////

//Helper Functions

///////////////////////////////
//
// Recursive Descend Functions
//
///////////////////////////////

//Used to Advance Like u see in Recursive Descend Method's Discussed in Compiler Books
void advanc();

//Used to Reject Like u see in Recursive Descend Method's Discussed in Compiler Books
void reject();

///////////////////////////////
//
// Type System's Functions
//
///////////////////////////////

//Used to Set the Datatype of Main()/Function's/Temporary Variables/Function's Return Type
void settype(int index,int type);

//Used to Set the Datatype of Function's Parameters
void settype_args(int index,int type);

//Generates New Temporary Variables
expr newtemp(int type);

//Generates New Temporary Variables Names Used by "newtemp"
string newtempname(void);

//Check whether an Identifier is DECLARED before it's used
long chk_ident(long index);

//Check whether Two Identifiers or Numbers are of same Type
bool chk_types(expr v1,expr v2);

//Makes ATOM of a Particular Type on the basis of it's Arguments
void setatom(int op,expr arg1,expr arg2,expr result);

//Generates New Labels
int newlabel(void);

//Check whether a Function is DECLARED before it's used
long chk_func(long index);

//Gived Arguments Info. of a Particular Function
void args_info(long index,long &init_arg,long &fin_arg);

//Calculates Paramters Offset,When they're on STACK
int calc_param_offset();

//Calculates Locals Offset,When they're on STACK
int calc_local_offset();

////////////////////
//
//Grammar Functions
//
////////////////////

//Read the Supplied Document For a Better Understanding

void program();
void data_or_function(int type);
void function_or_main();
void function_body();
void variable_declarations();
void variable_list(int type);
void argument_list();
void argument();
void compound_statement();
void statements();
void statement();
void optional_else();
void right_hand_side(expr &r);
void function_call(expr &f);
void optional_expression_list();
void expression_listf();
void expression_list_element();
void expression(expr &k);
void relational(expr &k,expr &t1);
void arithmetic(expr &p);
void subtract(expr p,expr &q);
void t(expr &p);
void add(expr p,expr &q);
void u(expr &p);
void multiply(expr p,expr &q);
void v(expr &p);
void divide(expr p,expr &q);
void w(expr &p);
void mod(expr p,expr &q);
void x(expr &p);


void advanc()
{	
	//Updating "parser_log.txt" File.
	error<<syn_index+1<<'\t'<<input.clas<<'\t'<<input.index<<'\t'<<scopestack.top()<<endl;

	//Picking Up Next Token
	if(syn_index!=(tokens.size()-1))
	{
	syn_index++;
	input=tokens[syn_index];
	}
}

void reject()
{
	//Updating "parser_log.txt" File.
	error<<syn_index+1<<'\t'<<input.clas<<'\t'<<input.index<<'\t'<<scopestack.top()<<endl;
	error.close();

    cout<<"\nParser Failed";
	cout<<"\nParser has parsed "<< syn_index+1 <<" Tokens\n";
	cout<<"See \"parser_log.txt\" For Details\n";
	getch();
	exit(-1);
}

void settype(int index,int type)
{
string name=lex_identifier[index];

for(unsigned int j=0;j<syn_identifier.size();j++)
{
	if(syn_identifier[j].name==name
		&& syn_identifier[j].scope==scopestack.top())
			{
				cout<<"Variable name->"<< name<<" with scope "<< scopestack.top()<<" and datatype "<< type <<endl
					<<"Already exists With name->"<< syn_identifier[j].name<<" ,scope "<<syn_identifier[j].scope <<" and datatype "<< syn_identifier[j].datatype<<endl;
				reject();			
			}
}
//Chk for the name clashing of FORMAL PARAMETERS and LOCAL VARIABLES.
if(func_index!=-10)
{
	for(unsigned int j=0;j<args_identifier.size();j++)
	{
	if(args_identifier[j].name==name
		&& args_identifier[j].binding==func_index)
			{
			cout<<endl<<"Redifinition of formal parameter "<< name
				<<" in "<<syn_identifier[func_index].name;
			reject();			
			}
	}
}

ident.name=name;
ident.datatype=type;
ident.scope=scopestack.top();
ident.func_or_not=false;
ident.xtra=-10;

//It's a Global Variable
if(func_index==-10 && main_func==false)
{
ident.binding=-2;	//-2 for a global
ident.type=0;		//0 for a global
ident.offset=-10;	//No Need To calculate this
}
//It's a Main Variable
else if(func_index==-10 && main_func==true)
{
ident.binding=-1;	//-1 for a main
ident.type=1;		//1 for main
ident.offset=-10;	//No Need To calculate this
}
//It's a Local Variable
else if(func_index!=-10 && main_func==false)
{
ident.binding=func_index;	
ident.type=2;		//2 for Local
ident.offset=-10;	//WE'LL CALCULATE THIS AFTER SOMETIME!!!!
}

syn_identifier.push_back(ident);
}

//For Arguments
void settype_args(int index,int type)
{
string name=lex_identifier[index];
int binding=syn_identifier.size()-1;

for(unsigned int j=0;j<args_identifier.size();j++)
{
	if(args_identifier[j].name==name
		&& args_identifier[j].binding==binding)
			{
				cout<<"Variable name->"<< name<<" with binding "<< binding <<" and datatype "<< type <<endl
					<<"Already exists With name->"<< args_identifier[j].name<<" ,binding "
					<<args_identifier[j].binding<<" and datatype "<< args_identifier[j].datatype<<endl;
				reject();			
			}
}
//Updating ARGUMENTS SYMBOL TABLE
ident.name=name;
ident.datatype=type;
ident.scope=-10;
ident.binding=binding;
ident.func_or_not=false;
ident.type=3;
ident.offset=-10;	//We'll Calculate this LATER on.
ident.xtra=-10;
args_identifier.push_back(ident);

}

expr newtemp(int type)
{
	if(type==23) type=0;
	if(type==24) type=1;

	expr temp;

	ident.name=newtempname();
	ident.datatype=type;
	ident.scope=scopestack.top();
	ident.func_or_not=false;
	ident.type=4;	//For Temporaries
	ident.offset=-10;	//Will CALCULATE afterwards
	ident.xtra=-10;
	
	//Deciding Whose Temporary is this! Main or an Ordinary Function
	if(main_func==true)
		ident.binding=-1;
	else
		ident.binding=func_index;

	syn_identifier.push_back(ident);
	 
	temp.index=syn_identifier.size()-1;
	temp.datatype=type;
	temp.whichtable=0;
	
	return temp;
}

string newtempname(void)
{
	static long count=1;
	
	char name[10];
	char temp[5];

	ltoa(count,temp,10);
	strcpy(name,"t");
	strcat(name,temp);
	
	count++;
	return string(name);
	
}

long chk_ident(long index)
{
table=-10;
string name=lex_identifier[index];
unsigned int j=0;

//Check in Local Scope
for(j=0;j<syn_identifier.size();j++)
{
	if(syn_identifier[j].name==name
		&& syn_identifier[j].scope==scopestack.top()
		&& syn_identifier[j].func_or_not==false)
			{
			table=0;	//For syn_identifier
			return j;
			}
}

//Check in if it's a Formal Parameter
if(func_index!=10)
{
for(j=0;j<args_identifier.size();j++)
{
	if(args_identifier[j].name==name
		&& args_identifier[j].binding==func_index)
			{
			table=1;	//For args_identifier
			return j;
			}
}

}

//Check in Global Scope
for(j=0;j<syn_identifier.size();j++)
{
	if(syn_identifier[j].name==name
		&& syn_identifier[j].scope==0
		&& syn_identifier[j].func_or_not==false)
			{
			table=0;	//For syn_identifier
			return j;
			}
}

return -10;
}

bool chk_types(expr v1,expr v2)
{
	v1.datatype=v1.datatype==23 ? 0 : v1.datatype;
	v1.datatype=v1.datatype==24 ? 1 : v1.datatype;

	v2.datatype=v2.datatype==23 ? 0 : v2.datatype;
	v2.datatype=v2.datatype==24 ? 1 : v2.datatype;

	return(v1.datatype==v2.datatype);
}

void setatom(int op,expr arg1,expr arg2,expr result)
{
	atm.type=op;
	atm.arg1=arg1;
	atm.arg2=arg2;
	atm.result=result;

	switch(op)
	{
	//Addition
	case 15:
		atm.op="ADD";
		break;

		//Subtraction
	case 16:
		atm.op="SUB";
		break;

		//Multiply
	case 17:
		atm.op="MUL";
		break;

		//Division
	case 18:
		atm.op="DIV";
		break;

		//Remainder
	case 19:
		atm.op="MOD";
		break;
		
		//Assign
	case 26:
		atm.op="ASSIGN";
		break;

		//Label
	case 25:
		atm.op="LABEL";
		break;

		//Conditional Jump
	case 27:
		atm.op="CONDJUMP";
		break;

		//Jump
	case 28:
		atm.op="JUMP";
		break;

		//Return
	case 29:
		atm.op="RETURN";
		break;

		//Param
	case 30:
		atm.op="PARAM";
		break;

			//CALL
	case 31:
		atm.op="CALL";
		break;
		
			//PROC_MARKER
	case 34:
		atm.op="PROC_MARKER";
		break;

			//JUMPF
	case 8:
	case 9:
	case 10:
	case 11:
	case 12:
	case 13:
		atm.op="JUMPF";
		break;

		//CMP
	case 108:
	case 109:
	case 110:
	case 111:
	case 112:
	case 113:
		atm.op="CMP";
		//atm.type=op-100;
		break;
	default:
		cout<<"\nNo Matching Found";
	}
	atoms.push_back(atm);
}

int newlabel(void)
{
	static long count=1;
	
	char name[10];
	char temp[5];

	ltoa(count,temp,10);
	strcpy(name,"L");
	strcat(name,temp);
	
	string s1=name;
	labels.push_back(s1);

	count++;
	return(labels.size()-1);
}

long chk_func(long index)
{
string name=lex_identifier[index];

for(unsigned int j=0;j<syn_identifier.size();j++)
{
	if(syn_identifier[j].name==name
		&& syn_identifier[j].func_or_not==true)
			{
			table=0;
			return j;
			}
}
return -10;
}

void args_info(long index,long &init_arg,long &fin_arg)
{
init_arg=-10;
fin_arg=-10;
vector<int> temp;
	for(unsigned int j=0;j<args_identifier.size();j++)
		if(args_identifier[j].binding==index)
			temp.push_back(j);
	if(temp.size()!=0)
	{
	init_arg=temp[0];
	fin_arg=temp[temp.size()-1];
	}
}

int calc_param_offset()
{
	int index=func_index;	//Get FUNCTION's INDEX
	bool flag=false;
	int counter=0;
	int k=args_identifier.size()-1;
	int tot_len=0;
	while(index==func_index)
	{
		//If It's the LAST parameter
		if(flag==false){
			counter=6;
			args_identifier[k].offset=counter;
			counter+=args_identifier[k].datatype==0 ? 2 : 4;
			tot_len+=args_identifier[k].datatype==0 ? 2 : 4;
			flag=true;
		}
		//If It's OTHER THAN last parameter
		else{
			args_identifier[k].offset=counter;
			counter+=args_identifier[k].datatype==0 ? 2 : 4;
			tot_len+=args_identifier[k].datatype==0 ? 2 : 4;
		}
		k--;

⌨️ 快捷键说明

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