gramanalyze.cpp
来自「pl0文法编译器」· C++ 代码 · 共 1,130 行 · 第 1/2 页
CPP
1,130 行
#include "GramAnalyze.h"
#include "PL0Compiler.h"
#include "SymSet.h"
#include "Errors.h"
#include "SymbolTable.h"
#include "CCode.h"
#include <iostream>
#include <utility>
using namespace std;
GramAnalyze::GramAnalyze(PL0Compiler *p)
{
lev = -1;
for(int i = 0; i <= MAX_LEV; i++)
dx[i] = 4;
pl0Compiler = p;
declBegSys+=constsy; declBegSys+=varsy; declBegSys+=procsy; declBegSys+=funcsy;
statBegSys+=beginsy; statBegSys+=ifsy; statBegSys+=whilesy;statBegSys+=forsy;
facBegSys+=ident; facBegSys+=inum; facBegSys+=rnum; facBegSys+=cha; facBegSys+=lparsy;
}
void GramAnalyze::startCompile()
{
SymSet set1; set1=declBegSys; set1+=statBegSys;
lev++;
getSymbol();
pl0Compiler->symbolTable->setTable();
block(set1);
}
bool GramAnalyze::test(SymSet s1, SymSet s2, int errorCode)
{
if( !s1.inSet(token.first) )
{
pl0Compiler->errors->addError(errorCode);
s1 += s2;
do {
getSymbol();
} while( !s1.inSet(token.first) );
return false;
}
return true;
}
void GramAnalyze::constDeclaration()
{
int fuhao = 1;
if( token.first == ident )
{
name = token.second;
getSymbol();
if(token.first == equsy)
{
getSymbol();
if(token.first==plussy) getSymbol();
if(token.first==minussy) {fuhao=-1; getSymbol();}
SymSet set1;
set1+=inum;
set1+=rnum;
set1+=cha;
set1+=chastring;
if( set1.inSet(token.first) )
{
set1-=chastring;
set1-=cha;
if(set1.inSet(token.first))
{
number = atof(token.second.c_str())*fuhao;
if(token.first == inum)
pl0Compiler->symbolTable->enter(constent, inum);
if(token.first == rnum)
pl0Compiler->symbolTable->enter(constent, rnum);
}
if(token.first == cha )
{
number = token.second.at(0);
pl0Compiler->symbolTable->enter(constent, cha);
}
if(token.first == chastring)
{
pl0Compiler->ccode->stringEnter(token.second);
number = pl0Compiler->ccode->getStringID();
pl0Compiler->symbolTable->enter(constent, chastring);
}
}
else
{
pl0Compiler->errors->addError(13);
}
}
else
pl0Compiler->errors->addError(12);
}
else
pl0Compiler->errors->addError(11);
getSymbol();
}
void GramAnalyze::varEnter(object kind)
{
if(token.first == ident)
{
name = token.second;
pl0Compiler->symbolTable->enter(kind,ident);
dx[lev]++;
getSymbol();
}
else
pl0Compiler->errors->addError(11);
}
void GramAnalyze::varDeclaration(object kind)
{
do{
varEnter(kind);
while(token.first == commasy)
{
getSymbol();
varEnter(kind);
}
}while( token.first == ident );
if(token.first == colonsy)//如果是‘:’
{
getSymbol();//得到类型说明符
if( token.first==intsy || token.first==realsy || token.first==charsy )
{
switch(token.first)
{
case intsy: pl0Compiler->symbolTable->typeFill(inum,kind); break;
case realsy: pl0Compiler->symbolTable->typeFill(rnum,kind); break;
case charsy: pl0Compiler->symbolTable->typeFill(cha,kind); break;
default: pl0Compiler->symbolTable->typeFill(inum,kind); break;
}
}
else
{
pl0Compiler->errors->addError(15);//缺少类型说明符
pl0Compiler->symbolTable->typeFill(inum,kind);
return;
}
}
else if( token.first==intsy || token.first==realsy || token.first==charsy )
{
pl0Compiler->errors->addError(14);//缺少‘:’
switch(token.first)
{
case intsy: pl0Compiler->symbolTable->typeFill(inum,kind); break;
case realsy: pl0Compiler->symbolTable->typeFill(rnum,kind); break;
case charsy: pl0Compiler->symbolTable->typeFill(cha,kind); break;
default: pl0Compiler->symbolTable->typeFill(inum,kind); break;
}
}
else if(token.first == semicolonsy)
{
pl0Compiler->errors->addError(14);//缺少‘:’
pl0Compiler->errors->addError(15);//缺少类型说明符
pl0Compiler->symbolTable->typeFill(inum,kind);
return;
}
getSymbol();
}
void GramAnalyze::block(SymSet set1)
{
//生成跳转指令,跳过声明部分到符合语句处理部分
pl0Compiler->ccode->gen(JMP,0,0);
int tx = pl0Compiler->ccode->getTopIndex();
pl0Compiler->symbolTable->setFunProAdr(tx);
//*********************************常量声明部分************************************/
if(token.first == constsy)
{
getSymbol();
do{
constDeclaration();
while(token.first==commasy)
{
getSymbol();
constDeclaration();
}
if(token.first==semicolonsy)
getSymbol();
else if(token.first != ident)
pl0Compiler->errors->addError(14);
}while(token.first == ident);
}
//*********************************变量声明部分************************************/
if(token.first == varsy)
{
getSymbol();
do{
varDeclaration(variable);
if(token.first == semicolonsy)
getSymbol();
else
pl0Compiler->errors->addError(14);
}while(token.first == ident);
}
//*********************************************************************************/
int i = pl0Compiler->symbolTable->findRecentFunPro();
if(i>=0)
pl0Compiler->symbolTable->setNumOfBlock(pl0Compiler->symbolTable->getTable(i).kind);
SymSet tempSet1; tempSet1=set1;
SymSet tempSet2; tempSet2+=endsy;
while(token.first==procsy || token.first == funcsy)
{
//********************************过程声明部分*************************************/
if(token.first==procsy)
{
do{
getSymbol();
procDeclaration(set1);
if(token.first==semicolonsy) getSymbol();
else pl0Compiler->errors->addError(14);
}while(token.first==procsy);
}
test(tempSet1,tempSet2,25);
//**********************************************************************************/
//**********************************函数声明****************************************/
if(token.first==funcsy)
{
do{
getSymbol();
funcDeclaration(set1);
if(token.first==semicolonsy) getSymbol();
else pl0Compiler->errors->addError(14);
}while(token.first==funcsy);
}
test(tempSet1,tempSet2,25);
}
//填入之前跳转指令的跳转地址
pl0Compiler->ccode->setAdr(tx,pl0Compiler->ccode->getTopIndex()+1);
//***********************************************************************************/
if(lev==0)
{
int n = pl0Compiler->symbolTable->sizeOfBBlock();
pl0Compiler->ccode->gen(ALOC,-1,n);
}
else if(lev>0)
{
int i = pl0Compiler->symbolTable->findRecentFunPro();
if(i >= 0)
{
table_type tbl = pl0Compiler->symbolTable->getTable(i);
pl0Compiler->ccode->gen(ALOC,0,tbl.numOfBlock);
int numOfPara = pl0Compiler->symbolTable->noOfPara(tbl.name);
for(int i = numOfPara+3; i>=4; i--)
{
pl0Compiler->ccode->gen(STO, 0, i);
}
}
}
//******************************一下为复合语句处理部分*******************************/
if(token.first!=beginsy)
pl0Compiler->errors->addError(24);
else
{
tempSet1.reSet();
tempSet1=set1;
set1+=endsy;
getSymbol();
pl0Compiler->gramAnalyze->compStament(tempSet1);
}
//***********************************************************************************/
lev--;
pl0Compiler->symbolTable->rsetTable();
pl0Compiler->ccode->gen(RTN,0,0);
if(lev==-1)
{
if(token.first!=dot)
pl0Compiler->errors->addError(53);
}
}
void GramAnalyze::formalPar(SymSet set1)
{
varDeclaration(para);
while(token.first==semicolonsy)
{
getSymbol();
varDeclaration(para);
}
}
void GramAnalyze::procDeclaration(SymSet set1)
{
lev++;
dx[lev]=4;
if(token.first==ident)
{
name = token.second;
pl0Compiler->symbolTable->enter(procedure,nul);
pl0Compiler->symbolTable->setTable();
getSymbol();
if(token.first==lparsy)//处理参数列表
{
getSymbol();
formalPar(set1);
if(token.first==rparsy) getSymbol();
else pl0Compiler->errors->addError(17);
}
}
else
pl0Compiler->errors->addError(16);//缺少过程或函数名
if(token.first==semicolonsy) getSymbol();
else pl0Compiler->errors->addError(14);//过程首部结尾缺少‘;’
set1+=semicolonsy;
block(set1);
}
void GramAnalyze::funcHead(SymSet set1)
{
if(token.first==ident)
{
name = token.second;
pl0Compiler->symbolTable->enter(func,funcsy);
pl0Compiler->symbolTable->setTable();
getSymbol();
if(token.first==lparsy)
{
getSymbol();
formalPar(set1);
if(token.first==rparsy)
{
getSymbol();
if(token.first == colonsy)//如果是‘:’
{
getSymbol();//得到类型说明符
if( token.first==intsy || token.first==realsy || token.first==charsy )
{
switch(token.first)
{
case intsy: pl0Compiler->symbolTable->typeFill(inum,func); break;
case realsy: pl0Compiler->symbolTable->typeFill(rnum,func); break;
case charsy: pl0Compiler->symbolTable->typeFill(cha,func); break;
default: pl0Compiler->symbolTable->typeFill(inum,func); break;
}
getSymbol();
}
else
{
pl0Compiler->errors->addError(15);//缺少类型说明符
pl0Compiler->symbolTable->typeFill(inum,func);
getSymbol();
return;
}
}
else if( token.first==intsy || token.first==realsy || token.first==charsy )
{
pl0Compiler->errors->addError(14);//缺少‘:’
switch(token.first)
{
case intsy: pl0Compiler->symbolTable->typeFill(inum,func); break;
case realsy: pl0Compiler->symbolTable->typeFill(rnum,func); break;
case charsy: pl0Compiler->symbolTable->typeFill(cha,func); break;
default: pl0Compiler->symbolTable->typeFill(inum,func); break;
}
getSymbol();
}
else if(token.first == semicolonsy)
{
getSymbol();
pl0Compiler->errors->addError(14);//缺少‘:’
pl0Compiler->errors->addError(15);//缺少类型说明符
pl0Compiler->symbolTable->typeFill(inum,func);
return;
}
}
else pl0Compiler->errors->addError(17);
}
else if(token.first == colonsy)//如果是‘:’
{
getSymbol();//得到类型说明符
if( token.first==intsy || token.first==realsy || token.first==charsy )
{
switch(token.first)
{
case intsy: pl0Compiler->symbolTable->typeFill(inum,func); break;
case realsy: pl0Compiler->symbolTable->typeFill(rnum,func); break;
case charsy: pl0Compiler->symbolTable->typeFill(cha,func); break;
default: pl0Compiler->symbolTable->typeFill(inum,func); break;
}
getSymbol();
}
else
{
pl0Compiler->errors->addError(15);//缺少类型说明符
pl0Compiler->symbolTable->typeFill(inum,func);
getSymbol();
}
}
else if( token.first==intsy || token.first==realsy || token.first==charsy )
{
pl0Compiler->errors->addError(14);//缺少‘:’
switch(token.first)
{
case intsy: pl0Compiler->symbolTable->typeFill(inum,func); break;
case realsy: pl0Compiler->symbolTable->typeFill(rnum,func); break;
case charsy: pl0Compiler->symbolTable->typeFill(cha,func); break;
default: pl0Compiler->symbolTable->typeFill(inum,func); break;
}
getSymbol();
}
else if(token.first == semicolonsy)
{
pl0Compiler->errors->addError(14);//缺少‘:’
pl0Compiler->errors->addError(15);//缺少类型说明符
pl0Compiler->symbolTable->typeFill(inum,func);
getSymbol();
return;
}
}
else
pl0Compiler->errors->addError(16);//缺少函数或过程名
if(token.first==semicolonsy) getSymbol();
else pl0Compiler->errors->addError(14);//函数首部结尾缺少‘;’
}
void GramAnalyze::funcDeclaration(SymSet set1)
{
lev++;
dx[lev]=4;
SymSet tempset1; tempset1=set1; tempset1+=declBegSys; tempset1+=statBegSys;
funcHead(tempset1);
set1+=semicolonsy;
block(set1);
}
void GramAnalyze::readFunc(SymSet set1)
{
if(token.first==lparsy)
{
do{
getSymbol();
if(token.first==ident)
{
int i = pl0Compiler->symbolTable->position(token.second);
if(i<0) pl0Compiler->errors->addError(21);//标识符未声明
else
{
table_type tbl = pl0Compiler->symbolTable->getTable(i);
if(tbl.kind!=variable)
{
pl0Compiler->errors->addError(20);//不可向非常量赋值
i = 0;
}
else
{
if(pl0Compiler->symbolTable->getTable(i).type==cha)
{
pl0Compiler->ccode->gen(READS, lev-tbl.level, tbl.address);
}
else if(pl0Compiler->symbolTable->getTable(i).type==inum)
{
pl0Compiler->ccode->gen(READI, lev-tbl.level, tbl.address);
}
else if(pl0Compiler->symbolTable->getTable(i).type==rnum)
{
pl0Compiler->ccode->gen(READR, lev-tbl.level, tbl.address);
}
}
}
getSymbol();
}
else
pl0Compiler->errors->addError(11);//缺少标识符
}while(token.first==commasy);
}
else
pl0Compiler->errors->addError(19);//缺少左括号
if(token.first!=rparsy)
pl0Compiler->errors->addError(13);//缺少右括号
else
getSymbol();
}
void GramAnalyze::writeFunc(SymSet set12)
{
SymSet set1;
set1+=plussy; set1+=minussy; set1+=ident; set1+=inum; set1+=rnum; set1+=lparsy;
if(token.first==lparsy)
{
do{
getSymbol();
bool b = false;
if(token.first==chastring)
{
string temp = token.second;
pl0Compiler->ccode->stringEnter(token.second);
int id = pl0Compiler->ccode->getStringID();
pl0Compiler->ccode->gen(WRTSTR,0,id);
getSymbol();
if(token.first==commasy)
getSymbol();
else
pl0Compiler->errors->addError(22);//缺少‘,’
}
else
{
pl0Compiler->errors->addError(22);
b = true;
}
if(set1.inSet(token.first))
{
int id2;
set12+=commasy; set12+=rparsy;
if(token.first==ident)
{
int i = pl0Compiler->symbolTable->position(token.second);
id2 = pl0Compiler->symbolTable->getTable(i).Val;
}
Symbol tempType = expression(set12);
switch(tempType)
{
case cha: pl0Compiler->ccode->gen(WRTCH,0,0); break;
case inum: pl0Compiler->ccode->gen(WRTI,0,0); break;
case rnum: pl0Compiler->ccode->gen(WRTR,0,0); break;
case chastring: pl0Compiler->ccode->gen(WRTSTR,0,id2); break;
}
//pl0Compiler->ccode->list();
//getSymbol();
}
else
{
if(!b)
pl0Compiler->errors->addError(22);
}
}while(token.first == commasy);
}
else
pl0Compiler->errors->addError(19);//缺少左括号
if(token.first!=rparsy)
pl0Compiler->errors->addError(17);//缺少右括号
else
getSymbol();
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?