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

📄 yufa.cpp

📁 自定义简单语法类C语言编译器
💻 CPP
📖 第 1 页 / 共 4 页
字号:
#include<stdio.h>
#include<string>
#include<fstream>
#include<iostream>
using namespace std;
#define null 0
char ch;
char strToken[10];
char read[50];
int i=0,j=0,m=0,n=0;
char *p[120];
int q[100];
int wordnum=0;//词法分析中单词串计数
int yf_wordnum=0;//语法分析中单词串计数
int filelinenum=0;//chengxu.txt行号计数
int toktype;//词法分析中用到的char* type[]下标计数
int yufaright=1;//语法分析是否正确,初始化为1
int treeheight=0;//
int tempwordnum;//printerror()里面未避免重复输出使用
int gloablevarnum;
int paranum=0;
int varnum=0;
int isroot=1;//是否为全局变量或函数
int funnum=0;//生成符号表时所用(函数个数计数)
char curfunname[10];//	为避免递归产生错误的判断
int needreturn=0;
int curcodenum=0;//正生成的代码计数
int curfunnum=0;//正在进行目标代码生成的函数计数
int returnfinish=0;


ofstream cfoutfile("chengxu.xml");
ofstream yfoutfile("chengxu_syntaxTree.xml");
ofstream sym_table("chengxu_symtable.xml");
ofstream codelist("chengxu_asm.xml");
enum TokenType
{
	//关键字		
	IF,ELSE,WHILE,RETURN,VOID,INT, EXP,THROW,CATCH,TRY,VIRTUAL,THIS,DELETE,NEW,PROTECTED,PRIVATE,PUBLIC,CLASS,
	//运算符 + - * /  =  <  <=  >  >=  !=  … //界符 ;  ,  (  )  [  ]  {  }  /*  */
	PLUS,MINUS,STAR,SLASH,LT,LTEQ,GT,GTEQ,EQ,NEQ,ASSIGN,SEMI,COMMA,COLON,DOT,
    WAVE,LPAREN,RPAREN,LSQUAR,RSQUAR,LBRACE,RBRACE,LCOMMENT,RCOMMENT,
	ID,				//标识符
	NUMBER, 			//数字常量
	NONTOKEN,ERROR,ENDFILE	// 其它
};

//变量是全局变量还是局部变量还是参数变量
/*enum VarType
{
	LOCALVAR,PARAVAR,GLOBALVAR
};*/

char* type[]={
	//关键字
	"IF","ELSE","WHILE","RETURN","VOID","INT","EXP","THROW","CATCH","TRY","VIRTUAL","THIS",
		"DELETE","NEW","PROTECTED","PRIVATE","PUBLIC","CLASS",
	//运算符
	"PLUS","MINUS","STAR","SLASH", "LT","LTEQ","GT","GTEQ","EQ","NEQ","ASSIGN",
	//界符 ;  ,  (  )  [  ]  {  }  /*  */
	"SEMI","COMMA","COLON","DOT",
	"WAVE","LPAREN","RPAREN","LSQUAR","RSQUAR","LBRACE","RBRACE",
	"LCOMMENT","RCOMMENT",
	"ID", 				//标识符
	"NUMBER", 			//数字常量
	"NONTOKEN","ERROR","ENDFILE"// 其它
};

//语法树节点类型
enum NodeType 
	{
		FunDecl,VarDecl,Para,	
		ADD, SUB, MUL, DIV, REQ, RLT, RGT, RNEQ, RNGT, RNLT,
		AssignStm,IfStm,IfElseStm,ElseStm,WhileStm,ReturnStm,
		FunCall, ConstID, VarID,OTHER
	};

char * nodetype[]={"FunDecl","VarDecl","Para",	
"ADD", "SUB", "MUL", "DIV", "REQ", "RLT", "RGT", "RNEQ", "RNGT", "RNLT",
"AssignStm","IfStm","IfElseStm","ElseStm","WhileStm","ReturnStm",
		"FunCall", "ConstID", "VarID","OTHER"
};


//节点结构
typedef struct TreeNode
	{
		int lineno;	//行号
		struct	TreeNode *child[3];//子节点
		struct	TreeNode *sibling;//兄弟节点
		NodeType ntype;//节点类型
		char nodestr[10];	//保存标识符的名称,便于在语法树中显示
		char vartype[10];	//用于标明变量类型int char float
		char rettype[10]; //函数返回类型void int char float
		bool isarray;
}TreeNode,* NodeList;  //语法树结点结构定义及数组定义

//建立抽象语法树结点

struct Token
	{
		string str;			//单词字符串 
		TokenType ttype;	//单词的类型
		int line;		//所在行号信息
	} tok[200];


struct keyword
	{
	int code;
	char keyname[10];
	};
 
struct keyword key[18]=
	{
		{1,"int"},	{2,"void"},{3,"if"},{4,"else"},{5,"while"},{6,"return"},{7,"exp"},{8,"throw"},{9,"catch"},{10,"try"},
		{11,"virtual"},	{12,"this"},{13,"delete"},{14,"new"},{15,"protected"},{16,"private"},{17,"public"},	{18,"class"}
	};

//变量结构体
struct VarTable
{
    char varname[10];
	char vartype[10];
	int isarray;
	int arraysize;
	int Rva;
}gloablevarlist[20];




//函数结构体
struct FunTable 
{
	char funname[10];
	int FunId;
	char rettype[10];
	int entryAddr;
	int paraVarSize;
	char varName[10];
	int localVarSize;
	int	tryblockCount;
	int unwindCount;
	VarTable  pvartable[10];
	VarTable pparavartable[10];
	int size;
}funlist[20];

struct Code
{
	string label;//标号
	string op;//操作码
	string arg1;//操作数1
	string arg2;//操作数2
}gencode[100];



//函数声明
NodeList CreateTreeNode();
void GetChar();
void GetBC();
void Concat();
int InsertConst();
int InsertId();
int IsLetter();
int IsDigit();
int Reserve();
void Retract();
int scan();
int cifa();
NodeList CreateTreeNode();
void printerror();
int  match();
NodeList fun_decla();
NodeList var_decla();
NodeList params();
NodeList param_list();
NodeList param();
NodeList compound_stmt();
NodeList local_decla();
NodeList statement_list();
NodeList statement();
NodeList  return_stmt();
NodeList  if_stmt();
NodeList  while_stmt();
NodeList  exp_stmt();
NodeList  exp();
NodeList  var();
NodeList  simple_expression();
NodeList  relop();
NodeList  additive_expression();
NodeList term();
NodeList factor();
NodeList call();
NodeList  args();
NodeList  program();
void printtree(NodeList node);
void ScanTree(NodeList root);
int insertgloablevar(NodeList root);
int	insertvar(NodeList root);
int insertfun(NodeList root);
int searchvar(NodeList root,int funnum);
int searchfun(NodeList root);
void printsymtable();
void stmtprocess(NodeList root);
//void ScanTreelast(NodeList root);
void ifstmt(NodeList root);
void ifelsestmt(NodeList root);
void whilestmt(NodeList root);
void assignstmt(NodeList root);
void funcallstmt(NodeList root);
void fundeclstmt(NodeList root);
void returnstmt(NodeList root);
void expressionstmt(NodeList root);
string varprocess(int varlocate);
void initcodelist();
void codegen(NodeList root);
int geningsearchfun(NodeList root);
int	searchmain();

//词法分析函数定义
void GetChar()
	{
	ch=read[i];
	i++;
	}

void GetBC()
	{
	while(ch==' '||ch=='	')
		GetChar();
	}

void Concat()
	{
	strToken[j++]=ch;
	}

int IsLetter()
	{
	if((ch>='A'&&ch<='Z')||(ch>='a'&&ch<='z'))
		return 1;
	else return 0;
	}

int IsDigit()
	{
    if(ch>='0'&&ch<='9')
		return 1;
	else return 0;
	}

int Reserve()
	{		
	int k=0,m,code1,len;
	for(m=0;m<18;m++)
		{
		len=strlen(key[m].keyname);
			if(j==len)
			{
		       while(strToken[k]==key[m].keyname[k]&&k<j)
				   k++;
			}	
			if(k==j)
			{code1=key[m].code;
			return code1;
			}
		}
		return 0;
	}


void Retract()
	{
	i--;
	ch=null;
	}

int InsertId()
	{
	p[m++]=strToken;
	return m;
	}

int InsertConst()
	{
	int temp,sum=0,digit;
	for(temp=0;temp<j;temp++)
		{
			digit=strToken[temp]-'0';
			sum=sum*10+digit;
		}

	q[n++]=sum;
	return n-1;
	}
int scan()
{
	int t;
	int code,value;
	j=0;
	GetChar();
 	GetBC();
	if(IsLetter())
		{while(IsLetter()||IsDigit())
			{
				 Concat();
		 		 GetChar();
			}
	   		Retract();
			code=Reserve();
			switch (code)
			{
				case 0:
					value=InsertId();
					tok[wordnum].ttype=ID;
					tok[wordnum].str=strToken;
					tok[wordnum].line=filelinenum;
					cout<<"$ID"<<' '<<value;
					break;
				case 1:
					tok[wordnum].ttype=INT;
					tok[wordnum].str=strToken;
					tok[wordnum].line=filelinenum;
					cout<<code<<' '<<"keyword";
					break;
				case 2:
					tok[wordnum].ttype=VOID;
					tok[wordnum].str=strToken;
					tok[wordnum].line=filelinenum;
					cout<<code<<' '<<"keyword";
					break;
				case 3:
					tok[wordnum].ttype=IF;
					tok[wordnum].str=strToken;
					tok[wordnum].line=filelinenum;
					cout<<code<<' '<<"keyword";
					break;
				case 4:
					tok[wordnum].ttype=ELSE;
					tok[wordnum].str=strToken;
					tok[wordnum].line=filelinenum;
					cout<<code<<' '<<"keyword";
					break;
				case 5:
					tok[wordnum].ttype=WHILE;
					tok[wordnum].str=strToken;
					tok[wordnum].line=filelinenum;
					cout<<code<<' '<<"keyword";
					break;
				case 6:
					tok[wordnum].ttype=RETURN;
					tok[wordnum].str=strToken;
					tok[wordnum].line=filelinenum;    
					cout<<code<<' '<<"keyword";
					break;
				case 7:
					tok[wordnum].ttype=EXP;
					tok[wordnum].str=strToken;
					tok[wordnum].line=filelinenum;
					cout<<code<<' '<<"keyword";
					break;
				case 8:
					tok[wordnum].ttype=THROW;
					tok[wordnum].str=strToken;
					tok[wordnum].line=filelinenum;
					cout<<code<<' '<<"keyword";
					break;
				case 9:
					tok[wordnum].ttype=CATCH;
					tok[wordnum].str=strToken;
					tok[wordnum].line=filelinenum;
					cout<<code<<' '<<"keyword";
					break;
				case 10:
					tok[wordnum].ttype=TRY;
					tok[wordnum].str=strToken;
					tok[wordnum].line=filelinenum;
					cout<<code<<' '<<"keyword";
					break;
				case 11:
					tok[wordnum].ttype=VIRTUAL;
					tok[wordnum].str=strToken;
					tok[wordnum].line=filelinenum;
					cout<<code<<' '<<"keyword";
					break;
				case 12:
					tok[wordnum].ttype=THIS;
					tok[wordnum].str=strToken;
					tok[wordnum].line=filelinenum;
					cout<<code<<' '<<"keyword";
					break;
				case 13:
					tok[wordnum].ttype=DELETE;
					tok[wordnum].str=strToken;
					tok[wordnum].line=filelinenum;
					cout<<code<<' '<<"keyword";
					break;
					case 14:
					tok[wordnum].ttype=NEW;
					tok[wordnum].str=strToken;
					tok[wordnum].line=filelinenum;
					cout<<code<<' '<<"keyword";
					break;
				case 15:
					tok[wordnum].ttype=PROTECTED;
					tok[wordnum].str=strToken;
					tok[wordnum].line=filelinenum;
					cout<<code<<' '<<"keyword";
					break;
				case 16:
					tok[wordnum].ttype=PRIVATE;
					tok[wordnum].str=strToken;
					tok[wordnum].line=filelinenum;
					cout<<code<<' '<<"keyword";
					break;
				case 17:
					tok[wordnum].ttype=PUBLIC;
					tok[wordnum].str=strToken;
					tok[wordnum].line=filelinenum;
					cout<<code<<' '<<"keyword";
					break;
				case 18:
					tok[wordnum].ttype=CLASS;
					tok[wordnum].str=strToken;
					tok[wordnum].line=filelinenum;
					cout<<code<<' '<<"keyword";
					break;
			}
		}
		else if(IsDigit())
			{
			while(IsDigit())
				{Concat();
		 	    GetChar();
				}
				Retract();
			//	value=InsertConst();
				tok[wordnum].ttype=NUMBER;
				tok[wordnum].str=strToken;
				tok[wordnum].line=filelinenum;
				cout<<"$INT"<<' '<<strToken;
			}
		else if(ch=='+') 
		{
			tok[wordnum].ttype=PLUS;
			tok[wordnum].str="+";
			tok[wordnum].line=filelinenum;
			cout<<"$PLUS";
		}
		else if(ch=='-') 
		{
			tok[wordnum].ttype=MINUS;
			tok[wordnum].str="-";
			tok[wordnum].line=filelinenum;
			cout<<"$MINUS";
		}
		else if(ch=='.')
		{
			tok[wordnum].ttype=DOT;
			tok[wordnum].str=".";
			tok[wordnum].line=filelinenum;
			cout<<"$DOT";
		}
		else if(ch==':')
		{
			tok[wordnum].ttype=COLON;
			tok[wordnum].str=":";
			tok[wordnum].line=filelinenum;
			cout<<"$COLON";
		}
		else if(ch=='*')
			{GetChar();
				if(ch=='/')
				{
					tok[wordnum].ttype=RCOMMENT;
					tok[wordnum].str="*/";
					tok[wordnum].line=filelinenum;
					cout<<"$RCOMMENT";
				}
				else	
				{
					Retract();
					tok[wordnum].ttype=STAR;
					tok[wordnum].str="*";
					tok[wordnum].line=filelinenum;
					cout<<"$STAR";
				}
		}
		else if(ch=='/')
				{GetChar();
				if(ch=='*')
				{
					tok[wordnum].ttype=LCOMMENT;
					tok[wordnum].str="/*";
					tok[wordnum].line=filelinenum;
					cout<<"$LCOMMENT";

				}
				else	
				{
					Retract();
					tok[wordnum].ttype=SLASH;
					tok[wordnum].str="/";
					tok[wordnum].line=filelinenum;
					cout<<"$SLASH";
				}
		}
		else if(ch=='=')
				{GetChar();
				if(ch=='=')
				{
					tok[wordnum].ttype=EQ;
					tok[wordnum].str="==";
					tok[wordnum].line=filelinenum;
					cout<<"$EQ";
				}
				else	
				{Retract();
				tok[wordnum].ttype=ASSIGN;
				tok[wordnum].str="=";
				tok[wordnum].line=filelinenum;
				cout<<"$ASSIGN";
				}
				
				}
		else if(ch=='>')
				{GetChar();
				if(ch=='=')
				{
					tok[wordnum].ttype=GTEQ;
					tok[wordnum].str=">=";
					tok[wordnum].line=filelinenum;
					cout<<"$GTEQ";

⌨️ 快捷键说明

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