📄 pl0dlg.cpp
字号:
}
getsymdo;
}
else
{
error(48,line);
}
break;
case decsym: /*处理形如--b的语句*/
getsymdo;
if(sym==ident)
{
i=position(id,*ptx);
if(i==0)
{
error(11,line);
}
else
{
if(table[i].kind==variable)
{
gendo(lod,lev-table[i].level,table[i].adr);
gendo(lit,0,1);
gendo(opr,0,3);
gendo(sto,lev-table[i].level,table[i].adr);
}
else
{
error(48,line);
}
}
getsymdo;
}
else
{
error(48,line);
}
break;
case ident: /*准备按照表达式语句处理*/
i=position(id,*ptx);
if(i==0)
{
error(11,line);
}
else
{
if(table[i].kind==variable || table[i].kind==array)
{
if(table[i].kind==array) /*标识符是数组*/
{
getsymdo;
if(sym==lepa) /*数组的[*/
{
getsymdo;
memcpy(nxtlev,fsys,sizeof(bool)* symnum);
nxtlev[ripa]=true;
expressiondo(nxtlev,ptx,lev);
if(sym!=ripa) /*缺少]*/
{
error(38,line-1);
}
}
}
getsymdo;
switch(sym)
{
case eql: /*如果是=则说明赋值语句有错*/
error(42,line);
getsymdo;
memcpy(nxtlev,fsys,sizeof(bool)* symnum);
expressiondo(nxtlev,ptx,lev);
break;
case becomes: /* 解释:=语句 */
getsymdo;
memcpy(nxtlev,fsys,sizeof(bool)* symnum);
expressiondo(nxtlev,ptx,lev);
break;
case incsym: /* 解释形如a++语句 */
gendo(lod,lev-table[i].level,table[i].adr);
gendo(lit,0,1);
gendo(opr,0,2); /*执行加法运算*/
getsymdo;
break;
case decsym: /* 解释形如a--语句 */
gendo(lod,lev-table[i].level,table[i].adr);
gendo(lit,0,1);
gendo(opr,0,3); /*执行减法运算*/
getsymdo;
break;
case plueql: /* 解释+=语句 */
gendo(lod,lev-table[i].level,table[i].adr);
getsymdo;
memcpy(nxtlev,fsys,sizeof(bool)* symnum);
expressiondo(nxtlev,ptx,lev);
gendo(opr,0,2); /*执行加法运算*/
break;
case mineql: /* 解释-=语句 */
gendo(lod,lev-table[i].level,table[i].adr);
getsymdo;
memcpy(nxtlev,fsys,sizeof(bool)* symnum);
expressiondo(nxtlev,ptx,lev);
gendo(opr,0,3); /*执行减法运算*/
break;
case muleql: /* 解释*=语句 */
gendo(lod,lev-table[i].level,table[i].adr);
getsymdo;
memcpy(nxtlev,fsys,sizeof(bool)* symnum);
expressiondo(nxtlev,ptx,lev);
gendo(opr,0,4); /*执行乘法运算*/
break;
case diveql: /* 解释/=语句 */
gendo(lod,lev-table[i].level,table[i].adr);
getsymdo;
memcpy(nxtlev,fsys,sizeof(bool)* symnum);
expressiondo(nxtlev,ptx,lev);
gendo(opr,0,5); /*执行除法运算*/
break;
default:
error(8,line);
break;
}
}
else
{
error(12,line);
i=0;
}
if(i!=0)
{
if(table[i].kind==array)
{
gendo(kep,lev-table[i].level,table[i].adr); /*如果是数组,则用取数组值的指令*/
}
else
gendo(sto,lev-table[i].level,table[i].adr); /*如果是变量*/
}
}
break;
case readsym: /*准备按照read语句处理*/
getsymdo;
if(sym!=lparen)
{
error(34,line);
}
else
{
do{
getsymdo;
if(sym==ident)
{
i=position(id, *ptx);
if(table[i].kind==array) /*如果输入的是数组*/
{
getsymdo;
if(sym==lepa)
{
getsymdo;
memcpy(nxtlev,fsys,sizeof(bool)* symnum);
nxtlev[ripa]=true;
expressiondo(nxtlev,ptx,lev);
if(sym!=ripa)
{
error(38,line-1); /*缺少]*/
}
}
}
}
else
{
i=0;
}
if(i==0)
{
error(11,line);
}
else
{
gendo(opr,0,16);
if(table[i].kind==array)
{
gendo(kep,lev-table[i].level,table[i].adr);
}
else
gendo(sto,lev-table[i].level,table[i].adr); /* 储存到变量*/
}
getsymdo;
}while (sym==comma); /*一条read语句可读多个变量 */
}
if(sym!=rparen)
{
error(35,line-1); /* 格式错误,应是右括号*/
while(!inset(sym,fsys)) /* 出错补救,直到收到上层函数的后跟符号*/
{
getsymdo;
}
}
else
{
getsymdo;
}
break;
case writesym: /* 准备按照write语句处理,与read类似*/
getsymdo;
if(sym==lparen)
{
do{
getsymdo;
memcpy(nxtlev,fsys,sizeof(bool)*symnum);
nxtlev[rparen]=true;
nxtlev[comma]=true; /* write的后跟符号为)or,*/
expressiondo(nxtlev,ptx,lev);/* 调用表达式处理,此处与read不同,read为给变量赋值*/
gendo(opr,0,14);/* 生成输出指令,输出栈顶的值*/
}while(sym==comma);
if(sym!=rparen)
{
error(44,line-1);/* write()应为完整表达式*/
}
else
{
getsymdo;
}
}
else
{
error(43,line);
}
gendo(opr,0,15); /* 输出换行*/
break;
case callsym: /* 准备按照call语句处理*/
getsymdo;
if(sym!=ident)
{
if(sym==semicolon)
{
error(45,line-1); /*call后漏掉了标识符*/
}
else
{
error(14,line); /*call后应为标识符*/
getsymdo;
}
}
else
{
i=position(id,*ptx);
if(i==0)
{
error(11,line); /*过程名未找到*/
}
else
{
if(table[i].kind==procedur)
{
gendo(cal,lev-table[i].level,table[i].adr); /*生成call指令*/
}
else
{
error(15,line); /*call后标识符应为过程*/
}
}
getsymdo;
}
break;
case ifsym: /*准备按照if语句处理*/
getsymdo;
memcpy(nxtlev,fsys,sizeof(bool)*symnum);
nxtlev[thensym]=true;
nxtlev[dosym]=true; /*后跟符号为then或do*/
conditiondo(nxtlev,ptx,lev); /*调用条件处理(逻辑运算)函数*/
if(sym==thensym)
{
getsymdo;
}
else
{
error(16,line-1); /*缺少then*/
}
cx3[ifi++]=cx; /*保存当前指令地址,cx3为一个全局变量的数组*/
gendo(jpc,0,0); /*生成条件跳转指令,跳转地址暂写0*/
statementdo(fsys,ptx,lev); /*处理then后的语句*/
code[cx3[--ifi]].a=cx; /*经statement处理后,cx为then后语句执行
完的位置,它正是前面未定的跳转地址*/
if(sym==elsesym) /*准备按照else语句处理*/
{
getsymdo;
code[cx3[ifi]].a=code[cx3[ifi]].a+1; /*如果有else语句,当if条件为假,则跳转执行else后的语句*/
cx4[elsei++]=cx; /*保存当前指令地址,cx4为一个全局变量的数组*/
gendo(jmp,0,0); /*生成无条件跳转指令,跳转地址暂写0*/
statementdo(fsys,ptx,lev); /*处理else后的语句*/
for(k=0;k<elsei;k++)
{
code[cx4[k]].a=cx; /*经statement处理后,cx为整个if语句执行完的位置的下一个位置*/
}
}
break;
case forsym: /*准备按照for语句处理*/
getsymdo;
if(sym==ident)
{
i=position(id,*ptx);
if(i==0)
{
error(11,line); /*变量未找到*/
}
else
{
if(table[i].kind!=variable)
{
error(12,line); /*赋值语句格式错误*/
i=0;
}
else
{
getsymdo;
if(sym==becomes)
{
getsymdo;
}
else
{
if(sym==eql)
{
error(42,line);
getsymdo;
}
else
error(13,line); /*没有检测到赋值符号*/
}
memcpy(nxtlev,fsys,sizeof(bool)*symnum);
nxtlev[tosym]=true;
nxtlev[downtosym]=true; /*后跟符号为to或downto*/
expressiondo(nxtlev,ptx,lev); /*处理赋值符号右侧表达式*/
if(i!=0)
{
gendo(sto,lev-table[i].level,table[i].adr); /*保存初值*/
}
switch(sym)
{
case tosym: /*循环变量逐渐增大*/
getsymdo;
cx1=cx; /*保存循环变值跟终值进行比较操作的有关位置*/
gendo(lod,lev-table[i].level,table[i].adr); /*将循环变值入栈*/
memcpy(nxtlev,fsys,sizeof(bool)*symnum);
nxtlev[dosym]=true; /*后跟符号为do*/
expressiondo(nxtlev,ptx,lev); /*调用终值的表达式处理*/
gendo(opr,0,13); /*判断循环变量是否小于等于终值*/
cx2=cx; /*保存循环体结束的下一个位置*/
gendo(jpc,0,0); /*生成条件跳转,但跳出循环的地址未知*/
if(sym==dosym) /*步长为1*/
{
getsymdo;
statementdo(fsys,ptx,lev); /*循环体*/
gendo(lod,lev-table[i].level,table[i].adr);
gendo(lit,0,1);
gendo(opr,0,2);
gendo(sto,lev-table[i].level,table[i].adr); /*循环变量加1*/
gendo(jmp,0,cx1); /*回头重新判断条件*/
code[cx2].a=cx; /*回填跳出循环的地址*/
}
else
{
if(sym==stepsym) /*步长不为1*/
{
getsymdo;
gendo(inte,0,1); /*开辟一个新的空间存放步长的值*/
expressiondo(nxtlev,ptx,lev);
ptx2=*ptx;
while(table[ptx2].kind !=variable) /*寻找最后一个在声明语句中定义的变量*/
{
ptx2--;
}
gendo(sto,0,table[ptx2].adr+1); /*把"表达式"结果保存在新开辟的空间,即之前最后一个变量的下一个地址*/
if(sym==dosym)
{
getsymdo;
statementdo(fsys,ptx,lev);
gendo(lod,lev-table[i].level,table[i].adr);
gendo(lod,0,table[ptx2].adr+1); /*取出步长的值*/
gendo(opr,0,2);
gendo(sto,lev-table[i].level,table[i].adr); /*循环变量加上步长的值*/
gendo(jmp,0,cx1); /*回头重新判断条件*/
code[cx2].a=cx; /*回填跳出循环的地址*/
}
else
{
error(46,line-1); /*语句中丢了"do"*/
}
}
else
{
error(29,line-1); /* 语句中丢了"step" */
}
}
break;
case downtosym: /*循环变量逐渐减少*/
getsymdo;
cx1=cx; /*保存循环变值跟终值进行比较操作的有关位置*/
gendo(lod,lev-table[i].level,table[i].adr); /*将循环变值入栈*/
memcpy(nxtlev,fsys,sizeof(bool)*symnum);
nxtlev[stepsym]=true;
nxtlev[dosym]=true; /*后跟符号为do*/
expressiondo(nxtlev,ptx,lev); /*调用终值的表达式处理*/
gendo(opr,0,11); /*判断循环变量是否小于等于终值*/
cx2=cx; /*保存循环体结束的下一个位置*/
gendo(jpc,0,0); /*生成条件跳转,但跳出循环的地址未知*/
if(sym==dosym) /*步长为-1*/
{
getsymdo;
statementdo(fsys,ptx,lev); /*循环体*/
gendo(lod,lev-table[i].level,table[i].adr);
gendo(lit,0,1);
gendo(opr,0,3);
gendo(sto,lev-table[i].level,table[i].adr); /*循环变量加1*/
gendo(jmp,0,cx1); /*回头重新判断条件*/
code[cx2].a=cx; /*回填跳出循环的地址*/
}
else
{
if(sym==stepsym) /*步长不为-1*/
{
getsymdo;
gendo(inte,0,1); /*开辟一个新的空间存放步长的值*/
expressiondo(nxtlev,ptx,lev);
ptx2=*ptx;
while(table[ptx2].kind !=variable) /*寻找最后一个在声明语句中定义的变量*/
{
ptx2--;
}
gendo(sto,0,table[ptx2].adr+1); /*把"表达式"结果保存在新开辟的空间,即之前最后一个变量的下一个地址*/
if(sym==dosym)
{
getsymdo;
statementdo(fsys,ptx,lev); /*循环体*/
gendo(lod,lev-table[i].level,table[i].adr);
gendo(lod,0,table[ptx2].adr+1); /*取出步长的值*/
gendo(opr,0,3);
gendo(sto,lev-table[i].level,table[i].adr); /*循环变量减掉步长的值*/
gendo(jmp,0,cx1); /*回头重新判断条件*/
code[cx2].a=cx; /*回填跳出循环的地址*/
}
else
{
error(46,line-1); /* 语句中丢了"do" */
}
}
else
{
error(29,line); /* 语句中丢了"step" */
}
}
break;
default:
error(22,line-1); /* 语句中缺少了"to"或"downto" */
break;
}
}
}
}
else
{
error(12,line); /* 赋值语句左部标识符应是变量 */
}
break;
case casesym:
casej=0;
getsymdo;
gendo(inte,0,1); /*开辟一个地址空间保存"表达式"计算的结果*/
memcpy(nxtlev,fsys,sizeof(bool)*symnum);
nxtlev[ofsym]=true; /*case语句后的表达式后跟符号为of*/
expressiondo(nxtlev,ptx,lev);
ptx2=*ptx;
while(table[ptx2].kind !=variable) /*寻找最后一个在声明语句中定义的变量*/
{
ptx2--;
}
gendo(sto,0,table[ptx2].adr+1); /*把"表达式"结果保存在新开辟的空间,即之前最后一个变量的下一个地址*/
if(sym==ofsym)
{
getsymdo;
}
else
{
error(37,line-1); /*缺少了of*/
}
while(sym!=endsym) /*case以end作为结束符*/
{
casei=0;
while(sym==number) /*case值表是一些用逗号分开的常数*/
{
gendo(lod,0,table[ptx2].adr+1);
gendo(lit,0,num);
gendo(opr,0,9); /*判断值表中的常数是否与之前"表达式"计算的结果相等*/
cx5[casei++]=cx; /* 记录需要回填的地址的序号*/
gendo(jpc,0,0); /*如果相等,则跳转到此值表后面的语句继续执行,如果不等则继续比较些值表后面的常数*/
getsymdo;
if(sym==comma)
getsymdo;
}
if(sym==colon)
{
cx1=cx;
gendo(jmp,0,0); /*如果此值表的值都不等于"表达式"的结果,则跳转到下一个case语句*/
for(k=0;k<casei;k++)
code[cx5[k]].a=cx; /*把开始执行值表后面语句的第一个位置回填*/
getsymdo;
}
statementdo(nxtlev,ptx,lev); /*每条case语句后面的循环体*/
cx6[casej++]=cx; /*记录需要回填的地址序号*/
gendo(jmp,0,0); /*执行此case语句后,需要跳转出case循环*/
code[cx1].a=cx; /*回填相对于上面case语句的下一条case语句的位置*/
if(sym==semicolon)
{
getsymdo;
}
}
if(sym==endsym)
{
getsymdo;
for(k=0;k<casej;k++)
code[cx6[k]].a=cx; /* 把case循环体结束的下一个位置回填*/
}
break;
case repeatsym:
cx1=cx; /*记录循环体开始的位置*/
getsymdo;
while(sym!=untilsym && !inset(sym,statbegsys) && sym!=endsym)
{
memcpy(nxtlev,fsys,sizeof(bool)*symnum);
nxtlev[semicolon]=true;
nxtlev[untilsym]=true;
statementdo(nxtlev,ptx,lev); /*循环体*/
if(sym==semicolon)
{
getsymdo;
}
}
if(sym==untilsym)
{
getsymdo;
memcpy(nxtlev,fsys,sizeof(bool)*symnum); /*表达式处理*/
nxtlev[semicolon]=true;
conditiondo(nxtlev,ptx,lev);
gendo(jpc,0,cx1); /*如果条件为假,则跳转到上面的循环体继续执行,直到条件为真*/
}
else
{
error(17,line);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -