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

📄 symboltable.cpp

📁 pl0文法编译器
💻 CPP
字号:

#include "SymbolTable.h"
#include "GramAnalyze.h"
#include "CCode.h"
#include "Errors.h"
#include <iostream>
using namespace std;

SymbolTable::SymbolTable(PL0Compiler *p)
{
	pl0Compiler = p;
	lev = -1;
	tx[0] = -1;
}

void SymbolTable::enter(enum object k, Symbol s)
{
	//token_pair token = pl0Compiler->gramAnalyze->getToken();
	//lev = pl0Compiler->gramAnalyze->getLev();
	if(nameCheck(pl0Compiler->gramAnalyze->getName()))
	{
		pl0Compiler->errors->addError(30);
		return;
	}
	tx[lev]++;
	if(tx[lev] > MAX_TABLELENGTH)	return;
	//table[tx[lev]].name = pl0Compiler->gramAnalyze->getName();
	table[tx[lev]].name = pl0Compiler->gramAnalyze->getName();
	table[tx[lev]].type = s;//inum, rnum, cha, chastring
	table[tx[lev]].kind = k;//const, variable, procedure, func
	table[tx[lev]].level = lev;
	//table[tx[lev]].numOfBlock = 0;
	switch(k)
	{
	case constent:
		{
			switch(table[tx[lev]].type) 
			{
			case inum:
				table[tx[lev]].Val = (int)pl0Compiler->gramAnalyze->getNumber();
				break;
			case rnum:
				table[tx[lev]].Val = pl0Compiler->gramAnalyze->getNumber();
				break;
			case cha:
				table[tx[lev]].Val = (char)pl0Compiler->gramAnalyze->getNumber();
				break;
			case chastring:
				//table[tx[lev]].sVal = token.second.c_str();
				table[tx[lev]].Val = (int)pl0Compiler->gramAnalyze->getNumber();
			}
			//table[tx[lev]].level = lev;
			break;
		}
	case variable: case para:
		//table[tx[lev]].level = lev;
		table[tx[lev]].address = pl0Compiler->gramAnalyze->DataAddr();
		//pl0Compiler->gramAnalyze->DataAddr(1);//dx指针加一
		break;
	case procedure: case func:
		//table[tx[lev]].level = lev;
		table[tx[lev]].address = 0;
		break;
	}
	//list();
}

void SymbolTable::setTable()
{
	if(lev==-1)
	{
		lev = 0;
		return;
	}
	if(lev < MAX_LEV)
	{
		tx[++lev] = tx[lev-1];
	}
	else
	{
		pl0Compiler->errors->addError(6);
	}
}

void SymbolTable::rsetTable()
{
	int i = tx[lev];
	int j = 0;
	while(table[i].level == lev)
	{
		if(table[i].kind==para&&table[i].address!=-1)
			break;
		i--;
	}
	j = i;
	while(table[i].level==lev && table[i].kind==para)
	{
		table[i].name=" ";
		table[i].address=-1;
		table[i].level=lev-1;
		i--;
	}
	if( lev >= 0 )
	{
		tx[--lev]=j;
	}
}

int SymbolTable::position(string tokenName)
{
	for(int i = tx[lev]; i>=0; i--)
	{
		if(table[i].name.empty()) 
			continue;
		if(tokenName==table[i].name)
			break;
	}
	return i;
}

void SymbolTable::typeFill(Symbol t, object k)
{
	//int i = tx[lev];
	//int l = lev;
	if(k==variable || k==para)
	{
		for(int i = tx[lev],l = lev; table[i].level==l&&i>=0&&table[i].type==ident; i--)
		{
			table[i].type = t;
		}
	}
	if(k==func)
	{
		for(int i = tx[lev]; i>=0; i--)
		{
			if(table[i].type==funcsy)
				table[i].type = t;
		}
	}
	
}

void SymbolTable::list()
{
	
	
	cout<<endl<<"Symbol Table:"<<endl;
	for(int i = 0; i <= tx[lev]; i++)
	{
		table_type tbl = table[i];
		cout<<i+1<<'\t'<<tbl.name<<'\t';
		if(tbl.kind == constent)
		{
			cout<<"\tconst";
			switch(tbl.type)
			{
			case inum:	cout<<"\tinum\t"<<"level: "<<tbl.level<<'\t'<<"value: "<<tbl.Val<<endl; break;
			case rnum:	cout<<"\trnum\t"<<"level: "<<tbl.level<<'\t'<<"value: "<<tbl.Val<<endl;	break;
			case cha:	cout<<"\tcha\t"<<"level: "<<tbl.level<<'\t'<<"value: "<<tbl.Val<<endl;	break;	
			}
		}
		if(tbl.kind == variable)
		{
			cout<<"\tvar\t";
			switch(tbl.type)
			{
			case inum:	cout<<"inum\t"; break;
			case rnum:	cout<<"rnum\t";	break;
			case cha:	cout<<"cha\t";	break;	
			}
			cout<<"level: "<<tbl.level<<"\tadress: "<<tbl.address<<endl;
		}
		if(tbl.kind == procedure)
		{
			cout<<"\tprocedure\tlevel: "<<tbl.level<<"\tadress: "<<tbl.address<<endl;
		}
		if(tbl.kind == func)
		{
			cout<<"\tfunc";
			switch(tbl.type)
			{
			case inum:	cout<<"\tinum\t"<<"level: "<<tbl.level<<"\tadress:"<<tbl.address<<endl; break;
			case rnum:	cout<<"\trnum\t"<<"level: "<<tbl.level<<"\tadress:"<<tbl.address<<endl;	break;
			case cha:	cout<<"\tcha\t"<<"level: "<<tbl.level<<"\tadress:"<<tbl.address<<endl;	break;	
			case funcsy:cout<<"\tfuncsy"<<endl;
			}
		}
		if(tbl.kind == para)
		{
			cout<<"\tpara\t";
			switch(tbl.type)
			{
			case inum:	cout<<"inum\t"; break;
			case rnum:	cout<<"rnum\t";	break;
			case cha:	cout<<"cha\t";	break;	
			}
			cout<<"level: "<<tbl.level<<"\tadress: "<<tbl.address<<endl;
		}
	}
}

int SymbolTable::funcproNameCheck(string tempname,object k)
{
	for(int i = tx[lev]; i>=0; i--)
	{
		if(table[i].name==tempname && table[i].kind==k)
			break;
	}
	return i;
}

int SymbolTable::funcproNameCheck(string tempname)
{
	for(int i = tx[lev]; i>=0; i--)
	{
		if(table[i].name==tempname && (table[i].kind==procedure||table[i].kind==func))
			break;
	}
	return i;
}



int SymbolTable::noOfPara(string name, object k)
{
	int i = funcproNameCheck(name,k);
	i++;
	for(int n = 0;table[i].kind==para;i++,n++);
	return n;
}

int SymbolTable::noOfPara(string name)
{
	int i = funcproNameCheck(name);
	i++;
	for(int n = 0;table[i].kind==para;i++,n++);
	return n;
}


Symbol SymbolTable::typeOfPara(string name, int n,object k)
{
	int i = funcproNameCheck(name,k);
	if( n > noOfPara(name,k) )
		return nul;
	else
	{
		i+=n;
		return table[i].type;
	}
}

void SymbolTable::setNumOfBlock(object k )
{
	for(int i = tx[lev]; i>= 0; i--)
	{
		if(table[i].kind==procedure || table[i].kind==func)
		{
			table[i].numOfBlock = sizeOfBBlock(table[i].name,k);
			break;
		}
	}
}

bool SymbolTable::nameCheck(string tempName)
{
	if(tx[lev]<0) return false;
	for(int i = tx[lev]; table[i].level==lev; i--)
	{
		if(table[i].name==tempName)
			return true;
	}
	return false;
}

int SymbolTable::findRecentFunPro()
{
	for(int i = tx[lev]; table[i].level==lev;i--);
	return i;
}

void SymbolTable::setFunProAdr(int adr)
{
	int i = findRecentFunPro();
	if(i>=0)
	{
		table[i].address = adr;
	}
}

int SymbolTable::sizeOfBBlock(string tempName,object k)
{
	int i = funcproNameCheck(tempName,k);
	int l = table[i].level+1;
	int n = 0;
	if(l>lev+1)
		return 0;
	i++;
		for(; table[i].kind!=procedure&&table[i].kind!=func&&i<=tx[lev]; i++)
		{
			if(table[i].kind==para||table[i].kind==variable)
			{
				n++;
				continue;
			}
		}
	return n;
}

int SymbolTable::sizeOfBBlock()
{
	if(tx[lev]<0)
		return 0;
	int n = 0;
	for(int i = 0; table[i].kind!=procedure&&table[i].kind!=func&&i<=tx[lev]; i++)
	{
		if(table[i].kind==para||table[i].kind==variable)
		{
			n++;
			continue;
		}
	}
	return n;
}

⌨️ 快捷键说明

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