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

📄 parse.cpp

📁 一个类c语言的解释器
💻 CPP
📖 第 1 页 / 共 4 页
字号:
	followset.push_back(_RBPAREN);
	followset.push_back(_INT);
	followset.push_back(_REAL);
	temp = compound_stmt(appendVector(synchset,followset));
	if (temp!=NULL)
	{
		t->addChild(temp);
	}
	//while循环的一个过程执行结束侯,无条件跳转到判断表达式处,判断是否该执行下一个循环
	code->push_back("JMP "+itos(address));
	codeAddress++;
	//回填while开始时候的跳转地址,如果while循环不执行,则跳转到此处
	code->at(backfill)="JPC "+itos(codeAddress);
	codeAddress++;
	check_input(appendVector(synchset,followset),firstset);
	return t;
}


/*
*<read_exp>::=read ID;
*firstset _READ
*followset _RBPAREN _INT _REAL _ID _IF _WHILE _READ _WRITE _RETURN
*/
TreeNode* read_exp(vector<_TokenType> synchset){
	TreeNode* t = new TreeNode;
	TreeNode* temp = new TreeNode;
	t->describe = "read_exp";
	vector<_TokenType> firstset;
	vector<_TokenType> followset;
	firstset.push_back(_READ);
	followset.push_back(_ID);
	followset.push_back(_IF);
	followset.push_back(_WHILE);
	followset.push_back(_READ);
	followset.push_back(_WRITE);
	followset.push_back(_RETURN);
	followset.push_back(_RBPAREN);
	followset.push_back(_INT);
	followset.push_back(_REAL);
	match(_READ,t);
	TokenRecord id = token;
	bool isArr = false;
	if(tokenList->at(index+1).tp==_LMPAREN)
		isArr = true;
	temp = var(appendVector(synchset,followset));
	if (temp!=NULL)
	{
		t->addChild(temp);
	}
	else{
		parse_err = true;
		errorList->push_back("miss the variable to store input at line "+itos(token.lineno));
		return NULL;
	}
	match(_SEMI,t);
	check_input(appendVector(synchset,followset),firstset);
	if(sym->find(id.tv)==NULL){
		parse_err = true;
		errorList->push_back("undeclared identifier "+token.tv+" at line "+itos(token.lineno));
		symbol->id = token.tv;
		sym->insert(symbol);
		symbol = new Symbol;
	}
	else{
		//弹出变量的值
		code->pop_back();
		codeAddress--;
		//获取保存输入ID的类型
		//输入的数据同样也会转换为该类型
		int type = sym->find(id.tv)->type;
		//输入一个和保存输入的变量类型相同的数保存再栈顶
		code->push_back("IN "+itos(type));
		codeAddress++;
		//保存数据栈顶的数字到要保存的变量中
		if(!isArr)
			code->push_back("STO "+sym->find(id.tv)->address);
		else{
			code->push_back("STO "+sym->find(id.tv)->address+"+[TOP]");
		}
		codeAddress++;
	}
	return t;
}

/*
*<write_exp>::=write <expression>;
*firstset _WRITE
*followset _RBPAREN _INT _REAL _ID _IF _WHILE _READ _WRITE _RETURN
*/
TreeNode* write_exp(vector<_TokenType> synchset){
	TreeNode* t = new TreeNode;
	TreeNode* temp = new TreeNode;
	t->describe = "write_exp";
	vector<_TokenType> firstset;
	vector<_TokenType> followset;
	firstset.push_back(_WRITE);
	followset.push_back(_ID);
	followset.push_back(_IF);
	followset.push_back(_WHILE);
	followset.push_back(_READ);
	followset.push_back(_WRITE);
	followset.push_back(_RETURN);
	followset.push_back(_RBPAREN);
	followset.push_back(_INT);
	followset.push_back(_REAL);
	match(_WRITE,t);
	synchset.push_back(_SEMI);
	temp = expression(appendVector(synchset,followset));
	data_type->pop_back();
	code->push_back("OUT");
	codeAddress++;
	if (temp!=NULL)
	{
		t->addChild(temp);
	}
	else{
		errorList->push_back("miss expression after 'write' at line " + itos(token.lineno));
	}
	match(_SEMI,t);
	check_input(appendVector(synchset,followset),firstset);
	return t;
}

/*
*<return_exp>::=return <expression>;
*firstset _RETURN
*followset _RBPAREN _INT _REAL _ID _IF _WHILE _READ _WRITE _RETURN
*/
TreeNode* return_exp(vector<_TokenType> synchset){
	TreeNode* t = new TreeNode;
	TreeNode* temp = new TreeNode;
	t->describe = "return_exp";
	vector<_TokenType> firstset;
	vector<_TokenType> followset;
	firstset.push_back(_RETURN);
	followset.push_back(_ID);
	followset.push_back(_IF);
	followset.push_back(_WHILE);
	followset.push_back(_READ);
	followset.push_back(_WRITE);
	followset.push_back(_RETURN);
	followset.push_back(_RBPAREN);
	followset.push_back(_INT);
	followset.push_back(_REAL);
	check_input(firstset,synchset);
	match(_RETURN,t);
	synchset.push_back(_SEMI);
	temp = expression(appendVector(synchset,followset));
	if (temp!=NULL)
	{
		t->addChild(temp);
	}
	else{
		errorList->push_back("miss expression after 'return' at line " + itos(token.lineno));
	}
	//判断返回类型是否和函数类型兼容,不兼容则报错
	if (fun->type<data_type->at(data_type->size()-1))
	{
		parse_err = true;
		errorList->push_back("return statement at line"+itos(token.lineno)+" conver 'real' to 'int'");
	}
	data_type->pop_back();
	match(_SEMI,t);
	//函数返回
	code->push_back("RET");
	codeAddress++;
	check_input(appendVector(synchset,followset),firstset);
	return t;
}
/*
*<local_var_declaration>::=(int|real)<var_list>
*firstset _INT _REAL
*followset _RBPAREN _INT _REAL _ID _IF _WHILE _READ _WRITE _RETURN
*/
TreeNode* local_var_declaration(vector<_TokenType> synchset){
	TreeNode* t = new TreeNode;
	TreeNode* temp = new TreeNode;
	t->describe = "local_var_declaration";
	vector<_TokenType> firstset;
	vector<_TokenType> followset;
	firstset.push_back(_INT);
	firstset.push_back(_REAL);
	followset.push_back(_ID);
	followset.push_back(_IF);
	followset.push_back(_WHILE);
	followset.push_back(_READ);
	followset.push_back(_WRITE);
	followset.push_back(_RETURN);
	followset.push_back(_RBPAREN);
	followset.push_back(_INT);
	followset.push_back(_REAL);
	//设置isLocal=true
	isLocal = true;
	check_input(firstset,synchset);
	//设置参数的类型
	if (token.tp==_INT||token.tp==_REAL)
	{
		if (token.tp==_INT)
		{
			match(_INT,t);
			symbol->type = 0;
		}
		else{
			match(_REAL,t);
			symbol->type=1;
		}
		temp = var_list(appendVector(synchset,followset));
		if (temp!=NULL)
		{
			t->addChild(temp);
		}
		else{
			errorList->push_back("miss varlist at line "+ itos(token.lineno));
		}
	}
	check_input(appendVector(synchset,followset),firstset);
	return t;
}

/*
*<var_list>::=(ID[=<expression>])|(ID[NUM][={<num_list>}])){,(ID[=<expression>])|(ID[NUM][={<num_list>}]))};
*firstset _ID
*followset
*/
TreeNode* var_list(vector<_TokenType> synchset){
	int ln = token.lineno;
	TreeNode* t = new TreeNode;
	TreeNode* temp = new TreeNode;
	t->describe = "var_list";
	vector<_TokenType> firstset;
	vector<_TokenType> followset;
	firstset.push_back(_ID);
	followset.push_back(_INT);
	followset.push_back(_REAL);
	int type = symbol->type;
	//当当前token为ID的时候,执行变量定义,这样可以同时定义多个变量
	while (token.tp==_ID&&ln == token.lineno)
	{
		printf_skip_err = true;
		if(check_input(firstset,synchset)==2){
			break;
		}
		printf_skip_err = false;
		synchset.push_back(_SEMI);
		//如果当前符号表里面包含ID,则是重复定义,报错
		if (sym->contain(token.tv))
		{
			parse_err = true;
			errorList->push_back("identifier '"+token.tv+"' at line "+itos(token.lineno)+" redefine");
		}
		match(_ID,t);
		//设置变量的id为上一个token的id
		symbol->id = tokenList->at(index-1).tv;
		//设置当前的符号的地址
		if(!isLocal)
			//如果是全局变量,设置地址为当前的全局变量地址
			symbol->address = itos(dataAddress);
		else{
			//如果是局部变量,设置地址为SP+当前局部变量地址
			symbol->address = "SP+"+itos(local_address);
		}
		//数组定义
		if (token.tp==_LMPAREN)
		{
			//设置符号的isarr=true
			symbol->isarr = true;
			match(_LMPAREN,t);
			match(_INUM,t);
			//读取当前的数组的大小
			currArraySize = atoi(tokenList->at(index-1).tv.c_str());
			if(!isLocal)
				//如果是全局变量,增加全局的变量的地址
				dataAddress+=atoi(tokenList->at(index-1).tv.c_str());
			else
				//如果是局部变量,增加局部变量的地址
				local_address+=atoi(tokenList->at(index-1).tv.c_str());
			//设置符号的size为数组的size
			symbol->size = atoi(tokenList->at(index-1).tv.c_str());
			//符号为int型
			if (type==0)
			{
				if(!isLocal){
					//全局变量,再全局数据区定义
					data->push_back("INT "+itos(symbol->size));
				}
				else{
					//局部变量,在代码区定义
					code->push_back("INT "+itos(symbol->size));
					codeAddress++;
				}
			}
			//符号为real型
			else{
				if(!isLocal){
					//全局变量,再全局数据区定义
					data->push_back("REAL "+itos(symbol->size));
				}
				else{
					//局部变量,在代码区定义
					code->push_back("REAL "+itos(symbol->size));
					codeAddress++;
				}
			}
			match(_RMPAREN,t);
			//当前输入符号为=,则在定义的时候赋值
			if (token.tp==_ASSIGN)
			{
				int temp_address;
				if (!isLocal)
				{
					temp_address = codeAddress;
				}
				match(_ASSIGN,t);
				match(_LBPAREN,t);
				//
				temp = num_list();
				if (temp!=NULL)
				{
					t->addChild(temp);
				}
				else{
					errorList->push_back("miss numlist after '[' at line "+ itos(token.lineno));
				}
				match(_RBPAREN,t);
				//数组大小-初始化的个数可以获取初始化的个数
				//
				if(!isLocal){
					for (int i=currArraySize-initNums+1;i<=currArraySize;i++)
					{
						code->push_back("STO "+itos(dataAddress-i));
						codeAddress++;
					}
				}
				else{
					for (int i=currArraySize-initNums+1;i<=currArraySize;i++)
					{
						code->push_back("STO SP+"+itos(local_address-i));
						codeAddress++;
					}
				}
				if (!isLocal)
				{
					for (int i = temp_address;i<codeAddress;i++)
					{
						global_init->push_back(code->at(i));
					}
					while (codeAddress!=temp_address)
					{
						code->pop_back();
						codeAddress--;
					}
				}
			}			
		}
		else{
			if (isLocal)
			{
				local_address++;
			}
			else{
				dataAddress++;
			}
			//数字定义,符号的大小为1
			symbol->size = 1;
			if (type==0)
			{
				if(!isLocal){
					//全局变量,再全局数据区定义
					data->push_back("INT "+itos(1));
				}
				else{
					//局部变量,在代码区定义
					code->push_back("INT "+itos(1));
					codeAddress++;
				}
			}
			//符号为real型
			else{
				if(!isLocal){
					//全局变量,再全局数据区定义
					data->push_back("REAL "+itos(1));
				}
				else{
					//局部变量,在代码区定义
					code->push_back("REAL "+itos(1));
					codeAddress++;
				}
			}
			//数字定义时同时赋值
			if (token.tp==_ASSIGN)
			{
				int temp_address;
				if (!isLocal)
				{
					temp_address = codeAddress;
				}
				match(_ASSIGN,t);
				temp = expression(appendVector(synchset,followset));
				//类型检查,判断类型栈顶的类型是否可以和定义的类型兼容
				if (type==0)
				{
					//不兼容,打印错误
					if (type!=data_type->at(data_type->size()-1))
					{
						parse_err = true;
						errorList->push_back("line "+itos(token.lineno)+", can,t cast right-hand expression  from 'real' to 'int'");
					}
				}
				//弹出符号栈的栈顶符号
				data_type->pop_back();
				code->push_back("STO "+symbol->address);
				codeAddress++;
				if (temp!=NULL)
				{
					t->addChild(temp);
				}
				//把数字栈顶的符号保存到变量中

				else{
					parse_err = true;
					errorList->push_back("miss expression after '=' at line " + itos(token.lineno));
				}
				if (!isLocal)
				{
					for (int i = temp_address;i<codeAddress;i++)
					{
						global_init->push_back(code->at(i));
					}
					while (codeAddress!=temp_address)
					{
						code->pop_back();
						codeAddress--;
					}
				}
			}
		}
		//如果遇到';',变量定义结束
		if (token.tp==_SEMI)
		{
			match(_SEMI,t);
			//如果当前符号表中有当前符号同id的符号,重复定义,打印错误
			if (sym->contain(symbol->id))
			{
				/*parse_err = true;
				errorList->push_back("identifier '"+symbol->id+"' at line "+itos(token.lineno));*/
			}
			//如果当前符号表中没有当前符号同id的符号,插入当前符号到符号表,并初始化当前符号,以便处理下一个符号
			else{
				sym->insert(symbol);
				symbol = new Symbol;
			}

			break;
		}
		//如果遇到','接着定义下一个符号
		if (token.tp==_COMMA)
		{
			match(_COMMA,t);
			//如果当前符号表中有当前符号同id的符号,重复定义,打印错误
			if (sym->contain(symbol->id))
			{
				/*parse_err = true;
				errorList->push_back("identifier '"+symbol->id+"' at line "+itos(token.lineno));*/
			}
			else{
				//如果当前符号表中没有当前符号同id的符号,插入当前符号到符号表,并初始化当前符号,以便处理下一个符号
				//并初始化新的当前符号的类型和老的相同
				sym->insert(symbol);
				int t = symbol->type;
				symbol = new Symbol;
				symbol->type = t;
			}		
			continue;
		}

	}
	if ((tokenList->at(index-1)).tp!=_SEMI)
	{
		errorList->push_back("miss ';' at line "+ itos(token.lineno-1));
		parse_err = true;
	}
	printf_skip_err=true;
	check_input(appendVector(synchset,followset),firstset);
	printf_skip_err = false;
	return t;
}


/*
*<expression>::=<additive_expression>[(>|<|==|<>)<additive_expression>]
*firstset _ID _LSPAREN _MINUS _PLUS _NUM
*followset _PLUS _MINUS
*/
TreeNode* expression(vector<_TokenType> synchset){
	TreeNode* t = new TreeNode;
	TreeNode* temp = new TreeNode;
	t->describe = "expression";
	vector<_TokenType> firstset;
	vector<_TokenType> followset;
	firstset.push_back(_LSPAREN);
	firstset.push_back(_MINUS);
	firstset.push_back(_PLUS);
	firstset.push_back(_ID);
	firstset.push_back(_RNUM);
	firstset.push_back(_INUM);
	if (check_input(firstset,synchset)==2)
	{
		return NULL;
	}
	else{
		temp = additive_expression(appendVector(synchset,followset));
		if (temp!=NULL)
		{
			t->addChild(temp);
		}
		_TokenType tp = token.tp;
		if(token.tp==_LT||token.tp==_BT||token.tp==_NE||token.tp==_EQ)
		{
			string tv = token.tv;
			match(token.tp,t);
			temp = additive_expression(appendVector(synchset,followset));
			if (temp!=NULL)
			{
				t->addChild(temp);
			}
			else{
				parse_err = true;
				errorList->push_back("unexcept token '"+tv+"' at line "+ itos(token.lineno));
			}
			int i = 0;
			//判断操作的类型
			switch(tp)
			{
			case _LT:
				i = 4;
				break;
			case _BT:
				i = 5;
				break;
			case _EQ:
				i = 6;
				break;
			case _NE:
				i = 7;
				break;
			}
			code->push_back("OPR "+itos(i));
			codeAddress++;
			//弹出2个操作数的类型
			data_type->pop_back();
			data_type->pop_back();
			//bool运算的结果的类型为int
			data_type->push_back(0);
		}
		//if(check_input(followset,firstset)!=0){
		//	errorList->push_back("unexcept token before '"+token.tv+"' at line "+itos(token.lineno));
		//}
	}
	//如果只有一个子节点,子节点上移,为了减少输出树的深度
	if (t->children->size()==1)
	{
		t = t->children->at(0);

⌨️ 快捷键说明

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