📄 c2asm.cpp
字号:
//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 + -