📄 pl0parser.cpp
字号:
match(ASSIGNOP);
expression();
code.gen("sto",curLev-table[n].level,table[n].val);
while(tokKind==END || tokKind==SEMICOLON || tokKind==DOT)
return;
//赋值语句非法结束,可能表达式出现错误
switch(tokKind)
{
case RPAREN:
error("表达式缺少“(”!");
match(RPAREN);
//由FT'E'开始推导,且已匹配了F
errExp();
break;
case LPAREN:
case VARIABLE:
case NUMBER:
error("表达式缺少运算符!");
//添加一个运算符,由FT'E'开始推导
expression();
break;
default:
error("表达式错,原因不知道!");
while(tokKind!=SEMICOLON && tokKind!=END && tokKind!=DOT)
match(tokKind);
}
}
void CPl0Parser::callWord()
{
match(CALL);
int n=tokVal;
match(PROCEDURE);
int t=code.gen("call",curLev-table[n].level,table[n].val);
if(table[n].size==-1)
table[n].val=t;
}
void CPl0Parser::beginWord()
{
match(BEGIN);
word();
while(tokKind==SEMICOLON)
{
match(SEMICOLON);
word();
}
match(END);
}
void CPl0Parser::ifWord()
{
match(IF);
condition();
int n=code.gen("jf",0,0);
if(tokKind!=THEN)
{
while(1)
{
switch(tokKind)
{
case THEN:
error("条件表达式错!");
match(THEN);
break;
case ASSIGNOP:
back();
tokKind=VARIABLE;
case BEGIN:
case IF:
case WHILE:
case READ:
case WRITE:
error("条件语句缺少then!");
break;
case SEMICOLON:
case END:
case DOT:
error("条件语句错!");
return;
default:
match(tokKind);
continue;
}
break;
}
}
else
match(THEN);
word();
code.modify(n);
}
void CPl0Parser::whileWord()
{
match(WHILE);
int n=code.getCodeAddr();
condition();
int m=code.gen("jf",0,0);
if(tokKind!=DO)
{
while(1)
{
switch(tokKind)
{
case DO:
error("条件表达式错!");
match(DO);
break;
case ASSIGNOP:
back();
tokKind=VARIABLE;
case BEGIN:
case IF:
case WHILE:
case READ:
case WRITE:
error("循环语句缺少do!");
break;
case SEMICOLON:
case END:
case DOT:
error("循环语句错!");
return;
default:
match(tokKind);
continue;
}
break;
}
}
else
match(DO);
word();
code.gen("j",0,n);
code.modify(m);
}
void CPl0Parser::readWord()
{
match(READ);
match(LPAREN);
code.gen("opr",0,16);
code.gen("sto",curLev-table[tokVal].level,table[tokVal].val);
match(VARIABLE);
while(tokKind==COMMA)
{
match(COMMA);
code.gen("opr",0,16);
code.gen("sto",curLev-table[tokVal].level,table[tokVal].val);
match(VARIABLE);
}
if(tokKind!=RPAREN)
{
error("read语句错");
while(tokKind!=RPAREN && tokKind!=SEMICOLON)
match(tokKind);
}
if(tokKind==RPAREN)
match(RPAREN);
}
void CPl0Parser::writeWord()
{
match(WRITE);
match(LPAREN);
expression();
code.gen("opr",0,14);
while(tokKind==COMMA)
{
match(COMMA);
expression();
code.gen("opr",0,14);
}
if(tokKind!=RPAREN)
{
error("write语句错误!");
while(tokKind!=RPAREN && tokKind!=SEMICOLON)
match(tokKind);
}
if(tokKind==RPAREN)
match(RPAREN);
code.gen("opr",0,15);
while(tokKind!=SEMICOLON && tokKind!=END && tokKind!=DOT)
match(tokKind);
}
int CPl0Code::gen(char code[],int lev,int addr)
{
strcpy(codes[curCodePosition].code,code);
codes[curCodePosition].level=lev;
codes[curCodePosition].addr=addr;
return curCodePosition++;
}
void CPl0Code::intit(CPl0Parser *p)
{
this->pParser=p;
curCodePosition=0;
}
void CPl0Code::modify(int pos)
{
codes[pos].addr=curCodePosition;
}
void CPl0Code::modify(int pos,int tg)
{
codes[pos].addr=tg;
}
int CPl0Code::getCodeAddr()
{
return curCodePosition;
}
void CPl0Parser::errExp()
{
while(tokKind==MULTOP || tokKind==DIVOP)
{
match(tokKind);
factor();
}
while(tokKind==PLUSOP || tokKind==MINUSOP)
{
match(tokKind);
term();
}
}
void CPl0Parser::expression()
{
int mbool=0;
switch(tokKind)
{
case MINUSOP:
mbool=1;
match(MINUSOP);break;
case PLUSOP:
match(PLUSOP);
break;
}
term();
while(1)
{
switch(tokKind)
{
case PLUSOP:
match(PLUSOP);
term();
code.gen("opr",0,2);
continue;
case MINUSOP:
match(MINUSOP);
term();
code.gen("opr",0,3);
continue;
default:
break;
}
break;
}
if(mbool)
code.gen("opr",0,1);
}
void CPl0Parser::term()
{
factor();
while(1)
{
switch(tokKind)
{
case MULTOP:
match(MULTOP);
factor();
code.gen("opr",0,4);
continue;
case DIVOP:
match(DIVOP);
factor();
code.gen("opr",0,5);
continue;
default:
break;
}
break;
}
}
void CPl0Parser::factor()
{
switch(tokKind)
{
case VARIABLE:
code.gen("lod",curLev-table[tokVal].level,table[tokVal].val);
match(VARIABLE);
break;
case NUMBER:
code.gen("lit",0,tokVal);
match(NUMBER);
break;
case CONSTANT:
code.gen("lit",0,table[tokVal].val);
match(CONSTANT);
break;
case LPAREN:
match(LPAREN);
expression();
match(RPAREN);
break;
case IDENT:
error("变量未定义!");
match(tokKind);
break;
default:
error("缺少运算数!");
}
}
void CPl0Parser::condition()
{
if(tokKind==ODD)
{
match(ODD);
expression();
code.gen("opr",0,6);
}
else
{
expression();
switch(tokKind)
{
case EQ:
match(EQ);
expression();
code.gen("opr",0,8);
break;
case NE:
match(NE);
expression();
code.gen("opr",0,9);
break;
case GT:
match(GT);
expression();
code.gen("opr",0,12);
break;
case GE:
match(GE);
expression();
code.gen("opr",0,11);
break;
case LT:
match(LT);
expression();
code.gen("opr",0,10);
break;
case LE:
match(LE);
expression();
code.gen("opr",0,13);
break;
default:
error(ROP);
}
}
}
void CPl0Parser::getCode(CString &cds)
{
if(errStr.GetLength())
{
cds="";
return;
}
code.getCode(cds);
}
void CPl0Code::getCode(CString &cds)
{
char buff[81];
cds="";
for(int i=0;i<this->curCodePosition;i++)
{
sprintf(buff,"%5d %5s%5d%5d\n",i,codes[i].code,codes[i].level,codes[i].addr);
cds+=buff;
}
}
void CPl0Execute::init(CPl0Code *p)
{
this->pCode=p;
}
void CPl0Execute::Execute()
{
sp=-1;IP=0;BX=0;b=1;
CodeStruc *pCD;
OutPut="";
InPut="";
pInPos=InPut;
stack[0]=0;
stack[1]=0;
stack[2]=0;
while(b)
{
if(IP==20)
IP=IP;
pCD=pCode->codes+IP++;
if(strcmp(pCD->code,"lit")==0)
LIT(pCD->addr);
else if(strcmp(pCD->code,"lod")==0)
LOD(pCD->level,pCD->addr);
else if(strcmp(pCD->code,"sto")==0)
STO(pCD->level,pCD->addr);
else if(strcmp(pCD->code,"call")==0)
CALL(pCD->level,pCD->addr);
else if(strcmp(pCD->code,"int")==0)
INT(pCD->addr);
else if(strcmp(pCD->code,"j")==0)
JMP(pCD->addr);
else if(strcmp(pCD->code,"jf")==0)
JPC(pCD->addr);
else if(strcmp(pCD->code,"opr")==0)
OPR(pCD->addr);
}
MessageBox(0,OutPut,"运算结果",0);
}
void CPl0Execute::LIT(int a)
{
stack[++sp]=a;
}
void CPl0Execute::LOD(int l,int a)
{
int sl=BX;
while(l-->0)
sl=stack[sl];
stack[++sp]=stack[sl+a];
}
void CPl0Execute::STO(int l,int a)
{
int sl=BX;
while(l-->0)
sl=stack[sl];
stack[sl+a]=stack[sp--];
}
void CPl0Execute::CALL(int l,int a)
{
int sl=BX;
while(l-->0)
sl=stack[sl];
stack[sp+1]=sl;
stack[sp+2]=BX;
stack[sp+3]=IP;
IP=a;
BX=sp+1;
}
void CPl0Execute::INT(int a)
{
sp+=a;
}
void CPl0Execute::JMP(int a)
{
IP=a;
}
void CPl0Execute::JPC(int a)
{
if(stack[sp--]==0)
IP=a;
}
void CPl0Execute::OPR(int a)
{
char buf[80];
const char *p;
switch(a)
{
case 0:
if(stack[BX+2]==0)
{
b=0;
break;
}
IP=stack[BX+2];
sp=BX-1;
BX=stack[sp+2];
break;
case 1:
stack[sp]=-stack[sp];
break;
case 2:
stack[sp-1]+=stack[sp];
sp--;
break;
case 3:
stack[sp-1]-=stack[sp];
sp--;
break;
case 4:
stack[sp-1]*=stack[sp];
sp--;
break;
case 5:
stack[sp-1]/=stack[sp];
sp--;
break;
case 6:
stack[sp]=stack[sp]%2;
break;
case 8:
stack[sp-1]=stack[sp-1]==stack[sp];
sp--;
break;
case 9:
stack[sp-1]=stack[sp-1]!=stack[sp];
sp--;
break;
case 10:
stack[sp-1]=stack[sp-1]<stack[sp];
sp--;
break;
case 11:
stack[sp-1]=stack[sp-1]>=stack[sp];
sp--;
break;
case 12:
stack[sp-1]=stack[sp-1]>stack[sp];
sp--;
break;
case 13:
stack[sp-1]=stack[sp-1]<=stack[sp];
sp--;
break;
case 14:
sprintf(buf,"%d ",stack[sp--]);
OutPut+=buf;
break;
case 15:
sprintf(buf,"\n");
OutPut+=buf;
break;
case 16:
while(*(p=pInPos) && *p==' ') pInPos++;
while(*pInPos && isdigit(*pInPos))
pInPos++;
if(p==pInPos)
{
CInputData inDlg;
if(inDlg.DoModal()==IDOK)
{
InPut=inDlg.m_data;
pInPos=InPut;
}
while(*(p=pInPos) && *p==' ') pInPos++;
while(*pInPos && isdigit(*pInPos))
pInPos++;
}
stack[++sp]=atoi(p);
break;
}
}
void CPl0Parser::Execute(const char *p)
{
pl0(p);
CPl0Execute exe;
exe.init(&code);
exe.Execute();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -