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

📄 parse.cpp

📁 一个类c语言的解释器
💻 CPP
📖 第 1 页 / 共 4 页
字号:
/*******************************************************
parse.cpp
武汉大学国际软件学院软件工程05级7班
崔灿
200532580235
2007-11-10
********************************************************/
#include "parse.h"
#include "globals.h"
#include "scan.h"
#include "SymTable.h"
#include <vector>
#include <stack>
#include <iostream>
using namespace std;

//当前分析的token在tokenList中的位置
int index=0;
//当前分析的token
static TokenRecord token;
static bool printf_skip_err;
//当前声明的符号,不是在声明部分则无意义
static Symbol *symbol;
//当前声明的函数,不是在声明部分则无意义
static Function *fun;
//记录生成的中间代码
vector<string>* code;
//记录全局数据定义的代码
vector<string>* data;
vector<string>* global_init;
//中间代码的地址
static int codeAddress = 0;
//全局数据的地址
static int dataAddress = 0;
//局部数据的地址
static int local_address = 2;
static stack<string> workStack;
static int type = 0;//当前符号或者表达式类型,int为0,real为1
//记录当前操作的变量是否为局部变量
static bool isLocal;
//记录当前的term是否为负
static bool negative;

//符号表
static SymTable *sym;
//函数表
static FunTable * funs;

//数组初始化时候使用
static int currArraySize;
//数组的大小
static int initNums;

//类型检查时使用
static vector<int>* data_type;
/*
*跳过一些符号,直到遇到firstse 和followset里面的符号或者ENDFILE
*/
static int skip_until(vector<_TokenType> firstSet,vector<_TokenType> followSet);
/*
*检查输入符号是否再开始集合里面,如果不在,就跳转
*/
static int check_input(vector<_TokenType> firstset,vector<_TokenType> followSet);
static void syntax_error(char* format,...);
TreeNode* declaration_list();
TreeNode* dedeclaration(vector<_TokenType> synchset);
TreeNode* var_declaration(vector<_TokenType> synchset);
TreeNode* fun_declaration(vector<_TokenType> synchset);
TreeNode* params(vector<_TokenType> synchset);
TreeNode* compound_stmt(vector<_TokenType> synchset);
TreeNode* statement_list(vector<_TokenType> synchset);
TreeNode* statement(vector<_TokenType> synchset);
TreeNode* var(vector<_TokenType> synchset);
TreeNode* assign_exp(vector<_TokenType> synchset);
TreeNode* selection_exp(vector<_TokenType> synchset);
TreeNode* iteration_exp(vector<_TokenType> synchset);
TreeNode* read_exp(vector<_TokenType> synchset);
TreeNode* write_exp(vector<_TokenType> synchset);
TreeNode* local_var_declaration(vector<_TokenType> synchset);
TreeNode* var_list(vector<_TokenType> synchset);
TreeNode* expression(vector<_TokenType> synchset);
TreeNode* additive_expression(vector<_TokenType> synchset);
TreeNode* term(vector<_TokenType> synchset);
TreeNode* factor(vector<_TokenType> synchset);
TreeNode* call(vector<_TokenType> synchset);
TreeNode* args(vector<_TokenType> synchset);
/*
*创建一个新节点,并把他插入到合适的地方
*/
static void newNode(_TokenType expected,TreeNode* t);
TreeNode *num_list();
TreeNode *return_exp(vector<_TokenType> synchset);

//合并2个向量
static vector<_TokenType> appendVector(vector<_TokenType>v1,vector<_TokenType>v2){
	for (int i=0;i<v2.size();i++)
	{
		v1.push_back(v2.at(i));
	}
	return v1;
}

//把一个整数转化为string类型
string itos(int i){
	string str;
	char buff[5];
	itoa(i,buff,10);
	str.assign(buff);
	return str;
}
//根据tonke的种类,返回一个描述性质的字符串
string format_token(_TokenType t){
	string s = "";
	switch(t)
	{
	case _IF:
		s = "if";
		break;
	case _ELSE:
		s = "else";
		break;
	case _WHILE:
		s = "while";
		break;
	case _READ:
		s = "read";
		break;
	case _WRITE:
		s = "write";
		break;
	case _INT:
		s = "int";
		break;
	case _REAL:
		s = "real";
		break;
	case _RETURN:
		s = "return";
		break;
	case _ID:
		s = "identifier";
		break;
	case _INUM:
	case _RNUM:
		s = "number";
		break;
	case _PLUS:
		s = "plus sign";
		break;
	case _MINUS:
		s = "subtraction sign";
		break;
	case _MUL:
		s = "multiply sign";
		break;
	case _DIV:
		s = "division sign";
		break;
	case _ASSIGN:
		s = "=";
		break;
	case _LT:
	case _BT:
	case _NE:
	case _EQ:
		s = "relation operator";
		break;
	case _LSPAREN:
		s = "(";
		break;
	case _RSPAREN:
		s = ")";
		break;
	case _LMPAREN:
		s = "[";
		break;
	case _RMPAREN:
		s = "]";
		break;
	case _LBPAREN:
		s = "{";
		break;
	case _RBPAREN:
		s = "}";
		break;
	case _SEMI:
		s = "semicolon";
		break;
	case _COMMA:
		s = "comma";
		break;
	}
	return s;
}
//创建一个新的节点,类型为excepted指定的类型,并把它添加到t的子节点中去
static void newNode(_TokenType expected,TreeNode* t){
	TreeNode* node = new TreeNode(expected);
	switch(expected)
	{
	case _IF:
		node->describe = "if";
		break;
	case _ELSE:
		node->describe = "else";
		break;
	case _WHILE:
		node->describe = "while";
		break;
	case _READ:
		node->describe = "read";
		break;
	case _WRITE:
		node->describe = "write";
		break;
	case _INT:
		node->describe = "int";
		break;
	case _REAL:
		node->describe = "real";
		break;
	case _ASSIGN:
		node->describe = "Op: =";
		break;
	case _LT:
		node->describe = "Op: <";
		break;
	case _BT:
		node->describe = "Op: >";
		break;
	case _EQ:
		node->describe = "Op: ==";
		break;
	case _NE:
		node->describe = "Op: <>";
		break;
	case _PLUS:
		node->describe = "Op: +";
		break;
	case _MINUS:
		node->describe = "Op: -";
		break;
	case _MUL:
		node->describe = "Op: *";
		break;
	case _DIV:
		node->describe = "Op: /";
		break;
	case _ID:
		node->describe = "id: "+token.tv;
		break;
	case _INUM:
	case _RNUM:
		node->describe = "const: "+token.tv;
		break;
	case _SEMI:
		node->describe = ";";
		break;
	case _COMMA:
		node->describe = ",";
		break;
	case _LSPAREN:
		node->describe = "(";
		break;
	case _RSPAREN:
		node->describe = ")";
		break;
	case _LMPAREN:
		node->describe = "[";
		break;
	case _RMPAREN:
		node->describe = "]";
		break;
	case _LBPAREN:
		node->describe = "{";
		break;
	case _RBPAREN:
		node->describe = "}";
		break;
	case _ENDFILE:
		break;
	case _RETURN:
		node->describe = "return";
		break;
	}
	t->addChild(node);
}
//跳过一些token,直到firstset 或者followset里面出现的token为止
static int skip_until(vector<_TokenType> firstSet,vector<_TokenType> followSet){
	followSet.push_back(_ENDFILE);
	int size = firstSet.size()>followSet.size()?(firstSet.size()):(followSet.size());
	int ln = token.lineno;
	while (true)
	{
		for (int i=0;i<size;i++)
		{
			if (i<firstSet.size())
			{
				if (token.tp==firstSet.at(i))
				{
					//如果符号在firstset中,返回1
					return 1;
				}
			}
			if (i<followSet.size())
			{
				if (token.tp==followSet.at(i))
				{
					//如果符号在followset中,返回2
					return 2;
				}
			}			
		}
		if (printf_skip_err)
		{
			errorList->push_back("unknow token '"+ token.tv+"' at line "+ itos(token.lineno));
		}
		if (token.tp==_LBPAREN)
		{
			printf_skip_err = false;
		}
		token=tokenList->at(++index);
	}
	printf_skip_err = false;
	return 3;
}

//检查下一个输入符号是否再firstset里面,如果不在则调用跳转函数
static int check_input(vector<_TokenType> firstset,vector<_TokenType> followSet){
	int size = firstset.size();
	if (token.tp==_ENDFILE)
	{
		return 0;
	}
	for (int i=0;i<size;i++)
	{
		if (token.tp==firstset.at(i))
		{
			//如果符号在firstset中,返回0;
			return 0;
		}
	}
	parse_err = true;
	//如果符号不在firstset中,跳转到firstset或者followset的地方
	int check =  skip_until(firstset,followSet);
	errorList->push_back("unexcept tokens before '"+token.tv+"' at line "+itos(token.lineno));
	return check;
}

static void syntax_error(char* format,...){

}
//匹配token
static bool match(_TokenType expected,TreeNode* t){
	//如果匹配成功,则把当前token向前移动一位,并返回true
	if (token.tp==expected)
	{
		newNode(expected,t);
		token = tokenList->at(++index);
		return true;
	}
	//如果匹配失败,打印错误信息
	else{
		string str;
		char buff[5];
		itoa(token.lineno,buff,10);
		str.assign(buff);
		errorList->push_back("unexpect token '"+token.tv+"' at line "+ str + " need "+ format_token(expected)+" here");
		parse_err = true;
		return false;
	}
}

/*
*<declaration_list> ::= <dedeclaration> {dedeclaration} 
*firstset _INT _REAL
*/
TreeNode* declaration_list(){
	TreeNode* root = new TreeNode;
	root->describe="root";
	token = tokenList->at(index);
	vector<_TokenType> synchset;
	//循环的读取,直到文件结尾
	while (token.tp!=_ENDFILE)
	{
		TreeNode *t = dedeclaration(synchset);
		if (t!=NULL)
		{
			root->addChild(t);
		}
	}
	return root;
}

/*
*<dedeclaration>::= (int|real) (<var_declaration>|<fun_declaration>)
*firstset _INT _REAL
*followset _INT _REAL
*/
TreeNode* dedeclaration(vector<_TokenType> synchset){
	TreeNode* t = new TreeNode;
	TreeNode* temp = new TreeNode;
	t->describe = "dedeclaration";
	vector<_TokenType> firstset;
	vector<_TokenType> followset;
	firstset.push_back(_INT);
	firstset.push_back(_REAL);
	followset.push_back(_INT);
	followset.push_back(_REAL);
	followset.push_back(_LBPAREN);
	int line = token.lineno;
	int check = check_input(firstset,synchset);
	if (check!=0)
	{
		errorList->push_back("miss of type identifier at line "+itos(line));
	}
	if(token.tp==_LBPAREN){
		temp = compound_stmt(appendVector(synchset,followset));
		if (temp!=NULL)
		{
			t->addChild(temp);
		}
	}
	else{
		//变量或者函数为int型,设置符号的类型为0
		if (token.tp==_INT)
		{
			match(_INT,t);
			symbol->type = 0;
			type = 0;
		}
		//变量或者函数为real型,设置符号的类型为1
		else if(token.tp==_REAL){
			match(_REAL,t);
			symbol->type = 1;
			type = 1;
		}
		//缺少类型,打印错误
		else{
			parse_err = true;
			errorList->push_back("miss of type identifier at line "+itos(token.lineno));
		}
		//如果标识符的下一个符号为'(',则认为是函数定义,转向函数定义
		if((tokenList->at(index+1)).tp==_LSPAREN){
			temp = fun_declaration(appendVector(synchset,followset));
			if (temp!=NULL)
			{
				t->addChild(temp);
			}
		}
		//如果标识符的下一个符号不是'(',认为是变量定义,转向变量定义
		else{
			temp = var_declaration(appendVector(synchset,followset));
			if (temp!=NULL)
			{
				t->addChild(temp);
			}
		}
	}
	check = check_input(followset,firstset);
	return t;
}


/*
*<var_declaration>::=<var_list>
*firstset _ID
*followset _INT _REAL
*/
TreeNode* var_declaration(vector<_TokenType> synchset){
	TreeNode* t = new TreeNode;
	TreeNode* temp = new TreeNode;
	t->describe = "var_declaration";
	vector<_TokenType> firstset;
	vector<_TokenType> followset;
	firstset.push_back(_ID);
	firstset.push_back(_LMPAREN);
	followset.push_back(_INT);
	followset.push_back(_REAL);
	//全局变量定义,设置isLocal为false
	isLocal = false;
	int i = check_input(firstset,synchset);
	if (i==2)
	{
		errorList->push_back("miss identifier at line "+token.lineno);
		return NULL;
	}
	else{
		//match(_ID,t);
		//转向变量定义列表
		t=var_list(appendVector(synchset,followset));
		i = check_input(followset,firstset);
	}
	return t;
}

/*
*<fun_declaration>::=ID (<params>)<compound_stmt>
*firstset _ID
*followset _INT _REAL
*/
TreeNode* fun_declaration(vector<_TokenType> synchset){
	TreeNode* t = new TreeNode;
	TreeNode* temp = new TreeNode;
	t->describe = "fun_declaration";
	match(_ID,t);
	if (sym->find(tokenList->at(index-1).tv)!=NULL)
	{
		parse_err = true;
		errorList->push_back("identifier '"+tokenList->at(index-1).tv+"' redefine at line "+itos(tokenList->at(index-1).lineno));
	}
	else{
		//设置当前符号的id和地址
		symbol->id = tokenList->at(index-1).tv;
		symbol->address = itos(codeAddress);
		//设置当前符号的isfun属性为true
		symbol->isfun = true;
		//插入符号表,并创建新的符号以便处理下一个符号
		sym->insert(symbol);	
		//设置当前函数的id
		fun->id = tokenList->at(index-1).tv;
		fun->address = symbol->address;
		fun->type = symbol->type;
		symbol = new Symbol;
		//初始化逻辑地址为2
		//逻辑地址为0是老的sp,1为返回地址
		local_address = 2;
	}
	match(_LSPAREN,t);
	//函数的参数
	temp=params(synchset);
	if (temp!=NULL)
	{
		t->addChild(temp);
	}
	match(_RSPAREN,t);
	//函数体
	temp=compound_stmt(synchset);
	if (temp!=NULL)
	{
		t->addChild(temp);
	}
	funs->insert(fun);
	fun = new Function;
	//如果函数没有返回语句,执行到函数体结束后,自动添加一个返回语句,返回0
	//如果有返回语句,则永远不会执行到这一句,这一句无效
	code->push_back("LIT 0 0");
	codeAddress++;
	code->push_back("RET");
	codeAddress++;
	return t;
}

/*
*<params>::= (void)| {(int|real) (ID)|(ID[])}
*firstset _RSPAREN _INT _REAL
*followset _RSPAREN
*/
TreeNode* params(vector<_TokenType> synchset){
	SymTable* ts = new SymTable;
	ts->parent = sym;
	sym = ts;
	vector<_TokenType> firstset;
	vector<_TokenType> followset;

⌨️ 快捷键说明

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