编译原理实验报告-- PL-0编译程序的修改.docx
实验报告课程名称编译原理颗目名称PL/O编译程序的修改学生学院计算机学院有'11/耕级一12级软件4班一、基本内容(成绩范围:“中”、“及格”或“不及格”)对PL/O作以下修改扩充:(1)增力口单词:保留字 ELSE, FOR, STEP, UNTIL, DO,RETURN 运算符 *=, /=, &, , !(2)修改单词:不等号#改为v>(3)增加条件语句的ELSE子句,要求:写出相关文法,语法图,语义 规则。二、设计思路1.扩充单词1)修改变量定义a)先修改保留字的个数COnSt NORW = 19;b)修改枚举变量SYMBOL的个数为43typedef enum NUL, IDENT, NUMBER, PLUS, MINUS, TIMES,Timesequal, slashequal,SLASH, ODDSYM, EQL, NEQ, LSS, LEQ, GTR, GEQ, LPAREN, RPAREN, COMMA, SEMICOLON, PERIOD, BECOMES, BEGINSYM, ENDSYM, IFSYM, THENSYM, WHILESYM, WRITESYM, READSYM, DOSYM, CALLSYM, CONSTSYM, VARSYM, PROCSYM, PROGSYM, ELSESYM, FORSYM, STEPSYM, UNTILSYM, RETURNSYM9 AND, OR,NOT SYMBOL;c)修改SYMOUT数组的个数为43char *SYMOUT = NUL, IDENT, nNUMBERn, nPLUSn, nMlNus V TIMESn9nTIMESEQUALn9 nSLASHEQUALn9 "SLASH", nODDSYMn9 EQLn, nNEQn, LSSn, ,LEQn, nGTRn, GEQ, hLPARENh, nRPARENn, COMMA, nSEMICOLONn, PERIOD, nBECOMESn, hBEGINSYMh, nENDSYMn, IFSYM, hTHENSYMh, nWHILESYMn, nWRITESYMn, nREADSYMn, DOSYM, nCALLSYMn, nCONSTSYMn, VARSYM, nPROCSYMn, nPROGSYMn, nELSESYMnnFORSYMn9 nSTEPSYMn9 nUNTILSYMn, nRETURNSYMn,AND, OR, NOT);d)增加关键字和保留字strcpy(KWORD 1,nBEGIN); strcpy(KWORD 2,CALLn);strcpy(KWORD 3,nCONST);strcpy(KWORD 4,DO);StrCPy(KWORD 5 JELSE'');StrCPy(KWORD6 JEND");StrCPy(KWORD7 JFoR');strcpy(KWORD 8,IF);StrCPy(KWORD9, "ODD");strcpy(KWORD10,"PROCEDURE");strcpy(KWORD 11, "PROGRAM");strcpy (KWORD 12, nREADn);StrCPy(KWORD13,''RETURN'');StrCPy(KWoRD14,''STEP'');strcpy(KWORD15,THEN);StrCPy(KWoRD16 JUNTlL'');strcpy (KWORD 17,n VARn);strcpy (KWORD 18, WHILE);strcpy(KWORD19,WRITE);WSYM 1=BEGINSYM; WSYM 2=CALLSYM;WSYM 3=CONSTSYM; WSYM 4=DOSYM;WSYM 5=ELSESYM; WSYM6=ENDSYM;WSYM7=FORSYM;WSYM8=IFSYM;WSYM9=ODDSYM;WSYM10=PROCSYM;WSYM11=PROGSYM;WSYM12=READSYM;WSYM13=RETURNSYM; WSYM14=STEPSYM;WSYM15=THENSYM;WSYM16=UNTILSYM;WSYM17=VARSYM;WSYM18=WHILESYM;ws YM 19 =writesym ;e.在STATEMENT方法 中添加case ELSESYM:FOrml>printfs("读取至! ELSE);break;case FORSYM:FOrmI>printfs("读取至(j FORn);break;case STEPSYM:FonnL>printfs(''读取到 STEP);break;case UNTILSYM:FOrmI>printfs("读取到 UNTILn); break;case RETURNSYM:FormL>printfs(''读取至! RETURN);break;case TIMESEQUAL:FOrml>printfs("读取到 *=”); break;case SLASHEQUAL:Forml>printfs("读取到/=");break;case AND:FormI>printfs("读取到&”); break;case OR:FOrml >printfs(''读取至! );break;case NOT:FormL>printfs(,读取至! NOT);break;2)修改GetSym()方法void GetSym() int i,J,K; ALFA A;while (CH<=f,) GetCh();if(CH>=,A, && CH<=,Z,) *ID OR RESERVED WORD*/ K=O;do if(K<AL)AK+=CH;GetCh();while(CH>='A' && CH<=,Z,)(CH>=,O, && CH<='9');AK=,0,;strcpy(ID,A); i=zl; J=NORW;do K=(i+J) / 2;if (strcmp(ID,KWORDK)<=0) J=K-1;if (strcmp(ID,KWORDK)>=0) i=K+l;while(i<=J);if (i-l > J) SYM=WSYMK;If(SYM=ELSESYM) Forml->printfs(ELSE);if(SYM=FORSYM) Forml->printfs(FOR);If(SYM=STEPSYM) Forml->printfs(STEP);If(SYM=UNTILSYM) Forml->printfs(UNTIL);If(SYM=RETURNSYM) Forml->printfs(RETURN);)else SYM=IDENT;)elseif(CH>=,0, && CH<=,9,) /*NUMBER*/K=0; NUM=O; SYM=NUMBER;do NUM=10*NUM+(CH-,0,);K+; GetCh();while(CH>=,0, && CH<=,9,);if(K>NMAX)Error(30);)elseif (CH=T) GetCh();if (CH=,=f) SYM=BECOMES; GetCh(); else SYM=NUL;)else * THE FOLLOWING TWO CHECK WERE ADDEDBECAUSE ASCII DOES NOT HAVE A SINGLE CHARACTERFOR <= OR >= */if (CH=,<,) GetCh();if (CH=,) SYM=LEQ; GetCh(); else if(CH=,>,) SYM=NEQ; GetCh(); else SYM=LSS;elseif (CH=,>,) GetCh();if (CH=,=, SYM=GEQ; GetCh(); else SYM=GTR;)elseif(CH=W)GetCh();添加运算符*二if (CH=,) SYM=TIMESEQUAL; GetCh(); else SYM=TIMES;)elseif(CH=7,)GetCh();添加运算符/二if(CH=,=,> SYM= SLASHEQUAL, GetCh();) else SYM=SLASH;)elseif(CH=,) SYM= AND, GetCh(); 添加运算符&elseif(CH=,)GetCh();if(CH=T) SYM= OR, GetCh(); 添加运算符 else SYM=NUL;)elseif(CH=,!,) SYM= NOT, GetCh(); 添加运算符!else SYM=SSYMCH; GetCh(); /*GetSym()*/2 .修改单词:不等号#改为<>a.在文件中的设置单字符符号的部分,将SSym铲=NEQ删除。b.在GetSym()方法中elseif (CH=T) GetCh();if (CH=,=t) SYM=BECOMES; GetCh(); else SYM=NUL;)else * THE FOLLOWING TWO CHECK WERE ADDEDBECAUSE ASCII DOES NOT HAVE A SINGLE CHARACTER FOR <= OR >=if (CH=,<,) GetCh();if(CH=,=,) SYM=LEQ; GetCh(); else if(CH=,>,) SYM=NEQ; GetCh(); else SYM=LSS;)elseif (CH=A) GetCh();if (CH='=') SYM=GEQ; GetCh(); else SYM=GTR;)3 .增加条件语句的ELSE子句1)语法图2)修改 STATEMENT ()方法case IFSYM:GetSymQ;CONDITION(SymSetUnion(SymSetNew(THENSYM,DOSYM),FSYS),LEV,TX);if (Sym=THENSYM) GetSym();else Error(16);CXl=CX; GEN(JPC9O9O);STATEMENT(SymSetUnion(SymSetNew(ELSESYM), FSYS), LEV9 TX); if(SYM != ELSESYM)CODECX1.A=CX;elseGetSym();CX2 = CX;GEN(JMP, 0