gramanalyze.cpp
来自「pl0文法编译器」· C++ 代码 · 共 1,130 行 · 第 1/2 页
CPP
1,130 行
}
Symbol GramAnalyze::expression(SymSet set1)
{
bool sflag=false;
Symbol fuhao;
Symbol type = cha;
Symbol temp1,temp2;
SymSet tempSet1; tempSet1=set1; tempSet1+=minussy; tempSet1+=plussy;
if(token.first==plussy || token.first==minussy)
{
fuhao = token.first;
getSymbol();
temp1 = term(tempSet1);
if(temp1>type) type = temp1;
if(fuhao==minussy)
pl0Compiler->ccode->gen(REV,0,0);
}
else
{
temp1 = term(tempSet1);
if(temp1 > type) type = temp1;
}
while(token.first==plussy || token.first==minussy)
{
fuhao = token.first;
getSymbol();
if(token.first!=ident && token.first!=rnum && token.first!=inum && token.first!= cha )
break;
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 == procedure)
break;
}
}
temp2 = term(tempSet1);
if(temp2 > type) type = temp2;
if((temp1==chastring || temp2==chastring) && !sflag)
{
pl0Compiler->errors->addError(41);
sflag = true;
}
if(fuhao==plussy)
{
pl0Compiler->ccode->gen(ADD,0,0);
}
else
{
pl0Compiler->ccode->gen(MIN,0,0);
}
}
return type;
}
void GramAnalyze::compStament(SymSet set12)
{
set12+=semicolonsy; set12+=endsy;
stament(set12);
SymSet set1;
set1+=semicolonsy; set1+=beginsy; set1+=ifsy; set1+=whilesy; set1+=forsy;
while(set1.inSet(token.first))
{
if(token.first==semicolonsy) getSymbol();
else pl0Compiler->errors->addError(14);
stament(set12);
}
if(token.first==endsy) getSymbol();
else pl0Compiler->errors->addError(23);
}
void GramAnalyze::stament(SymSet set1)
{
switch(token.first)
{
case readsy: getSymbol(); readFunc(set1); break;
case writesy: getSymbol(); writeFunc(set1); break;
case ident: identForStatment(set1); break;
case beginsy: getSymbol(); compStament(set1); break;
case ifsy: getSymbol(); ifFunc(set1); break;
case forsy: getSymbol(); forFunc(set1); break;
case whilesy: getSymbol(); whileFunc(set1); break;
case semicolonsy: case endsy: break;
default: pl0Compiler->errors->addError(35);
}
SymSet set2;
test(set1,set2,35);
}
Symbol GramAnalyze::term(SymSet set1)
{
set1+=timesy;
set1+=divisy;
bool sflag=false;
Symbol fuhao;
Symbol type = cha;
Symbol temp1,temp2;
temp1 = factor(set1);
if(temp1>type) type = temp1;
while(token.first==timesy || token.first==divisy)
{
fuhao = token.first;
getSymbol();
if(token.first!=ident && token.first!=rnum && token.first!=inum && token.first!= cha && token.first!=lparsy)
break;
if(token.first==ident)
{
table_type tbl;
int i = pl0Compiler->symbolTable->position(token.second);
if(i > 0)
{
tbl = pl0Compiler->symbolTable->getTable(i);
if(tbl.kind == procedure)
break;
}
}
temp2 = factor(set1);
if((temp1==chastring || temp2==chastring) && !sflag)
{
pl0Compiler->errors->addError(41);
sflag = true;
}
if(temp2>type) type = temp2;
if(fuhao==timesy)
{
pl0Compiler->ccode->gen(TIM,0,0);
}
else if(temp1<=inum && temp2<=inum)
{
pl0Compiler->ccode->gen(DIVI,0,0);
}
else
{
pl0Compiler->ccode->gen(DIV,0,0);
}
}
return type;
}
Symbol GramAnalyze::factor(SymSet set1)
{
test(facBegSys,set1,27);
Symbol type = cha;
while(facBegSys.inSet(token.first))
{
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);
switch(tbl.kind)
{
case variable: case para:
switch(tbl.type)
{
case inum: pl0Compiler->ccode->gen(LODI,lev-tbl.level,tbl.address); break;
case rnum: pl0Compiler->ccode->gen(LODR,lev-tbl.level,tbl.address); break;
case cha: pl0Compiler->ccode->gen(LODCH,lev-tbl.level,tbl.address); break;
default: break;
}
if(tbl.type>type) type = tbl.type;
getSymbol();
break;
case constent:
switch (tbl.type)
{
case inum: pl0Compiler->ccode->gen(LITI,0,tbl.Val); break;
case rnum: pl0Compiler->ccode->gen(LITR,0,tbl.Val); break;
case cha: pl0Compiler->ccode->gen(LITCH,0,tbl.Val); break;
}
if(tbl.type>type) type = tbl.type;
getSymbol();
break;
case func:
{
if(tbl.type>type) type = tbl.type;
SymSet tempSet1 = set1; set1+=minussy; set1+=plussy; set1+=divisy; set1+=timesy;
funcCall(tempSet1);
break;
}
default: pl0Compiler->errors->addError(28);
}
}
}
if(token.first==inum||token.first==rnum||token.first==cha)
{
if(token.first>type) type = token.first;
if(token.first==cha)
{
pl0Compiler->ccode->gen(LITCH,0,token.second.at(0));
}
else
{
switch (token.first)
{
case inum: pl0Compiler->ccode->gen(LITI,0,atof(token.second.c_str())); break;
case rnum: pl0Compiler->ccode->gen(LITR,0,atof(token.second.c_str())); break;
}
}
getSymbol();
}
if(token.first==lparsy)
{
getSymbol();
SymSet tempSet1; tempSet1=set1; tempSet1+=rparsy;
Symbol temp = expression(tempSet1);
if(temp>type) type = temp;
if(token.first==rparsy)
getSymbol();
else
pl0Compiler->errors->addError(17);
}
SymSet set2; set2+=endsy;
test(set1,set2,29);
}
return type;
}
void GramAnalyze::funcCall(SymSet set1)
{
int i = pl0Compiler->symbolTable->funcproNameCheck(token.second, func);
if( i < 0)
{
pl0Compiler->errors->addError(33);
}
else
{
int numOfPara = pl0Compiler->symbolTable->noOfPara(token.second,func);
int n = numOfPara;
//pl0Compiler->ccode->gen(ALOC,lev-pl0Compiler->symbolTable->getTable(i).level,pl0Compiler->symbolTable->getTable(i).numOfBlock);
getSymbol();
if(n>0)
{
if(token.first!=lparsy)
pl0Compiler->errors->addError(19);
else
{
getSymbol();
actualPara(set1, i+1,n);
}
}
pl0Compiler->ccode->gen(CALL,lev-pl0Compiler->symbolTable->getTable(i).level,pl0Compiler->symbolTable->getTable(i).address);
}
}
void GramAnalyze::procCall(SymSet set1)
{
int i = pl0Compiler->symbolTable->funcproNameCheck(token.second,procedure);
if( i < 0)
{
pl0Compiler->errors->addError(34);
}
else
{
int numOfPara = pl0Compiler->symbolTable->noOfPara(token.second,procedure);
int n = numOfPara;
//pl0Compiler->ccode->gen(ALOC,lev-pl0Compiler->symbolTable->getTable(i).level,pl0Compiler->symbolTable->getTable(i).numOfBlock);
getSymbol();
if(n>0)
{
if(token.first!=lparsy)
pl0Compiler->errors->addError(19);
else
{
getSymbol();
actualPara(set1, i+1,n);
}
}
pl0Compiler->ccode->gen(CALL,lev-pl0Compiler->symbolTable->getTable(i).level,pl0Compiler->symbolTable->getTable(i).address);
}
}
void GramAnalyze::actualPara(SymSet set1, int i, int &numOfPara)
{
set1+=rparsy; set1+=commasy;
table_type tbl = pl0Compiler->symbolTable->getTable(i);
Symbol type = expression(set1);
if(type > tbl.type)
{
if(type!=inum)
pl0Compiler->errors->addError(52);
}
numOfPara--;
while(token.first==commasy)
{
getSymbol();
numOfPara--; i++;
if(numOfPara < 0)
{
pl0Compiler->errors->addError(32);
break;
}
table_type tbl = pl0Compiler->symbolTable->getTable(i);
Symbol type = expression(set1);
if(type > tbl.type)
{
if(type==inum)
break;
pl0Compiler->errors->addError(52);
}
}
if(numOfPara>0)
pl0Compiler->errors->addError(32);
if(token.first==rparsy)
getSymbol();
else
pl0Compiler->errors->addError(17);
}
void GramAnalyze::identForStatment(SymSet set1)
{
int i = pl0Compiler->symbolTable->position(token.second);
if(i < 0)
pl0Compiler->errors->addError(21);
else
{
table_type tbl = pl0Compiler->symbolTable->getTable(i);
int l = tbl.level;
int a = tbl.address;
Symbol type = tbl.type;
Symbol temptype = cha;
if(tbl.kind==variable||tbl.kind==para)
{
getSymbol();
if(token.first==assignsy || token.first==equsy)
{
if(token.first==equsy) pl0Compiler->errors->addError(51);
getSymbol();
temptype = expression(set1);
if(temptype>type)
{
if(temptype!=inum)
pl0Compiler->errors->addError(52);
}
pl0Compiler->ccode->gen(STO, lev-l,a);
}
else
pl0Compiler->errors->addError(12);
}
else if(tbl.kind == func)
{
int funcLev = tbl.level;
getSymbol();
if(token.first==assignsy || token.first==equsy)
{
getSymbol();
if(token.first==equsy) pl0Compiler->errors->addError(51);
temptype = expression(set1);
if(temptype>type)
{
if(temptype!=inum)
pl0Compiler->errors->addError(52);
}
pl0Compiler->ccode->gen(STO, lev-funcLev-1,3);
}
else
pl0Compiler->errors->addError(12);
}
else if(tbl.kind == procedure)
{
procCall(set1);
}
else
pl0Compiler->errors->addError(35);
}
}
void GramAnalyze::condition(SymSet set1)
{
SymSet conditionSet;
conditionSet+=equsy; conditionSet+=nequsy; conditionSet+=lesssy; conditionSet+=leseqsy; conditionSet+=grtsy; conditionSet+=grteqsy;
SymSet tempSet = set1; tempSet+=conditionSet;
expression(tempSet);
if(conditionSet.inSet(token.first))
{
Symbol conSy = token.first;
getSymbol();
set1+=conditionSet;
expression(set1);
switch(conSy)
{
case equsy: pl0Compiler->ccode->gen(EQU, 0,0); break;
case nequsy: pl0Compiler->ccode->gen(NEQU, 0,0); break;
case lesssy: pl0Compiler->ccode->gen(LES, 0,0); break;
case leseqsy: pl0Compiler->ccode->gen(LESEQ, 0,0); break;
case grtsy: pl0Compiler->ccode->gen(GRT, 0,0); break;
case grteqsy: pl0Compiler->ccode->gen(GRTEQ, 0,0); break;
default: break;
}
}
else
pl0Compiler->errors->addError(36);
}
void GramAnalyze::whileFunc(SymSet set1)
{
int cx1 = pl0Compiler->ccode->getTopIndex()+1;
set1+=dosy;
condition(set1);
set1-=dosy;
pl0Compiler->ccode->gen(JPC,0,0);
int cx2 = pl0Compiler->ccode->getTopIndex();
if(token.first==dosy)
{
set1+=endsy; set1+=semicolonsy;
getSymbol();
}
else
{
pl0Compiler->errors->addError(39);
}
set1+=endsy; set1+=semicolonsy;
stament(set1);
pl0Compiler->ccode->gen(JMP, 0, cx1);
pl0Compiler->ccode->setAdr(cx2,pl0Compiler->ccode->getTopIndex()+1);
}
void GramAnalyze::forFunc(SymSet set1)
{
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 && tbl.kind!=para) || (tbl.type!=inum && tbl.type!=cha))
{
pl0Compiler->errors->addError(37);//for后应为整形变量
}
else
{
int l = tbl.level;
int a = tbl.address;
Symbol type = tbl.type;
getSymbol();
if(token.first==equsy || token.first==assignsy)
{
if(token.first==equsy)
{
pl0Compiler->errors->addError(51);//应为赋值符号
}
else
{
getSymbol();
set1+=tosy;
Symbol tempType = expression(set1);
set1-=tosy;
pl0Compiler->ccode->gen(STO,lev-l,a);
if(tempType > type)
{
if(tempType != inum)
pl0Compiler->errors->addError(52);
}
if(token.first==tosy)
{
getSymbol();
int cx1 = pl0Compiler->ccode->getTopIndex()+1;
set1+=dosy;
expression(set1);
set1-=dosy;
pl0Compiler->ccode->gen(LODI,lev-l,a);
pl0Compiler->ccode->gen(GRTEQ,0,0);
pl0Compiler->ccode->gen(JPC,0,0);
int cx2 = pl0Compiler->ccode->getTopIndex();
if(token.first==dosy)
{
getSymbol();
set1+= endsy;set1+=semicolonsy;
stament(set1);
pl0Compiler->ccode->gen(LODI,lev-l,a);
pl0Compiler->ccode->gen(LITI,0,1);
pl0Compiler->ccode->gen(ADD, 0, 0);
pl0Compiler->ccode->gen(STO,lev-l,a);
pl0Compiler->ccode->gen(JMP, 0, cx1);
pl0Compiler->ccode->setAdr(cx2,pl0Compiler->ccode->getTopIndex()+1);
}
else
{
pl0Compiler->errors->addError(39);
}
}
else
{
pl0Compiler->errors->addError(38);//缺少to
}
}
}
else
{
pl0Compiler->errors->addError(12);//标识符后应为:=
}
}
}
}
else
{
pl0Compiler->errors->addError(37);//for后应为标识符
}
}
void GramAnalyze::ifFunc(SymSet set1)
{
set1+=thensy;
condition(set1);
set1-=thensy;
pl0Compiler->ccode->gen(JPC,0,0);
int cx1 = pl0Compiler->ccode->getTopIndex();
if(token.first==thensy)
{
getSymbol();
set1+=elsesy;
stament(set1);
set1-=elsesy;
}
else
pl0Compiler->errors->addError(40);
//SymSet tempSet1= set1;
//tempSet1+=statBegSys;
//tempSet1+=elsesy;
//test(tempSet1, set1,35);
if(token.first==elsesy)
{
pl0Compiler->ccode->gen(JMP,0,0);
int cx2 = pl0Compiler->ccode->getTopIndex();
pl0Compiler->ccode->setAdr(cx1,cx2+1);
set1+=endsy;set1+=semicolonsy;
getSymbol();
stament(set1);
pl0Compiler->ccode->setAdr(cx2,pl0Compiler->ccode->getTopIndex()+1);
}
else
{
pl0Compiler->ccode->setAdr(cx1,pl0Compiler->ccode->getTopIndex()+1);
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?