📄 yufa.cpp
字号:
#include "yufa.h"
#include "errors.h"
#include "cifa.h"
#include "biaoge.h"
#include "daima.h"
CYufa::CYufa(CPlCompiler *p)
{
pl=p;
declbegsys+=constsym;
declbegsys+=varsym;
declbegsys+=procsym;
statbegsys+=beginsym;
statbegsys+=callsym;
statbegsys+=ifsym;
statbegsys+=whilesym;
statbegsys+=repeatsym;
facbegsys+=ident;
facbegsys+=number;
facbegsys+=lparen;
}
void CYufa::Analysis()
{
getsym();
lev=-1;
CSymbolSet s;
s=declbegsys;
s+=statbegsys;
s+=period;
block(s);
}
void CYufa::test(CSymbolSet s1,CSymbolSet s2,int n)
{
if (!s1.InSet(sym))
{
pl->errors->Add(n);
s1+=s2;
while (!s1.InSet(sym)) getsym();
}
}
void CYufa::block(CSymbolSet fsys)
{
lev++;
int tx0,cx0;
CSymbolSet s;
CErrors *err=pl->errors;
CDaima *dm=pl->daima;
CBiaoge *bg=pl->biaoge;
dx[lev]=3;
tx0=bg->TableIndex();
bg->table[tx0].adr=dm->cx;
dm->Gen(jmp,0,0);
if (lev>MAX_LEVEL) err->Add(32);
do{
if (sym==constsym)
{
getsym();
do{
constdeclaration();
while (sym==comma)
{
getsym();
constdeclaration();
}
if (sym==semicolon) getsym(); else err->Add(5);
}while (sym==ident);
}
if (sym==varsym)
{
getsym();
do{
vardeclaration();
while (sym==comma)
{
getsym();
vardeclaration();
}
if (sym==semicolon) getsym(); else err->Add(5);
}while (sym==ident);
}
while (sym==procsym)
{
getsym();
if (sym==ident)
{
bg->Enter(procedure);
getsym();
}
else err->Add(4);
if (sym==semicolon) getsym(); else err->Add(5);
s=fsys;
s+=semicolon;
block(s);
if (sym==semicolon)
{
getsym();
s=statbegsys;
s+=ident;
s+=procsym;
test(s,fsys,6);
}
else
err->Add(5);
}
s=statbegsys;
s+=ident;
test(s,declbegsys,7);
}while (declbegsys.InSet(sym));
dm->code[bg->table[tx0].adr].a=dm->cx;
bg->table[tx0].adr=dm->cx;
bg->table[tx0].size=dx[lev];
cx0=dm->cx;
dm->Gen(intint,0,dx[lev]);
s=fsys;
s+=semicolon;
s+=endsym;
statement(s);
dm->Gen(opr,0,0);
test(fsys,CSymbolSet(),8);
lev--;
}
void CYufa::constdeclaration()
{
CErrors *err=pl->errors;
CBiaoge *bg=pl->biaoge;
if (sym==ident)
{
getsym();
if (sym==eql || sym==becomes)
{
if (sym==becomes)
err->Add(1);
getsym();
if (sym==number)
{
bg->Enter(constant);
getsym();
}
else
err->Add(2);
}
else
err->Add(3);
}
else
err->Add(4);
}
void CYufa::vardeclaration()
{
CErrors *err=pl->errors;
CDaima *dm=pl->daima;
CBiaoge *bg=pl->biaoge;
if (sym==ident)
{
bg->Enter(variable);
dx[lev]++;
getsym();
}
else
err->Add(4);
}
void CYufa::factor(CSymbolSet fsys)
{
int i;
CErrors *err=pl->errors;
table_type *table=pl->biaoge->table;
CDaima *dm=pl->daima;
test(facbegsys,fsys,24);
while (facbegsys.InSet(sym))
{
switch (sym)
{
case ident:
i=pl->biaoge->Position(pl->cifa->id);
if (i==0)
err->Add(11);
else
{
switch (table[i].kind)
{
case constant:
dm->Gen(lit,0,table[i].val);
break;
case variable:
dm->Gen(lod,lev-table[i].level,table[i].adr);
break;
case procedure:
err->Add(21);
break;
}
}
getsym();
break;
case number:
if (pl->cifa->num>MAX_NUMBER)
{
err->Add(31);
pl->cifa->num=0;
}
dm->Gen(lit,0,pl->cifa->num);
getsym();
break;
case lparen:
getsym();
expression(fsys+=rparen);
if (sym==rparen)
getsym();
else
err->Add(22);
break;
}
test(fsys,facbegsys,23);
}
}
void CYufa::term(CSymbolSet fsys)
{
symbol mulop;
CSymbolSet symset;
symset+=fsys;
symset+=times;
symset+=slash;
factor(symset);
while (sym==times||sym==slash)
{
mulop=sym;
getsym();
factor(symset);
if (mulop==times)
pl->daima->Gen(opr,0,4);
else
pl->daima->Gen(opr,0,5);
}
}
void CYufa::expression(CSymbolSet fsys)
{
symbol addop;
CSymbolSet symset;
symset+=fsys;
symset+=plus;
symset+=minus;
if (sym==plus||sym==minus)
{
addop=sym;
getsym();
term(symset);
if (addop==minus)
pl->daima->Gen(opr,0,1);
}
else
term(symset);
while (sym==plus||sym==minus)
{
addop=sym;
getsym();
term(symset);
if (addop==plus)
pl->daima->Gen(opr,0,2);
else
pl->daima->Gen(opr,0,3);
}
}
void CYufa::condition(CSymbolSet fsys)
{
symbol relop;
CSymbolSet s1,s2;
s1+=eql;
s1+=neq;
s1+=lss;
s1+=leq;
s1+=gtr;
s1+=geq;
if (sym==oddsym)
{
getsym();
expression(fsys);
pl->daima->Gen(opr,0,6);
}
else
{
s2+=s1;
expression(s2+=fsys);
if (!s1.InSet(sym))
pl->errors->Add(20);
else
{
relop=sym;
getsym();
expression(fsys);
switch (relop)
{
case eql:pl->daima->Gen(opr,0,8);break;
case neq:pl->daima->Gen(opr,0,9);break;
case lss:pl->daima->Gen(opr,0,10);break;
case geq:pl->daima->Gen(opr,0,11);break;
case gtr:pl->daima->Gen(opr,0,12);break;
case leq:pl->daima->Gen(opr,0,13);break;
}
}
}
}
void CYufa::statement(CSymbolSet fsys)
{
int i,cx1,cx2;
table_type *table=pl->biaoge->table;
CErrors *err=pl->errors;
CDaima *dm=pl->daima;
CSymbolSet s,s2;
switch (sym)
{
case ident:
i=pl->biaoge->Position(pl->cifa->id);
if (i==0)
err->Add(11);
else if (table[i].kind!=variable)
{err->Add(12);i=0;}
getsym();
if (sym==becomes)
getsym();
else
err->Add(13);
expression(fsys);
if (i>0)
dm->Gen(sto,lev-table[i].level,table[i].adr);
break;
case readsym:
getsym();
if (sym!=lparen)
err->Add(34);
else
do{
getsym();
i=(sym==ident) ? pl->biaoge->Position(pl->cifa->id):0;
if (i==0)
err->Add(35);
else
{
dm->Gen(opr,0,16);
dm->Gen(sto,lev-table[i].level,table[i].adr);
}
getsym();
}while (sym==comma);
if (sym!=rparen)
{
err->Add(33);
while (fsys.InSet(sym)) getsym();
}
else getsym();
break;
case writesym:
s=fsys;
s+=rparen;
s+=comma;
getsym();
if (sym==lparen)
{
do{
getsym();
expression(s);
pl->daima->Gen(opr,0,14);
}while (sym==comma);
if (sym!=rparen)
err->Add(33);
else
getsym();
}
dm->Gen(opr,0,15);
break;
case callsym:
getsym();
if (sym!=ident)
err->Add(14);
else
{
i=pl->biaoge->Position(pl->cifa->id);
if (i==0) err->Add(11);
else if (table[i].kind==procedure)
dm->Gen(cal,lev-table[i].level,table[i].adr);
else
err->Add(15);
getsym();
}
break;
case ifsym:
s=fsys;
s+=thensym;
s+=dosym;
getsym();
condition(s);
if (sym==thensym) getsym();else err->Add(16);
cx1=dm->cx;
dm->Gen(jpc,0,0);
s=fsys;
s+=elsesym;
statement(s);
if (sym==elsesym)
{
getsym();
cx2=dm->cx;
dm->Gen(jmp,0,0);
statement(fsys);
dm->code[cx1].a=cx2+1;
dm->code[cx2].a=dm->cx;
}
else
dm->code[cx1].a=dm->cx;
break;
case beginsym:
s=fsys;
s+=semicolon;
s+=endsym;
s2=statbegsys;
s2+=semicolon;
getsym();
statement(s);
while (s2.InSet(sym))
{
if (sym==semicolon) getsym();else err->Add(10);
statement(s);
}
if (sym==endsym) getsym(); else err->Add(17);
break;
case whilesym:
cx1=dm->cx;
getsym();
s=fsys;
s+=dosym;
condition(s);
cx2=dm->cx;
dm->Gen(jpc,0,0);
if (sym==dosym) getsym(); else err->Add(18);
statement(fsys);
dm->Gen(jmp,0,cx1);
dm->code[cx2].a=dm->cx;
break;
case repeatsym:
getsym();
s=fsys;
s+=semicolon;
s+=untilsym;
cx1=dm->cx;
statement(s);
s2=statbegsys;
s2+=semicolon;
while (s2.InSet(sym))
{
if (sym==semicolon) getsym();else err->Add(10);
statement(s);
}
if (sym==untilsym)
{
getsym();
condition(fsys);
dm->Gen(jpc,0,cx1);
}
else
err->Add(25);
break;
}
test(fsys,CSymbolSet(),19);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -