📄 symboltable.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 + -