📄 statement.cpp
字号:
#include "Global.h"
using namespace std;
void PL0::Factor(SYMSET fsys,ITEM &x,int lev)
{
int i;
x.typ=notyp;
x.ref=0;
Test(facbegsys,fsys,"因子必须以标志符,常量或'('开始");
while(facbegsys.find(sym)!=facbegsys.end())
{
if(sym==IDENT)
{
i=Position(id,lev);
Getsym();
if(i==0)
Error("变量不存在或不可引用",linecount);
switch(table[i].kind)
{
case CONSTANT:
x.typ=table[i].type;
x.ref=0;
//if(x.typ==reals)
Gen(Lit,(float)(lev-table[i].level),(float)table[i].val);
break;
case VARIABLE:
x.typ=table[i].type;
x.ref=0;
Gen(Lod,lev-table[i].level,table[i].adr);
break;
case PROCEDURE:
Error("过程名不能成为因子",linecount);
break;
case FUNCTION:
x.typ=table[i].type;
ret=true;
Call(fsys,i,lev);
}
}
else
if(sym==INUM||sym==RNUM||sym==CNUM)
{
if(sym==RNUM)
{
x.typ=reals;
Gen(Lit,0,num);
Getsym();
}
else
{
x.typ=ints;
Gen(Lit,0,num);
Getsym();
}
x.ref=0;
}
else
if(sym==LPAREN)
{
Getsym();
SYMSET temp;
temp=fsys;
temp.insert(RPAREN);
Expression(temp,x,lev);
if(sym==RPAREN)
Getsym();
else
Error("缺少右括号",linecount);
}
Test(fsys,facbegsys,"因子后不可为此符号");
}
}
void PL0::Call(SYMSET fsys,int i,int lev)
{
ITEM x;
x.typ=notyp;
x.ref=-1;
int lastp,cp,k;
lastp=btab[table[i].ref].lastpar;
cp=i;
if(sym==LPAREN)
{
do
{
Getsym();
if(cp>=lastp)
Error("实参个数与形参个数不等",linecount);
else
{
cp++;
SYMSET temp;
temp=fsys;
temp.insert(COMMA);
temp.insert(COLON);
temp.insert(RPAREN);
Expression(temp,x,lev);
if(x.typ<table[cp].type)
Warning("形参实参类型不符,运算可能导致精度损失",linecount);
Gen(Stof,0,table[cp].adr);
}
SYMSET temp;
temp.insert(COMMA);
temp.insert(RPAREN);
Test(temp,fsys,"编译将跳一些非法符号符号");
}while(sym==COMMA);
//Getsym();
if(sym==RPAREN)
Getsym();
else Error("缺少右括号",linecount);
}
Gen(Cal,0,table[i].adr);
if(ret)
Gen(Opr,0,16);
}
void PL0::Term(SYMSET fsys,ITEM &x,int lev)
{
ITEM y;
SYMBOL op;
SYMSET temp1;
temp1=fsys;
temp1.insert(TIMES);
temp1.insert(SLASH);
Factor(temp1,x,lev);
while(sym==TIMES||sym==SLASH)
{
op=sym;
Getsym();
//SYMSET temp2;
//temp2=temp1;
//temp2.insert(TIMES);
//temp2.insert(SLASH);
Factor(temp1,y,lev);
if(op==TIMES)
{
x.typ=Resulttype(x.typ,y.typ);
if(x.typ==reals)
Gen(Opr,0,4);
else
Gen(Opr,0,6);
}
else
if(op==SLASH)
{
x.typ=Resulttype(x.typ,y.typ);
if(x.typ==reals)
Gen(Opr,0,5);
else
Gen(Opr,0,7);
}
}
}
void PL0::Expression(SYMSET fsys,ITEM &x,int lev)
{
ITEM y;
SYMBOL op;
SYMSET temp;
temp=fsys;
temp.insert(PLUS);
temp.insert(MINUS);
if(sym==PLUS||sym==MINUS)
{
op=sym;
Getsym();
Term(temp,x,lev);
if(op==MINUS)
{
Gen(Opr,0,1);//生成一条1号操作指令:取反运算
}
}
else
{
Term(temp,x,lev);
}
while(sym==PLUS||sym==MINUS)
{
op=sym;
Getsym();
Term(temp,y,lev);
x.typ=Resulttype(x.typ,y.typ);
if(op==PLUS)
{
if(x.typ==reals)
Gen(Opr,0,2);
else
Gen(Opr,0,8);
}
else
{
if(x.typ==reals)
Gen(Opr,0,3);
else
Gen(Opr,0,9);
}
}
}
void PL0:: Condition(SYMSET fsys,ITEM &x,int lev)
{
ITEM y;
SYMBOL relop;
SYMSET temp1,temp2;
temp1.insert(EQL),temp1.insert(NEQ),temp1.insert(LSS),temp1.insert(GTR),temp1.insert(LEQ),temp1.insert(GEQ);
temp2=temp1;
for(SYMSET::iterator it=fsys.begin();it!=fsys.end();it++)
temp1.insert(*it);
if(sym==ODDSYM)
{
Getsym();
Expression(fsys,x,lev);
Gen(Opr,0,6);
}
else
{
//Getsym();
Expression(temp1,x,lev);
if(temp2.find(sym)==temp2.end())
{
Error("应为关系运算符",linecount);
}
else
{
relop=sym;
Getsym();
Expression(fsys,y,lev);
//cout<<"if语句中左边表达式类型为......."<<x.typ<<endl;
//cout<<"if语句中右边表达式类型为......."<<y.typ<<endl;
switch(relop)
{
case EQL:
Gen(Opr,0,10);
break;
case NEQ:
Gen(Opr,0,11);
break;
case LSS://小于等于
Gen(Opr,0,14);
break;
case GEQ://大于
Gen(Opr,0,13);
break;
case GTR://大于等于
Gen(Opr,0,15);
break;
case LEQ://小于
Gen(Opr,0,12);
break;
}
}
}
}
void PL0::Listcode()
{
for(int i=0;i<cx;i++)
cout<<i<<setw(5)<<fctmap[code[i].f]<<setw(5)<<code[i].l<<setw(5)<<code[i].a<<endl;
}
TYP PL0::Resulttype(TYP a,TYP b)
{
if(a==chars)
{
return b;
}
if(a==ints)
{
if(b==reals)
return b;
else
return ints;
}
if(a==reals)
return a;
}
void PL0::Assignment(SYMSET fsys,int lv,int ad,int i)
{
ITEM x,y;
int f;
x.typ=table[i].type;
x.ref=table[i].ref;
y.typ=notyp;
y.ref=-1;
if(sym==BECOMES)
Getsym();
else
{
Warning("应该为赋值号:':='",linecount);
if(sym==EQL)
Getsym();
}
Expression(fsys,y,lv);
//cout<<y.typ<<"********************"<<y.ref<<endl;
switch(table[i].kind)
{
case FUNCTION:
Gen(Fun,0,3);
break;
case VARIABLE:
{
if(x.typ>=y.typ)
Gen(Sto,lv-table[i].level,table[i].adr);
else
{
Warning("赋值可能会导致精度丢失",linecount);
if(y.typ==reals)
Gen(Stoi,lv-table[i].level,table[i].adr);
else
Gen(Sto,lv-table[i].level,table[i].adr);
}
}
break;
}
}
void PL0::Compoundstatement(SYMSET fsys,int lev)
{
Getsym();
SYMSET temp;
temp=fsys;
temp.insert(ENDSYM);
temp.insert(SEMICOLON);
Statement(temp,lev);
SYMSET temp1;
temp1=statbegsys;
temp1.insert(SEMICOLON);
while(temp1.find(sym)!=temp1.end())
{
if(sym==SEMICOLON)
Getsym();
else
Error("缺少分号:';'",linecount);
Statement(temp,lev);
}
if(sym==ENDSYM)
Getsym();
else
Error("缺少关键字:'end'",linecount);
}
void PL0::Statement(SYMSET fsys,int lev)
{
int i;
float value;
ITEM x;
x.typ=notyp;
x.ref=0;
SYMSET temp;
temp=statbegsys;
temp.insert(IDENT);
if(temp.find(sym)!=temp.end())
{
switch(sym)
{
case IDENT:
i=Position(id,lev);
Getsym();
if(i!=0)
{
switch(table[i].kind)
{
case CONSTANT:
Error("应是变量,过程/函数名",linecount);
break;
case VARIABLE:
//Assignment(fsys,table[i].level,table[i].adr,i);
Assignment(fsys,lev,table[i].adr,i);
break;
//case PARAMETER:
//Assignment(fsys,lev,table[i].adr,i);
//break;
case PROCEDURE:
if(table[i].level!=0)
Call(fsys,i,lev);
else
Error("函数名定义有错误,请检查",linecount);
break;
case FUNCTION:
if(table[i].ref==DISPLAY[lev])
Assignment(fsys,table[i].level+1,0,i);
else
Error("应是变量,过程/函数名",linecount);
break;
}
}
else
Error("变量不存在或不可引用",linecount);
break;
case BEGINSYM:
Compoundstatement(fsys,lev);
break;
case IFSYM:
{
int lc1,lc2;
ITEM x;
x.typ=notyp;
x.ref=-1;
SYMSET temp,temp1;
temp=fsys;
temp.insert(THENSYM);
//temp.insert(DOSYM);
Getsym();
Condition(temp,x,lev);
if(x.typ==notyp)
Error("if语句中的判断表达式错误",linecount);
if(sym==THENSYM)
Getsym();
else
{
Error("缺少关键字:then",linecount);
}
lc1=cx,Gen(Jpc,0,0);
cout<<"then语句处理前cx="<<lc1<<endl;
temp1=fsys;
temp1.insert(ELSESYM);
Statement(temp1,lev);
Getsym();
//code[lc1].a=cx;
if(sym==ELSESYM)
{
Getsym();
lc2=cx;
cout<<"else语句处理前cx="<<lc2<<endl;
Gen(Jmp,0,0);
code[lc1].a=cx;
Statement(fsys,lev);
code[lc2].a=cx;
}
else
code[lc1].a=cx;
}
break;
case WHILESYM:
{
ITEM x;
x.typ=notyp;
x.ref=-1;
int lc1,lc2;
SYMSET temp;
Getsym();
lc1=cx;
temp=fsys;
temp.insert(DOSYM);
Condition(temp,x,lev);
lc2=cx;
Gen(Jpc,0,0);
if(sym==DOSYM)
Getsym();
else
Error("缺少关键字:do",linecount);
Statement(fsys,lev);
Gen(Jmp,0,lc1);
code[lc2].a=cx;
}
break;
case FORSYM:
{
TYP tp;
FCT f;
ITEM x;
x.typ=notyp;
x.ref=-1;
int i,lc1,lc2;
Getsym();
if(sym==IDENT)
{
i=Position(id,lev);
Getsym();
if(i==0)
Error("变量不存在,或不可引用",linecount);
else if(table[i].kind==VARIABLE)
{
tp=table[i].type;
Gen(Loda,lev-table[i].level,table[i].adr);
}
else
Error("标识符类型错误",linecount);
}
else
{
Error("for语句中应为标识符",linecount);
SYMSET temp=fsys;
temp.insert(BECOMES),temp.insert(TOSYM),temp.insert(DOWNTOSYM),temp.insert(DOSYM);
while(temp.find(sym)==temp.end())
Getsym();
}
if(sym==BECOMES)
{
SYMSET temp=fsys;
temp.insert(TOSYM),temp.insert(DOWNTOSYM),temp.insert(DOSYM);
Getsym();
Expression(temp,x,lev);
if(x.typ!=tp)
Warning("赋值可能会导致精度丢失",linecount);
}
else
{
Error("应为赋值符号:':='",linecount);
SYMSET temp=fsys;
temp.insert(TOSYM),temp.insert(DOWNTOSYM),temp.insert(DOSYM);
while(temp.find(sym)==temp.end())
Getsym();
}
f=F1U;//增量步长型for循环体入口测试
if(sym==TOSYM||sym==DOWNTOSYM)
{
if(sym==DOWNTOSYM)
f=F1D;//减量步长型for循环体入口测试
Getsym();
SYMSET temp=fsys;
temp.insert(DOSYM);
Expression(temp,x,lev);
if(x.typ!=tp)
Warning("赋值可能会导致精度丢失",linecount);
}
else
{
Error("应为:to或是downto",linecount);
SYMSET temp=fsys;
temp.insert(DOSYM);
while(temp.find(sym)==temp.end())
Getsym();
}
lc1=cx;
Gen(F1U,0,0);
if(sym==DOSYM)
Getsym();
else
Error("缺少关键字:do",linecount);
lc2=cx;
Statement(fsys,lev);
if(f==F1U)
Gen(F2U,0,lc2);
else
Gen(F2D,0,lc2);
code[lc1].a=cx;
}
break;
case READSYM:
{
Getsym();
if(sym==LPAREN)
{
do
{
Getsym();
if(sym!=IDENT)
Error("应该是变量标志符",linecount);
i=Position(id,lev);
if(i!=0)
{
if(table[i].kind==VARIABLE)
{
x.typ=table[i].type;
x.ref=table[i].ref;
//Gen(Loda,lev-table[i].level,table[i].adr);
Gen(Red,lev-table[i].level,table[i].adr);
Getsym();
}
else
Error("应该是变量",linecount);
}
else
Error("变量不存在或不可引用",linecount);
}while(sym==COMMA);
if(sym==RPAREN)
Getsym();
else
Error("缺少右括号:')'",linecount);
}
else
{
Error("缺少左括号:'('",linecount);
}
}
break;
case REPEAT:
{
ITEM x;
int lc1;
SYMSET temp1,temp2;
temp1=fsys,temp1.insert(SEMICOLON),temp1.insert(UNTIL);
x.typ=notyp,x.ref=0,lc1=cx;
Getsym();
Statement(temp1,lev);
temp2=statbegsys;
temp2.insert(SEMICOLON);
while(temp2.find(sym)!=temp2.end())
{
if(sym==SEMICOLON)
Getsym();
else
Error("缺少分号",linecount);
Statement(temp1,lev);
}
if(sym==UNTIL)
{
Getsym();
Condition(fsys,x,lev);
Gen(Jpc,0,lc1);
}
else
Error("缺少关键字:until",linecount);
}
break;
case WRITESYM:
{
Getsym();
if(sym==LPAREN)
{
do
{
Getsym();
if(sym==STRING)
{
Gen(Wrts,sentry,sleng);
sentry=sleng+sentry;
Getsym();
}
else
{
SYMSET temp;
temp=fsys;
temp.insert(RPAREN);
Expression(temp,x,lev);
Gen(Wrt,0.0f,0.0f);
}
}while(sym==COMMA);
if(sym!=RPAREN)
Error("write后缺少右括号:')'",linecount);
Getsym();
}
else
{
Error("write后缺少左括号:'('",linecount);
Getsym();
}
}
break;
}
}
SYMSET kong;
Test(fsys,kong,"应该是分号:';'");
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -