if (i==0) Error(11);
else if (TABLE[i].KIND!=VARIABLE) { /*ASSIGNMENT TO NON-VARIABLE*/
Error(12); i=0; }
if (i!=0) GEN(LOD,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR); GEN (LIT,0,1); GEN (OPR,0,3); if (i!=0) {
GEN(STO,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR); //将栈顶送入变量单元 GEN(LOD,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR); //将变量送入栈顶 }
GetSym (); }
else Error(45); }
d)扩充 += 和 -= 操作
这两个操作都是一种对变量进行赋值的形式,其合法的语句形式的语法图如下所示:
根据图3,在语句处理STATEMENT中,在已经处理INC和DEC的基础上,添加对PLUSBK(+=)运算和MINUSBK(-=)运算的扩充,相关代码添加如下:
else if (SYM==PLUSBK) //增加运算符+= {
if (i!=0) GEN(LOD,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR); GetSym();
EXPRESSION(FSYS,LEV,TX); GEN(OPR,0,2);
if (i!=0) GEN(STO,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR); }
else if (SYM==MINUSBK) //增加运算符-= {
if (i!=0) GEN(LOD,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR); GetSym();
EXPRESSION(FSYS,LEV,TX); GEN(OPR,0,3);
if (i!=0) GEN(STO,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR); }
这样就完成了对+=运算和-=运算的添加。
17
2.增加Pascal的FOR语句: a)格式如下:
FOR <变量> := <常数>
TO(或DOWNTO) <常数>
DO <语句>
b)添加语句
for 语句的语句语法图如下:
首先,词法分析部分增加关键字
在SYMBOL里增加FORSYM, TOSYM, DOWNTOSYM,对应SYMMAX=44 ; NORW = 25; 初始化中
strcpy(KWORD[10],\ WSYM[ 10]=IFSYM; strcpy(KWORD[22],\ WSYM[22]=TOSYM;
strcpy(KWORD[ 7],\ WSYM[ 7]=DOWNTOSYM;
其次,修改STATEMENT,代码如下: case FORSYM: //添加FOR语句。 GetSym();
if(SYM != IDENT) Error(47); else i=POSITION(ID,TX); if(i == 0) Error(11); else if (TABLE[i].KIND!=VARIABLE) { /*ASSIGNMENT TO NON-VARIABLE*/ Error(12); i=0; }
GetSym();
if(SYM == BECOMES) GetSym(); else Error(13); EXPRESSION(SymSetUnion(SymSetNew(TOSYM,DOWNTOSYM),FSYS),LEV,TX); if(i != 0) GEN(STO,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR);
if(SYM == TOSYM){ //如果是to语句 CX1=CX;//记录当前地址入口
GEN(LOD,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR); //取ident变量值到栈顶 GetSym();
EXPRESSION(SymSetUnion(SymSetNew(DOSYM),FSYS),LEV,TX);
18
//取表达式值到栈顶
GEN(OPR,0,13);//判断变量是否小于或等于栈顶 CX2=CX;GEN(JPC,0,0);
GEN(LOD,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR); GEN(LIT,0,1); GEN(OPR,0,2);
GEN(STO,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR); //变量加一
if(SYM == DOSYM){//执行DO后的语句 GetSym();
STATEMENT(FSYS,LEV,TX); }
else Error(48); GEN(JMP,0,CX1); CODE[CX2].A=CX; }
else if (SYM==DOWNTOSYM){ //如果为down语句 CX1=CX;
GEN(LOD,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR); GetSym();
EXPRESSION(SymSetUnion(SymSetNew(DOSYM),FSYS),LEV,TX); GEN(OPR,0,11);//变量大于或等于栈顶 CX2=CX;GEN(JPC,0,0);
GEN(LOD,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR); GEN(LIT,0,1); GEN(OPR,0,3);
GEN(STO,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR); //变量减一
if (SYM==DOSYM){//执行DO后的语句 GetSym();
STATEMENT(FSYS,LEV,TX); }
else Error(48); GEN(JMP,0,CX1); CODE[CX2].A=CX; }
else Error(47);
break; //添加FOR语句。 FOR语句扩充完毕。
3.增加一维数组类型
首先设置一维数组的左右括号: ssym['[']=lepa;//一维数组的左括号[ ssym[']']=ripa;//一维数组的右括号]
19
增加指令:
strcpy(&(mnemonic[gar][0]),\根据栈顶的偏移地址从数组中取值到新的栈顶 strcpy(&(mnemonic[sar][0]),\根据次栈顶的偏移地址把栈顶的值存入数组
strcpy(&(mnemonic[shd][0]),\将栈顶的值下移到次栈顶,栈顶出栈,即次栈顶成为栈顶
strcpy(&(mnemonic[del][0]),\出栈顶
strcpy(&(mnemonic[jud][0]),\判断数组下标合法性
strcpy(&(mnemonic[tra][0]),\将数组的下标范围入栈,gendo(tra,0,数组下标最大值);
增加标识符类型属性: /*--标识符的类型属性--*/ enum object{ constant, variable, procedur,
array, //数组 };
在block()函数中添加如下代码: for(i=tx0+1;i<=tx;i++) {
switch(table[i].kind) {
case constant: printf(\ printf(\ fprintf(fas,\ fprintf(fas,\ break; case variable:
printf(\
printf(\ fprintf(fas,\
fprintf(fas,\ break; case procedur:
printf(\ printf(\size=%d\\n\ fprintf(fas,\ fprintf(fas,\adr=%d \\n\ break;
20
addr=%d size=%d

