期末到了,忙课设好久了,在编译原理的课设上面走了好多的弯路,也好久没有碰前端的东西了,心感惭愧,那我就把我最近忙的一些东西贡献出来,希望可以帮助到那些感觉这门科目很难的同学,祝大家可以学好每一门学科~
下面是我们学校的学习要求,我全部已经完成,时间仓促,大家仅供参考。转载请注明出处。
基本内容(成绩范围:“中”、“及格”或“不及格”)
(1)扩充赋值运算:+=,-=, *= 和 /=
(2)扩充语句(Pascal的FOR语句):
FOR <变量>:=<表达式>STEP<表达式> UNTIL<表达式>Do<语句>
选做内容(成绩评定范围扩大到:“优”和“良”)
(1)增加类型:① 字符类型; ② 实数类型。
(2) 增加 注释; 注释由/*和*/包含;
(3)扩充函数:① 有返回值和返回语句;② 有参数函数。
(4)增加一维数组类型(可增加指令)。
(5)其他典型语言设施。
1 /*** PL0 COMPILER WITH CODE GENERATION ***/ 2 /** 3 * 时间2015/12/28 22:35 4 * 添加 前++ 后++ 前-- 后-- 5 * 6 */ 7 //--------------------------------------------------------------------------- 8 #include <vcl.h> 9 #pragma hdrstop 10 #include "Unit1.h" 11 //--------------------------------------------------------------------------- 12 #pragma package(smart_init) 13 #pragma resource "*.dfm" 14 TForm1 *Form1; 15 //--------------------------------------------------------------------------- 16 const AL = 10; /* LENGTH OF IDENTIFIERS */ 17 const NORW = 24; /* # OF RESERVED WORDS */ 18 const TXMAX = 100; /* LENGTH OF IDENTIFIER TABLE */ 19 const NMAX = 14; /* MAX NUMBER OF DEGITS IN NUMBERS */ 20 const AMAX =2047; /* MAXIMUM ADDRESS */ 21 const LEVMAX= 3; /* MAX DEPTH OF BLOCK NESTING */ 22 const CXMAX = 200; /* SIZE OF CODE ARRAY */ 23 int SYMMAX = 53;//记录SYMBOL元素个数,原为33 24 typedef enum { NUL, IDENT, NUMBER, PLUS, MINUS, TIMES, 25 SLASH, ODDSYM, EQL, NEQ, LSS, LEQ, GTR, GEQ, 26 LPAREN, RPAREN, COMMA, SEMICOLON, PERIOD, 27 BECOMES, BEGINSYM, ENDSYM, IFSYM, THENSYM, 28 WHILESYM, WRITESYM, READSYM, DOSYM, CALLSYM, 29 CONSTSYM, VARSYM, PROCSYM,PROGSYM, 30 /*添加字符 & || !*/ 31 AND,OR,NOT, 32 /*添加运算符 += -= *= /= ++ -- */ 33 PLUSBECOMES,MINUSBECOMES,MEQ,DEQ,DPLUS,DMINUS, 34 //关键字 35 ELSESYM,FORSYM,STEPSYM,UNTILSYM,RETURNSYM, 36 /*添加类型 */ 37 OFSYM,INTSYM, CHARSYM, REALSYM, 38 //左右方括号 39 LBK,RBK 40 } SYMBOL; 41 char *SYMOUT[] = {"NUL", "IDENT", "NUMBER", "PLUS", "MINUS", "TIMES", 42 "SLASH", "ODDSYM", "EQL", "NEQ", "LSS", "LEQ", "GTR", "GEQ", 43 "LPAREN", "RPAREN", "COMMA", "SEMICOLON", "PERIOD", 44 "BECOMES", "BEGINSYM", "ENDSYM", "IFSYM", "THENSYM", 45 "WHILESYM", "WRITESYM", "READSYM", "DOSYM", "CALLSYM", 46 "CONSTSYM", "VARSYM", "PROCSYM", "PROGSYM", 47 /*添加字符 & || !*/ 48 "AND","OR","NOT", 49 /*添加运算符 += -= *= /= ++ -- */ 50 "PLUSBECOMES","MINUSBECOMES","MEQ","DEQ","DPLUS","DMINUS", 51 //关键字 52 "ELSESYM","FORSYM", "STEPSYM","UNTILSYM","RETURNSYM", 53 /*添类型*/ 54 "OFSYM","INTSYM","CHARSYM","REALSYM", 55 //左右方括号 56 "LBK","RBK" 57 }; 58 typedef int *SYMSET; // SET OF SYMBOL; 59 typedef char ALFA[11]; 60 typedef enum { CONSTANT, VARIABLE, PROCEDUR,ARRAY} OBJECTS ; 61 typedef enum { LIT, OPR, LOD, STO, CAL, INI, JMP, JPC, 62 GAR, TAR, DEL, SAR, JUD} FCT; 63 typedef struct 64 { 65 FCT F; /*FUNCTION CODE*/ 66 int L; /*0..LEVMAX LEVEL*/ 67 float A; /*0..AMAX DISPLACEMENT ADDR*/ //int 68 } INSTRUCTION; 69 /* LIT O A -- LOAD CONSTANT A */ 70 /* OPR 0 A -- EXECUTE OPR A */ 71 /* LOD L A -- LOAD VARIABLE L,A */ 72 /* STO L A -- STORE VARIABLE L,A */ 73 /* CAL L A -- CALL PROCEDURE A AT LEVEL L */ 74 /* INI 0 A -- INCREMET T-REGISTER BY A */ 75 /* JMP 0 A -- JUMP TO A */ 76 /* JPC 0 A -- JUMP CONDITIONAL TO A */ 77 char CH; /*LAST CHAR READ*/ 78 SYMBOL SYM; /*LAST SYMBOL READ*/ 79 ALFA ID; /*LAST IDENTIFIER READ*/ 80 float NUM; /*LAST NUMBER READ*/ //int 81 int CC; /*CHARACTER COUNT*/ 82 int LL; /*LINE LENGTH*/ 83 int CX; /*CODE ALLOCATION INDEX*/ 84 char LINE[81]; 85 86 //记录数组的大小 87 float ARRYSIZE; 88 INSTRUCTION CODE[CXMAX]; 89 ALFA KWORD[NORW+1]; 90 SYMBOL WSYM[NORW+1]; 91 SYMBOL SSYM[‘^‘+1]; 92 ALFA MNEMONIC[9]; 93 SYMSET DECLBEGSYS, STATBEGSYS, FACBEGSYS; 94 //类型 95 typedef enum { CHARCON, INTCON, REALCON, NOTYP} TYPES; 96 TYPES TY; //记录类型 97 struct 98 { 99 ALFA NAME; 100 OBJECTS KIND; 101 TYPES TYPE; //增加类型 102 union 103 { 104 float VAL; /*CONSTANT*/ //统一用浮点型记录 //int 105 struct 106 { 107 int LEVEL,ADR,SIZE; 108 } vp; /*VARIABLE,PROCEDUR: 层次、地址、存储空间*/ 109 }; 110 } TABLE[TXMAX]; 111 112 FILE *FIN,*FOUT; 113 int ERR; 114 void EXPRESSION(SYMSET FSYS, int LEV, int &TX); 115 void TERM(SYMSET FSYS, int LEV, int &TX); 116 //--------------------------------------------------------------------------- 117 int SymIn(SYMBOL SYM, SYMSET S1) 118 { 119 return S1[SYM]; 120 } 121 //--------------------------------------------------------------------------- 122 SYMSET SymSetUnion(SYMSET S1, SYMSET S2) 123 { 124 SYMSET S=(SYMSET)malloc(sizeof(int)*SYMMAX); 125 for (int i=0; i<SYMMAX; i++) 126 if (S1[i] || S2[i]) S[i]=1; 127 else S[i]=0; 128 return S; 129 } 130 //--------------------------------------------------------------------------- 131 SYMSET SymSetAdd(SYMBOL SY, SYMSET S) 132 { 133 SYMSET S1; 134 S1=(SYMSET)malloc(sizeof(int)*SYMMAX); 135 for (int i=0; i<SYMMAX; i++) S1[i]=S[i]; 136 S1[SY]=1; 137 return S1; 138 } 139 //--------------------------------------------------------------------------- 140 SYMSET SymSetNew(SYMBOL a) 141 { 142 SYMSET S; 143 int i,k; 144 S=(SYMSET)malloc(sizeof(int)*SYMMAX); 145 for (i=0; i<SYMMAX; i++) S[i]=0; 146 S[a]=1; 147 return S; 148 } 149 //--------------------------------------------------------------------------- 150 SYMSET SymSetNew(SYMBOL a, SYMBOL b) 151 { 152 SYMSET S; 153 int i,k; 154 S=(SYMSET)malloc(sizeof(int)*SYMMAX); 155 for (i=0; i<SYMMAX; i++) S[i]=0; 156 S[a]=1; 157 S[b]=1; 158 return S; 159 } 160 //--------------------------------------------------------------------------- 161 SYMSET SymSetNew(SYMBOL a, SYMBOL b, SYMBOL c) 162 { 163 SYMSET S; 164 int i,k; 165 S=(SYMSET)malloc(sizeof(int)*SYMMAX); 166 for (i=0; i<SYMMAX; i++) S[i]=0; 167 S[a]=1; 168 S[b]=1; 169 S[c]=1; 170 return S; 171 } 172 //--------------------------------------------------------------------------- 173 SYMSET SymSetNew(SYMBOL a, SYMBOL b, SYMBOL c, SYMBOL d) 174 { 175 SYMSET S; 176 int i,k; 177 S=(SYMSET)malloc(sizeof(int)*SYMMAX); 178 for (i=0; i<SYMMAX; i++) S[i]=0; 179 S[a]=1; 180 S[b]=1; 181 S[c]=1; 182 S[d]=1; 183 return S; 184 } 185 //--------------------------------------------------------------------------- 186 SYMSET SymSetNew(SYMBOL a, SYMBOL b, SYMBOL c, SYMBOL d,SYMBOL e) 187 { 188 SYMSET S; 189 int i,k; 190 S=(SYMSET)malloc(sizeof(int)*SYMMAX); 191 for (i=0; i<SYMMAX; i++) S[i]=0; 192 S[a]=1; 193 S[b]=1; 194 S[c]=1; 195 S[d]=1; 196 S[e]=1; 197 return S; 198 } 199 //--------------------------------------------------------------------------- 200 SYMSET SymSetNew(SYMBOL a, SYMBOL b, SYMBOL c, SYMBOL d,SYMBOL e, SYMBOL f) 201 { 202 SYMSET S; 203 int i,k; 204 S=(SYMSET)malloc(sizeof(int)*SYMMAX); 205 for (i=0; i<SYMMAX; i++) S[i]=0; 206 S[a]=1; 207 S[b]=1; 208 S[c]=1; 209 S[d]=1; 210 S[e]=1; 211 S[f]=1; 212 return S; 213 } 214 //--------------------------------------------------------------------------- 215 SYMSET SymSetNULL() 216 { 217 SYMSET S; 218 int i,n,k; 219 S=(SYMSET)malloc(sizeof(int)*SYMMAX); 220 for (i=0; i<SYMMAX; i++) S[i]=0; 221 return S; 222 } 223 //--------------------------------------------------------------------------- 224 void Error(int n) 225 { 226 String s = "***"+AnsiString::StringOfChar(‘ ‘, CC-1)+"^"; 227 Form1->printls(s.c_str(),n); 228 fprintf(FOUT,"%s%d\n", s.c_str(), n); 229 ERR++; 230 } /*Error*/ 231 //--------------------------------------------------------------------------- 232 void GetCh() 233 { 234 if (CC==LL) /*如果缓冲区读完*/ 235 { 236 if (feof(FIN)) //检查文件是否结束 结束返回非零值 否则返回0 237 { 238 Form1->printfs("PROGRAM INCOMPLETE"); 239 fprintf(FOUT,"PROGRAM INCOMPLETE\n"); 240 fclose(FOUT); 241 exit(0); 242 } 243 LL=0;CC=0; //line length 244 CH=‘ ‘; 245 246 //s1为注释内容所用的数组,s为每一行所要执行内容所用的数组 247 String s1 = "注释:"; 248 249 while (!feof(FIN) && CH!=10) 250 //文件未结束或者没遇到换行符 251 { 252 CH=fgetc(FIN); 253 //--------------------课设--------------- 254 if(CH==‘/‘) 255 { 256 CH=getc(FIN); 257 if(CH==‘*‘) 258 { //判断是否出现/* */字段,若是则将其读进一个数组s1里面去 并且略去/**/ 259 while(!feof(FIN)) 260 { 261 CH=getc(FIN); 262 if(CH==‘*‘ && (CH=getc(FIN))==‘/‘) 263 { 264 Form1->printfs(s1.c_str()); 265 fprintf(FOUT,"%s\n",s1); 266 break; 267 } 268 //将字符加入到s1数组中 269 s1 = s1 + CH; 270 } 271 continue; 272 } 273 else 274 LINE[LL++] = ‘/‘; //若是没有/**/则将/补回去 275 } 276 LINE[LL++]=CH; //将从文件中读取的字符存储在数组line中 277 } 278 LINE[LL-1]=‘ ‘; 279 LINE[LL]=0; 280 if(s1.Length()==6) 281 { 282 //因为"注释:"为6个字符时表示没读到注释掉的语句,所以需要判断 283 String s=IntToStr(CX); 284 while(s.Length()<3) s=" "+s; 285 s=s+" "+LINE; 286 Form1->printfs(s.c_str()); 287 fprintf(FOUT,"%s\n",s); 288 } 289 } 290 CH=LINE[CC++]; //将当前第一个读取到的字符赋值给ch;字符数+1; 291 } /*GetCh()*/ 292 //--------------------------------------------------------------------------- 293 void GetSym() 294 { 295 int i,J,K; 296 ALFA A; 297 while (CH<=‘ ‘) GetCh(); 298 if (CH>=‘A‘ && CH<=‘Z‘) /*ID OR RESERVED WORD*/ 299 { 300 K=0; 301 do 302 { 303 if (K<AL) A[K++]=CH; 304 GetCh(); 305 } 306 while((CH>=‘A‘ && CH<=‘Z‘)||(CH>=‘0‘ && CH<=‘9‘)); 307 A[K]=‘\0‘; 308 strcpy(ID,A); 309 i=1; 310 J=NORW; 311 do 312 { 313 K=(i+J) / 2; 314 if (strcmp(ID,KWORD[K])<=0) J=K-1; 315 if (strcmp(ID,KWORD[K])>=0) i=K+1; 316 } 317 while(i<=J); 318 if (i-1 > J) SYM=WSYM[K]; 319 else SYM=IDENT; 320 } 321 else if (CH>=‘0‘ && CH<=‘9‘) /*NUMBER*/ 322 { 323 K=0; 324 NUM=0; 325 SYM=NUMBER; 326 TY=INTCON; //add----------- 327 float count=10; //add----------- 328 do 329 { 330 if(CH==‘.‘){ //实数 331 GetCh(); 332 TY=REALCON; 333 while(CH>=‘0‘ && CH<=‘9‘){ 334 NUM=NUM+(CH-‘0‘)/count; 335 K++; 336 count*=10; 337 GetCh(); 338 } 339 break; 340 } 341 else{ //整数 342 NUM=10*NUM+(CH-‘0‘); 343 K++; 344 GetCh(); 345 } 346 347 } 348 while(CH>=‘0‘ && CH<=‘9‘||CH==‘.‘); 349 if (K>NMAX) Error(30); 350 } 351 else if((int)CH==39) //对应‘号 可输入一个字符 352 { 353 SYM = NUMBER; 354 GetCh(); 355 if((CH>=‘A‘ && CH<=‘Z‘)||(CH>=‘a‘ && CH<=‘z‘)) 356 { 357 NUM=(int)CH; 358 GetCh(); 359 if((int)CH==39) 360 TY=CHARCON; 361 else { 362 NUM=0; 363 SYM=NUL; 364 Error(49); 365 } //类型错误 366 } else Error(49); //类型不匹配 367 GetCh(); 368 } 369 else if (CH==‘:‘) 370 { 371 GetCh(); 372 if (CH==‘=‘) 373 { 374 SYM=BECOMES; 375 GetCh(); 376 } 377 else SYM=OFSYM; 378 } 379 else /* THE FOLLOWING TWO CHECK WERE ADDED 380 BECAUSE ASCII DOES NOT HAVE A SINGLE CHARACTER FOR <= OR >= */ 381 if (CH==‘<‘) 382 { 383 GetCh(); 384 if (CH==‘=‘) 385 { 386 SYM=LEQ; 387 GetCh(); 388 } 389 else if(CH==‘>‘) 390 { 391 SYM=NEQ; 392 GetCh(); 393 } 394 else SYM=LSS; 395 } 396 else if (CH==‘>‘) 397 { 398 GetCh(); 399 if (CH==‘=‘) 400 { 401 SYM=GEQ; 402 GetCh(); 403 } 404 else SYM=GTR; 405 } 406 /*课设*/ 407 else if(CH==‘+‘) 408 { 409 GetCh(); 410 if(CH==‘+‘) 411 { 412 SYM=DPLUS; 413 GetCh(); 414 } 415 else if(CH==‘=‘) 416 { 417 SYM=PLUSBECOMES; 418 GetCh(); 419 } 420 421 else SYM=PLUS; 422 } 423 else if(CH==‘-‘) 424 { 425 GetCh(); 426 if(CH==‘=‘) 427 { 428 SYM=MINUSBECOMES; 429 GetCh(); 430 } 431 else if(CH==‘-‘) 432 { 433 SYM=DMINUS; 434 GetCh(); 435 } 436 else SYM=MINUS; 437 } 438 else if(CH==‘*‘) 439 { 440 GetCh(); 441 if(CH==‘=‘) 442 { 443 SYM=MEQ; 444 GetCh(); 445 } 446 else SYM=TIMES; 447 } 448 else if(CH==‘/‘) 449 { 450 GetCh(); 451 if(CH==‘=‘) 452 { 453 SYM=DEQ; 454 GetCh(); 455 } 456 else 457 SYM=SLASH; 458 } 459 else if(CH==‘|‘) 460 { 461 GetCh(); 462 if(CH==‘|‘) 463 { 464 SYM=OR; 465 GetCh(); 466 } 467 else 468 Error(11); 469 } 470 else 471 { 472 SYM=SSYM[CH]; 473 GetCh(); 474 } 475 } /*GetSym()*/ 476 //--------------------------------------------------------------------------- 477 //修改 Z int -> float 478 void GEN(FCT X, int Y, float Z) 479 { 480 if (CX>CXMAX) 481 { 482 Form1->printfs("PROGRAM TOO LONG"); 483 fprintf(FOUT,"PROGRAM TOO LONG\n"); 484 fclose(FOUT); 485 exit(0); 486 } 487 CODE[CX].F=X; 488 CODE[CX].L=Y; 489 CODE[CX].A=Z; 490 CX++; 491 } /*GEN*/ 492 //--------------------------------------------------------------------------- 493 void TEST(SYMSET S1, SYMSET S2, int N) 494 { 495 if (!SymIn(SYM,S1)) 496 { 497 Error(N); 498 while (!SymIn(SYM,SymSetUnion(S1,S2))) GetSym(); 499 } 500 } /*TEST*/ 501 //--------------------------------------------------------------------------- 502 void ENTER(OBJECTS K, int LEV, int &TX, int &DX) /*ENTER OBJECT INTO TABLE*/ 503 { 504 TX++; 505 strcpy(TABLE[TX].NAME,ID); 506 TABLE[TX].KIND=K; 507 switch (K) 508 { 509 case CONSTANT: 510 if (NUM>AMAX) 511 { 512 Error(31); 513 NUM=0; 514 } 515 TABLE[TX].VAL=NUM; 516 break; 517 case VARIABLE: 518 TABLE[TX].vp.LEVEL=LEV; 519 TABLE[TX].vp.ADR=DX; 520 TABLE[TX].vp.SIZE = 0; 521 DX++; 522 break; 523 case PROCEDUR: 524 TABLE[TX].vp.LEVEL=LEV; 525 break; 526 527 case ARRAY: /*数组名字 加到TABLE表中*/ 528 TABLE[TX].vp.LEVEL=LEV; 529 TABLE[TX].vp.ADR=DX-ARRYSIZE; 530 TABLE[TX].vp.SIZE=ARRYSIZE; 531 break; 532 } 533 } /*ENTER*/ 534 //--------------------------------------------------------------------------- 535 int POSITION(ALFA ID, int TX) /*FIND IDENTIFIER IN TABLE*/ 536 { 537 int i=TX; 538 strcpy(TABLE[0].NAME,ID); 539 while (strcmp(TABLE[i].NAME,ID)!=0) i--; 540 return i; 541 } /*POSITION*/ 542 //--------------------------------------------------------------------------- 543 void ConstDeclaration(int LEV,int &TX,int &DX) 544 { 545 if (SYM==IDENT) 546 { 547 GetSym(); 548 if (SYM==EQL||SYM==BECOMES) 549 { 550 if (SYM==BECOMES) Error(1); 551 GetSym(); 552 if (SYM==NUMBER) 553 { 554 ENTER(CONSTANT,LEV,TX,DX); 555 GetSym(); 556 } 557 else Error(2); 558 } 559 else Error(3); 560 } 561 else Error(4); 562 } /*ConstDeclaration()*/ 563 //--------------------------------------------------------------------------- 564 void VarDeclaration(int LEV,int &TX,int &DX) 565 { 566 int i; 567 char IDTEMP[AL+1];//临时保存数组名? 568 if (SYM==IDENT) 569 { 570 ALFA ID0; 571 strcpy(ID0, ID); 572 strcpy(IDTEMP,ID); 573 GetSym(); 574 if (SYM==COMMA) 575 { 576 GetSym(); 577 VarDeclaration(LEV,TX,DX); 578 } 579 if(SYM == OFSYM) //声明变量类型 580 { 581 GetSym(); 582 switch(SYM) 583 { 584 case CHARSYM: 585 TY = CHARCON; 586 break; 587 case INTSYM: 588 TY = INTCON; 589 break; 590 case REALSYM: 591 TY = REALCON; 592 break; 593 default: 594 Error(52); 595 } 596 GetSym(); 597 strcpy(ID, ID0); 598 ENTER(VARIABLE,LEV,TX,DX); 599 TABLE[TX].TYPE = TY; 600 } 601 else if(SYM==LBK)//数组的左中括号 602 { 603 GetSym(); 604 if(SYM==NUMBER)//a[]中的中括号里是数字的话 605 { 606 DX=DX+NUM;//为数组分配空间 607 ARRYSIZE=NUM;//保存数组的长度 608 } 609 else 610 { 611 if(SYM==IDENT)//a[]中的中括号里是变量的话 612 { 613 //要检查是不是以声明的常量 614 i=POSITION(ID,TX);//查找名字表 615 if(i==0) 616 { 617 Error(11);//标识符未说明 618 } 619 else 620 { 621 if(TABLE[i].KIND==CONSTANT)//标识符的属性是常量 622 { 623 DX=DX+TABLE[i].VAL;//为数组分配空间 624 ARRYSIZE=TABLE[i].VAL;//保存数组的长度 625 } 626 else 627 { 628 Error(25);//数组下标定义不符合规定,应为常量 629 } 630 } 631 }//if 632 else 633 { 634 Error(25);//数组下标定义不符合规定,应为常量 635 } 636 }//else 637 strcpy(ID,IDTEMP);//恢复数组名字id 638 ENTER(ARRAY,TX,LEV,DX);//填写名字表 639 GetSym(); 640 if(SYM!=RBK)//如果不是[结尾 641 { 642 Error(26); 643 } 644 else 645 { 646 GetSym(); 647 } 648 if(SYM == OFSYM) //声明变量类型 649 { 650 GetSym(); 651 switch(SYM) 652 { 653 case CHARSYM: 654 TY = CHARCON; 655 break; 656 case INTSYM: 657 TY = INTCON; 658 break; 659 case REALSYM: 660 TY = REALCON; 661 break; 662 default: 663 Error(52); 664 } 665 TABLE[TX].TYPE = TY; 666 GetSym(); 667 } 668 } 669 else Error(19); 670 } 671 else Error(4); 672 } /*VarDeclaration()*/ 673 //--------------------------------------------------------------------------- 674 void ListCode(int CX0) /*LIST CODE GENERATED FOR THIS Block*/ 675 { 676 if (Form1->ListSwitch->ItemIndex==0) 677 for (int i=CX0; i<CX; i++) 678 { 679 String s=IntToStr(i); 680 while(s.Length()<3)s=" "+s; 681 s=s+" "+MNEMONIC[CODE[i].F]+" "+IntToStr(CODE[i].L)+" " 682 +IntToStr((int)CODE[i].A); 683 Form1->printfs(s.c_str()); 684 fprintf(FOUT,"%3d%5s%4d%4d\n",i,MNEMONIC[CODE[i].F],CODE[i].L,CODE[i].A); 685 } 686 } /*ListCode()*/; 687 //--------------------------------------------------------------------------- 688 void FACTOR(SYMSET FSYS, int LEV, int &TX) 689 { 690 int i; 691 TEST(FACBEGSYS,FSYS,24); 692 while (SymIn(SYM,FACBEGSYS)) 693 { 694 if (SYM==IDENT) 695 { 696 i=POSITION(ID,TX); 697 if (i==0) Error(11); 698 else 699 { 700 switch (TABLE[i].KIND) 701 { 702 case CONSTANT: 703 GEN(LIT,0,TABLE[i].VAL); 704 break; 705 case VARIABLE: 706 GEN(LOD,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR); 707 break; 708 case PROCEDUR: 709 Error(21); 710 break; 711 case ARRAY: 712 GetSym(); 713 if(SYM == LBK) 714 { 715 GetSym(); 716 EXPRESSION(SymSetUnion(FSYS,SymSetNew(RBK)),LEV,TX); 717 if(SYM != RBK) 718 { 719 Error(44); 720 } 721 GEN(GAR,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR); 722 } 723 else Error(28); 724 break; 725 } 726 GetSym(); 727 ////后++,后-- 728 if(SYM==DPLUS||SYM==DMINUS) //++或-- 729 { 730 switch (TABLE[i].KIND) 731 { 732 case CONSTANT: 733 Error(36); 734 break; //常量不能++或-- 735 case VARIABLE: 736 GEN(LIT,0,1); 737 if(SYM==DPLUS)GEN(OPR,0,2); //++ 738 else if(SYM==DMINUS)GEN(OPR,0,3); //-- 739 GEN(STO,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR); //将栈顶送入变量单元 740 GEN(LOD,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR); //将变量送入栈顶 741 GetSym(); 742 break; 743 case PROCEDUR: 744 Error(36); 745 break; 746 }//switch 747 }//if 748 else if(SYM==DPLUS||SYM==DMINUS) 749 { 750 if(SYM==DPLUS) //前++ 751 { 752 GetSym(); 753 if(SYM==IDENT) 754 { 755 i=POSITION(ID,TX); 756 if (i==0) Error(11); 757 else if (TABLE[i].KIND!=VARIABLE) /*ASSIGNMENT TO NON-VARIABLE*/ 758 { 759 Error(36); 760 i=0; 761 } 762 if(i!=0) 763 { 764 GEN(LOD,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR); 765 GEN(LIT,0,1); 766 GEN(OPR,0,2); 767 GEN(STO,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR); 768 GEN(LOD,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR); 769 } 770 GetSym(); 771 } 772 else Error(36); 773 }//if 774 else //前-- 775 { 776 GetSym(); 777 if(SYM==IDENT) 778 { 779 i=POSITION(ID,TX); 780 if (i==0) Error(11); 781 else if (TABLE[i].KIND!=VARIABLE) /*ASSIGNMENT TO NON-VARIABLE*/ 782 { 783 Error(36); 784 i=0; 785 } 786 if(i!=0) 787 { 788 GEN(LOD,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR); 789 GEN(LIT,0,1); 790 GEN(OPR,0,3); 791 GEN(STO,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR); 792 GEN(LOD,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR); 793 } 794 GetSym(); 795 } 796 else Error(36); 797 }//else 798 }//i 799 } 800 if(TABLE[i].TYPE > TY) 801 TY = TABLE[i].TYPE; //向高层的数据类型转 802 803 } 804 else if (SYM==NUMBER) 805 { 806 if (NUM>AMAX) 807 { 808 Error(31); 809 NUM=0; 810 } 811 GEN(LIT,0,NUM); 812 GetSym(); 813 } 814 else if (SYM==LPAREN) 815 { 816 GetSym(); 817 EXPRESSION(SymSetAdd(RPAREN,FSYS),LEV,TX); 818 if (SYM==RPAREN) GetSym(); 819 else Error(22); 820 } 821 TEST(FSYS,FACBEGSYS,23); 822 } 823 }/*FACTOR*/ 824 //--------------------------------------------------------------------------- 825 void TERM(SYMSET FSYS, int LEV, int &TX) /*TERM*/ 826 { 827 SYMBOL MULOP; 828 FACTOR(SymSetUnion(FSYS,SymSetNew(TIMES,SLASH)), LEV,TX); 829 while (SYM==TIMES || SYM==SLASH) 830 { 831 MULOP=SYM; 832 GetSym(); 833 FACTOR(SymSetUnion(FSYS,SymSetNew(TIMES,SLASH)),LEV,TX); 834 if (MULOP==TIMES) GEN(OPR,0,4); 835 else GEN(OPR,0,5); 836 } 837 } /*TERM*/; 838 //--------------------------------------------------------------------------- 839 void EXPRESSION(SYMSET FSYS, int LEV, int &TX) 840 { 841 SYMBOL ADDOP; 842 if (SYM==PLUS || SYM==MINUS) 843 { 844 ADDOP=SYM; 845 GetSym(); 846 TERM(SymSetUnion(FSYS,SymSetNew(PLUS,MINUS)),LEV,TX); 847 if (ADDOP==MINUS) GEN(OPR,0,1); 848 } 849 else TERM(SymSetUnion(FSYS,SymSetNew(PLUS,MINUS)),LEV,TX); 850 while (SYM==PLUS || SYM==MINUS) 851 { 852 ADDOP=SYM; 853 GetSym(); 854 TERM(SymSetUnion(FSYS,SymSetNew(PLUS,MINUS)),LEV,TX); 855 if (ADDOP==PLUS) GEN(OPR,0,2); 856 else GEN(OPR,0,3); 857 } 858 } /*EXPRESSION*/ 859 //--------------------------------------------------------------------------- 860 void CONDITION(SYMSET FSYS,int LEV,int &TX) 861 { 862 SYMBOL RELOP; 863 if (SYM==ODDSYM) 864 { 865 GetSym(); 866 EXPRESSION(FSYS,LEV,TX); 867 GEN(OPR,0,6); 868 } 869 else 870 { 871 EXPRESSION(SymSetUnion(SymSetNew(EQL,NEQ,LSS,LEQ,GTR,GEQ),FSYS),LEV,TX); 872 if (!SymIn(SYM,SymSetNew(EQL,NEQ,LSS,LEQ,GTR,GEQ))) Error(20); 873 else 874 { 875 RELOP=SYM; 876 GetSym(); 877 EXPRESSION(FSYS,LEV,TX); 878 switch (RELOP) 879 { 880 case EQL: 881 GEN(OPR,0,8); 882 break; 883 case NEQ: 884 GEN(OPR,0,9); 885 break; 886 case LSS: 887 GEN(OPR,0,10); 888 break; 889 case GEQ: 890 GEN(OPR,0,11); 891 break; 892 case GTR: 893 GEN(OPR,0,12); 894 break; 895 case LEQ: 896 GEN(OPR,0,13); 897 break; 898 } 899 } 900 } 901 } /*CONDITION*/ 902 //--------------------------------------------------------------------------- 903 int flag=0; 904 void STATEMENT(SYMSET FSYS,int LEV,int &TX) /*STATEMENT*/ 905 { 906 int i,CX1,CX2; 907 switch (SYM) 908 { 909 case IDENT: 910 i=POSITION(ID,TX); 911 if (i==0) Error(11); 912 else if (TABLE[i].KIND==VARIABLE||TABLE[i].KIND==ARRAY) /*ASSIGNMENT TO NON-VARIABLE*/ 913 { 914 GetSym(); 915 if(SYM == LBK) 916 { 917 GetSym(); 918 EXPRESSION(SymSetUnion(SymSetNew(RBK),FSYS),LEV,TX); 919 if(SYM != RBK) 920 { 921 Error(44); 922 } 923 GetSym(); 924 } 925 } 926 else 927 { 928 Error(12); 929 i=0; 930 } 931 if (SYM==BECOMES) { 932 GetSym(); 933 TY = CHARCON; //初始为字符型 934 EXPRESSION(FSYS,LEV,TX);//计算表达式的值 935 if (i!=0) { 936 if(TY > TABLE[i].TYPE) 937 Error(50); //类型无法转换 938 GEN(STO,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR); 939 } 940 } 941 else if(SYM==DPLUS) //语句中后++运算 942 { 943 if(i!=0)GEN(LOD,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR); //取变量 944 GEN(LIT,0,1); //常量取到栈顶 945 GEN(OPR,0,2); 946 if(i!=0)GEN(STO,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR); //存变量 947 GetSym(); 948 } 949 else if(SYM==DMINUS) //语句中后--运算 950 { 951 if(i!=0)GEN(LOD,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR); 952 GEN(LIT,0,1); 953 GEN(OPR,0,3); 954 if(i!=0)GEN(STO,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR); 955 GetSym(); 956 } 957 else if ( SYM==MEQ || SYM==DEQ || SYM==PLUSBECOMES || SYM==MINUSBECOMES ) 958 //添加处理加等、减等、乘等、除等 959 { 960 if (SYM==MEQ) 961 { 962 flag = 1; 963 } 964 if (SYM==DEQ) 965 { 966 flag = 2; 967 } 968 if (SYM==PLUSBECOMES) 969 { 970 flag = 3; 971 } 972 if (SYM==MINUSBECOMES) 973 { 974 flag = 4; 975 } 976 977 if(TABLE[i].KIND==ARRAY) //先把值存入栈 978 GEN(TAR,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR); 979 else 980 GEN(LOD,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR); 981 982 GetSym(); 983 EXPRESSION(FSYS,LEV,TX); 984 if (i!=0) { 985 switch (flag) 986 { 987 case 1: //标记为1的时候处理乘法 988 GEN(OPR,0,4); 989 flag = 0; 990 break; 991 case 2: //标记为2的时候处理除法 992 GEN(OPR,0,5); 993 flag = 0; 994 break; 995 case 3: //标记为3的时候处理加法 996 GEN(OPR,0,2); 997 flag = 0; 998 break; 999 case 4: //标记为4的时候处理减法 1000 GEN(OPR,0,3); 1001 flag = 0; 1002 break; 1003 default: 1004 flag = 0; 1005 break; 1006 } 1007 if(TABLE[i].KIND==ARRAY) 1008 GEN(SAR,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR); 1009 else 1010 GEN(STO,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR); 1011 } 1012 } 1013 1014 else Error(13); 1015 break; 1016 case READSYM: 1017 GetSym(); 1018 if (SYM!=LPAREN) Error(34); 1019 else 1020 do 1021 { 1022 GetSym(); 1023 if (SYM==IDENT) 1024 { 1025 i=POSITION(ID,TX); 1026 if (TABLE[i].KIND==ARRAY) /*ASSIGNMENT TO NON-VARIABLE*/ 1027 { 1028 GetSym(); 1029 if(SYM == LBK) 1030 { 1031 GetSym(); 1032 EXPRESSION(SymSetUnion(SymSetNew(RBK),FSYS),LEV,TX); 1033 GEN(LIT,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.SIZE); 1034 GEN(JUD,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR); 1035 GEN(DEL,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR); 1036 if(SYM != RBK) 1037 { 1038 Error(44); 1039 } 1040 } 1041 } 1042 } 1043 else i=0; 1044 if (i==0) Error(35); 1045 else //读入处理 1046 { 1047 switch(TABLE[i].TYPE) 1048 { 1049 case CHARCON: 1050 GEN(OPR,0,18); 1051 break; 1052 case INTCON: 1053 GEN(OPR,0,19); 1054 break; 1055 case REALCON: 1056 GEN(OPR,0,20); 1057 break; 1058 } 1059 if(TABLE[i].KIND==ARRAY) //判断是否是数组类型并 把栈顶内容放到数组或变量中 1060 GEN(SAR,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR); 1061 else 1062 GEN(STO,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR); 1063 } 1064 GetSym(); 1065 } 1066 while(SYM==COMMA); 1067 if (SYM!=RPAREN) 1068 { 1069 Error(33); 1070 while (!SymIn(SYM,FSYS)) GetSym(); 1071 } 1072 else GetSym(); 1073 break; /* READSYM */ 1074 case WRITESYM: 1075 GetSym(); 1076 if (SYM==LPAREN) 1077 { 1078 do 1079 { 1080 GetSym(); 1081 if (SYM==IDENT) 1082 { 1083 i=POSITION(ID,TX); 1084 if (TABLE[i].KIND==ARRAY) /*ASSIGNMENT TO NON-VARIABLE*/ 1085 { 1086 GetSym(); 1087 if(SYM == LBK) 1088 { 1089 GetSym(); 1090 EXPRESSION(SymSetUnion(SymSetNew(RBK),FSYS),LEV,TX); 1091 GEN(LIT,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.SIZE); 1092 GEN(JUD,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR); 1093 GEN(DEL,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR); 1094 if(SYM != RBK) 1095 { 1096 Error(44); 1097 } 1098 } 1099 } 1100 } 1101 else i=0; 1102 if (i==0) Error(35); 1103 else //输出处理 1104 { 1105 if(TABLE[i].KIND==ARRAY) //判断是否是数组类型并 把值栈顶 1106 GEN(GAR,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR); 1107 else 1108 GEN(LOD,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR); 1109 switch(TABLE[i].TYPE) 1110 { 1111 case CHARCON: 1112 GEN(OPR,0,14); 1113 break; 1114 case INTCON: 1115 GEN(OPR,0,15); 1116 break; 1117 case REALCON: 1118 GEN(OPR,0,16); 1119 break; 1120 } 1121 } 1122 GetSym(); 1123 } 1124 while(SYM==COMMA); 1125 if (SYM!=RPAREN) Error(33); 1126 else GetSym(); 1127 } 1128 break; /*WRITESYM*/ 1129 case CALLSYM: 1130 GetSym(); 1131 if (SYM!=IDENT) Error(14); 1132 else 1133 { 1134 i=POSITION(ID,TX); 1135 if (i==0) Error(11); 1136 else if (TABLE[i].KIND==PROCEDUR) 1137 GEN(CAL,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR); 1138 else Error(15); 1139 GetSym(); 1140 } 1141 break; 1142 case IFSYM: 1143 GetSym(); 1144 CONDITION(SymSetUnion(SymSetNew(THENSYM,DOSYM),FSYS),LEV,TX); 1145 if (SYM==THENSYM) 1146 GetSym(); 1147 else Error(16); 1148 CX1=CX; 1149 GEN(JPC,0,0); 1150 STATEMENT(SymSetUnion(SymSetNew(ELSESYM),FSYS),LEV,TX); 1151 1152 if(SYM!=ELSESYM) 1153 { 1154 CODE[CX1].A=CX; 1155 } 1156 else 1157 { 1158 GetSym(); 1159 CX2=CX; 1160 GEN(JMP,0,0); 1161 CODE[CX1].A=CX; 1162 STATEMENT(FSYS,LEV,TX); 1163 CODE[CX2].A=CX; 1164 } 1165 break; 1166 case BEGINSYM: 1167 GetSym(); 1168 STATEMENT(SymSetUnion(SymSetNew(SEMICOLON,ENDSYM),FSYS),LEV,TX); 1169 while (SymIn(SYM, SymSetAdd(SEMICOLON,STATBEGSYS))) 1170 { 1171 if (SYM==SEMICOLON) GetSym(); 1172 else Error(10); 1173 STATEMENT(SymSetUnion(SymSetNew(SEMICOLON,ENDSYM),FSYS),LEV,TX); 1174 } 1175 if (SYM==ENDSYM) GetSym(); 1176 else Error(17); 1177 break; 1178 case WHILESYM: 1179 CX1=CX; 1180 GetSym(); 1181 CONDITION(SymSetAdd(DOSYM,FSYS),LEV,TX); 1182 CX2=CX; 1183 GEN(JPC,0,0); 1184 if (SYM==DOSYM) GetSym(); 1185 else Error(18); 1186 STATEMENT(FSYS,LEV,TX); 1187 GEN(JMP,0,CX1); 1188 CODE[CX2].A=CX; 1189 break; 1190 /*添加代码*/ 1191 case FORSYM: 1192 GetSym(); 1193 if(SYM != IDENT) Error(38); 1194 else 1195 { 1196 i=POSITION(ID,TX); //查找名字的位置,找到则返回在名字表的位置,否则返回0 1197 if(i == 0) 1198 Error(11); 1199 else if (TABLE[i].KIND!=VARIABLE) /*判断是不是变量*/ 1200 { 1201 Error(12); 1202 i=0; 1203 } 1204 GetSym(); 1205 if(SYM == BECOMES) 1206 GetSym(); 1207 else Error(13); 1208 EXPRESSION(SymSetUnion(SymSetNew(STEPSYM,UNTILSYM,DOSYM),FSYS),LEV,TX); 1209 //把栈顶的值送到变量 1210 if(i != 0) 1211 //赋值,处理是i:=1 1212 GEN(STO,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR); 1213 if(SYM==STEPSYM) 1214 GetSym(); 1215 else Error(46); 1216 CX1=CX; //保存地址,等待回填 1217 GEN(JMP,0,0); //无条件跳转 1218 CX2=CX; 1219 EXPRESSION(SymSetUnion(SymSetNew(UNTILSYM,DOSYM),FSYS),LEV,TX); //表达式处理 1220 GEN(LOD,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR); //将变量送回栈顶 1221 GEN(OPR,0,2); //栈顶与次栈顶相加 1222 GEN(STO,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR);//把栈顶的值送到变量 1223 if(SYM==UNTILSYM) 1224 GetSym(); 1225 else Error(34); 1226 CODE[CX1].A=CX; //将当前地址回填 1227 EXPRESSION(SymSetUnion(SymSetNew(DOSYM),FSYS),LEV,TX);//终止条件 1228 GEN(LOD,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR); //将变量送回栈顶 1229 GEN(OPR,0,11); //判断栈顶跟次栈顶数据大小 1230 CX1=CX; //保存地址,等待回填 1231 GEN(JPC,0,0); //条件跳转,当栈顶布尔值非真则跳转,否则顺序执行 ,跳出程序 1232 if(SYM==DOSYM) 1233 GetSym(); 1234 else Error(34); 1235 STATEMENT(FSYS,LEV,TX); 1236 GEN(JMP,0,CX2); //无条件跳转到CX2处 1237 CODE[CX1].A=CX; //回填假出口 1238 } 1239 break; 1240 //修改statememt 添加 ++ -- 1241 case DPLUS: 1242 Form1->printfs("识别出++\n"); 1243 GetSym(); 1244 if(SYM==IDENT) 1245 { 1246 i=POSITION(ID,TX); 1247 if (i==0) Error(11); 1248 else if (TABLE[i].KIND!=VARIABLE) /*ASSIGNMENT TO NON-VARIABLE*/ 1249 { 1250 Error(36); 1251 i=0; 1252 } 1253 if(i!=0) 1254 { 1255 GEN(LOD,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR); 1256 GEN(LIT,0,1); 1257 GEN(OPR,0,2); 1258 GEN(STO,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR); 1259 } 1260 GetSym(); 1261 } 1262 else Error(36); 1263 break; 1264 case DMINUS: 1265 Form1->printfs("识别出--\n"); 1266 GetSym(); 1267 if(SYM==IDENT) 1268 { 1269 i=POSITION(ID,TX); 1270 if (i==0) Error(11); 1271 else if (TABLE[i].KIND!=VARIABLE) /*ASSIGNMENT TO NON-VARIABLE*/ 1272 { 1273 Error(36); 1274 i=0; 1275 } 1276 if(i!=0) 1277 { 1278 GEN(LOD,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR); 1279 GEN(LIT,0,1); 1280 GEN(OPR,0,3); 1281 GEN(STO,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR); 1282 } 1283 GetSym(); 1284 } 1285 else Error(36); 1286 break; 1287 } 1288 TEST(FSYS,SymSetNULL(),19); 1289 } /*STATEMENT*/ 1290 //--------------------------------------------------------------------------- 1291 void Block(int LEV, int TX, SYMSET FSYS) 1292 { 1293 int DX=3; /*DATA ALLOCATION INDEX*/ 1294 int TX0=TX; /*INITIAL TABLE INDEX*/ 1295 int CX0=CX; /*INITIAL CODE INDEX*/ 1296 TABLE[TX].vp.ADR=CX; 1297 GEN(JMP,0,0); 1298 if (LEV>LEVMAX) Error(32); 1299 do 1300 { 1301 if (SYM==CONSTSYM) 1302 { 1303 GetSym(); 1304 do 1305 { 1306 ConstDeclaration(LEV,TX,DX); 1307 while (SYM==COMMA) 1308 { 1309 GetSym(); 1310 ConstDeclaration(LEV,TX,DX); 1311 } 1312 if (SYM==SEMICOLON) GetSym(); 1313 else Error(5); 1314 } 1315 while(SYM==IDENT); 1316 } 1317 if (SYM==VARSYM) 1318 { 1319 GetSym(); 1320 do 1321 { 1322 VarDeclaration(LEV,TX,DX); 1323 while (SYM==COMMA) 1324 { 1325 GetSym(); 1326 VarDeclaration(LEV,TX,DX); 1327 } 1328 if (SYM==SEMICOLON) GetSym(); 1329 else Error(5); 1330 } 1331 while(SYM==IDENT); 1332 } 1333 while ( SYM==PROCSYM) 1334 { 1335 GetSym(); 1336 if (SYM==IDENT) 1337 { 1338 ENTER(PROCEDUR,LEV,TX,DX); 1339 GetSym(); 1340 } 1341 else Error(4); 1342 if (SYM==SEMICOLON) GetSym(); 1343 else Error(5); 1344 Block(LEV+1,TX,SymSetAdd(SEMICOLON,FSYS)); 1345 if (SYM==SEMICOLON) 1346 { 1347 GetSym(); 1348 TEST(SymSetUnion(SymSetNew(IDENT,PROCSYM),STATBEGSYS),FSYS,6); 1349 } 1350 else Error(5); 1351 } 1352 TEST(SymSetAdd(IDENT,STATBEGSYS), DECLBEGSYS,7); 1353 } 1354 while(SymIn(SYM,DECLBEGSYS)); 1355 CODE[TABLE[TX0].vp.ADR].A=CX; 1356 TABLE[TX0].vp.ADR=CX; /*START ADDR OF CODE*/ 1357 TABLE[TX0].vp.SIZE=DX; /*SIZE OF DATA SEGMENT*/ 1358 GEN(INI,0,DX); 1359 STATEMENT(SymSetUnion(SymSetNew(SEMICOLON,ENDSYM),FSYS),LEV,TX); 1360 GEN(OPR,0,0); /*RETURN*/ 1361 TEST(FSYS,SymSetNULL(),8); 1362 ListCode(CX0); 1363 } /*Block*/ 1364 //--------------------------------------------------------------------------- 1365 int BASE(int L,int B,float S[]) 1366 { 1367 int B1=B; /*FIND BASE L LEVELS DOWN*/ 1368 while (L>0) 1369 { 1370 B1=S[B1]; 1371 L=L-1; 1372 } 1373 return B1; 1374 } /*BASE*/ 1375 //--------------------------------------------------------------------------- 1376 void Interpret() 1377 { 1378 const STACKSIZE = 500; 1379 int P,B,T; /*PROGRAM BASE TOPSTACK REGISTERS*/ 1380 INSTRUCTION I; 1381 String s; 1382 float S[STACKSIZE]; /*DATASTORE*/ //int 1383 Form1->printfs("~~~ RUN PL0 ~~~"); 1384 fprintf(FOUT,"~~~ RUN PL0 ~~~\n"); 1385 T=0; 1386 B=1; 1387 P=0; 1388 S[1]=0; 1389 S[2]=0; 1390 S[3]=0; 1391 do 1392 { 1393 I=CODE[P]; 1394 P=P+1; 1395 switch (I.F) 1396 { 1397 case LIT: 1398 T++; 1399 S[T]=I.A; 1400 break; 1401 case OPR: 1402 switch ((int)I.A) /*OPERATOR*/ 1403 { 1404 case 0: /*RETURN*/ 1405 T=B-1; 1406 P=S[T+3]; 1407 B=S[T+2]; 1408 break; 1409 case 1: 1410 S[T]=-S[T]; 1411 break; 1412 case 2: 1413 T--; 1414 S[T]=S[T]+S[T+1]; 1415 break; 1416 case 3: 1417 T--; 1418 S[T]=S[T]-S[T+1]; 1419 break; 1420 case 4: 1421 T--; 1422 S[T]=S[T]*S[T+1]; 1423 break; 1424 case 5: 1425 T--; 1426 S[T]=S[T] / S[T+1]; 1427 break; 1428 case 6: 1429 S[T]=(S[T]/2!=0); 1430 break; 1431 case 8: 1432 T--; 1433 S[T]=S[T]==S[T+1]; 1434 break; 1435 case 9: 1436 T--; 1437 S[T]=S[T]!=S[T+1]; 1438 break; 1439 case 10: 1440 T--; 1441 S[T]=S[T]<S[T+1]; 1442 break; 1443 case 11: 1444 T--; 1445 S[T]=S[T]>=S[T+1]; 1446 break; 1447 case 12: 1448 T--; 1449 S[T]=S[T]>S[T+1]; 1450 break; 1451 case 13: 1452 T--; 1453 S[T]=S[T]<=S[T+1]; 1454 break; 1455 case 14: //字符输出 1456 Form1->printcs((char)S[T]); 1457 fprintf(FOUT,"%c\n",(char)S[T]); 1458 T--; 1459 break; 1460 case 15: //整数输出 1461 Form1->printls("",S[T]); 1462 fprintf(FOUT,"%d\n",(int)S[T]); 1463 T--; 1464 break; 1465 case 16: //实数输出 1466 s = FloatToStrF(S[T],ffNumber,8,6); 1467 Form1->printfs(s.c_str()); 1468 fprintf(FOUT,"%.2f\n",S[T]); 1469 T--; 1470 break; 1471 case 17: /*Form1->printfs(""); fprintf(FOUT,"\n"); */ break; 1472 case 18: //输入字符 1473 T++; 1474 s=InputBox("输入","输入字符:", 0); 1475 S[T] = (float)(*s.SubString(1,1).c_str()); 1476 Form1->printcs(‘ ‘); 1477 Form1->printcs((char)S[T]); 1478 fprintf(FOUT," %c\n",(char)S[T]); 1479 break; 1480 case 19: //输入整型 1481 T++; 1482 S[T]=InputBox("输入","输入整数:", 0).ToDouble(); 1483 while((S[T]-(int)S[T])!=0) { 1484 S[T]=InputBox("输入","输入整数:", 0).ToDouble(); 1485 } 1486 Form1->printrs("",S[T]); 1487 fprintf(FOUT,"? %f\n",S[T]); 1488 break; 1489 case 20: //输入实数 1490 T++; 1491 S[T]=InputBox("输入","输入实数:",0).ToDouble(); 1492 s = " " + FloatToStrF(S[T],ffNumber,8,6); 1493 Form1->printfs(s.c_str()); 1494 fprintf(FOUT,".2f\n",S[T]); 1495 break; 1496 } 1497 break; 1498 case LOD: 1499 T++; 1500 S[T]=S[(int)(BASE(I.L,B,S)+(int)I.A)]; 1501 break; 1502 case STO: 1503 S[(int)(BASE(I.L,B,S)+(int)I.A)]=S[T]; 1504 T--; 1505 break; 1506 case CAL: /*GENERAT NEW Block MARK*/ 1507 S[T+1]=BASE(I.L,B,S); 1508 S[T+2]=B; 1509 S[T+3]=P; 1510 B=T+1; 1511 P=I.A; 1512 break; 1513 case INI: 1514 T=T+I.A; 1515 break; 1516 case JMP: 1517 P=I.A; 1518 break; 1519 case JPC: 1520 if (S[T]==0) P=I.A; 1521 T--; 1522 break; 1523 //添加指令操作 1524 case GAR: 1525 S[T]=S[(int)(BASE(I.L,B,S)+I.A+S[T])]; 1526 break; 1527 case SAR: 1528 T--; S[(int)(BASE(I.L,B,S)+I.A+S[T])] = S[T+1]; T--; 1529 break; 1530 case TAR: 1531 T++; S[T]=S[(int)(BASE(I.L,B,S)+I.A+S[T-1])]; 1532 break; 1533 case DEL: 1534 T--; 1535 break; 1536 case JUD: 1537 S[T]=S[T-1]-S[T];if(S[T]>=0)Error(53); 1538 break; 1539 } /*switch*/ 1540 } 1541 while(P!=0); 1542 Form1->printfs("~~~ END PL0 ~~~"); 1543 fprintf(FOUT,"~~~ END PL0 ~~~\n"); 1544 } /*Interpret*/ 1545 //--------------------------------------------------------------------------- 1546 void __fastcall TForm1::ButtonRunClick(TObject *Sender) 1547 { 1548 for (CH=‘ ‘; CH<=‘^‘; CH++) SSYM[CH]=NUL; 1549 strcpy(KWORD[1],"BEGIN"); 1550 strcpy(KWORD[2],"CALL"); 1551 strcpy(KWORD[3],"CHAR"); 1552 strcpy(KWORD[4],"CONST"); 1553 strcpy(KWORD[5],"DMINUS"); 1554 strcpy(KWORD[6],"DO"); 1555 strcpy(KWORD[7],"DPLUS"); 1556 strcpy(KWORD[8],"ELSE"); 1557 strcpy(KWORD[9],"END"); 1558 strcpy(KWORD[10],"FOR"); 1559 strcpy(KWORD[11],"IF"); 1560 strcpy(KWORD[12],"INT"); 1561 strcpy(KWORD[13],"ODD"); 1562 strcpy(KWORD[14],"PROCEDURE"); 1563 strcpy(KWORD[15],"PROGRAM"); 1564 strcpy(KWORD[16],"READ"); 1565 strcpy(KWORD[17],"REAL"); 1566 strcpy(KWORD[18],"RETURN"); 1567 strcpy(KWORD[19],"STEP"); 1568 strcpy(KWORD[20],"THEN"); 1569 strcpy(KWORD[21],"UNTIL"); 1570 strcpy(KWORD[22],"VAR"); 1571 strcpy(KWORD[23],"WHILE"); 1572 strcpy(KWORD[24],"WRITE"); 1573 WSYM[1]=BEGINSYM; 1574 WSYM[2]=CALLSYM; 1575 WSYM[3]=CHARSYM; 1576 WSYM[4]=CONSTSYM; 1577 WSYM[5]=DMINUS; 1578 WSYM[6]=DOSYM; 1579 WSYM[7]=DPLUS; 1580 WSYM[8]=ELSESYM; 1581 WSYM[9]=ENDSYM; 1582 WSYM[10]=FORSYM; 1583 WSYM[11]=IFSYM; 1584 WSYM[12]=INTSYM; 1585 WSYM[13]=ODDSYM; 1586 WSYM[14]=PROCSYM; 1587 WSYM[15]=PROGSYM; 1588 WSYM[16]=READSYM; 1589 WSYM[17]=REALSYM; 1590 WSYM[18]=RETURNSYM; 1591 WSYM[19]=STEPSYM; 1592 WSYM[20]=THENSYM; 1593 WSYM[21]=UNTILSYM; 1594 WSYM[22]=VARSYM; 1595 WSYM[23]=WHILESYM; 1596 WSYM[24]=WRITESYM; 1597 1598 SSYM[‘+‘]=PLUS; 1599 SSYM[‘-‘]=MINUS; 1600 SSYM[‘*‘]=TIMES; 1601 SSYM[‘/‘]=SLASH; 1602 SSYM[‘(‘]=LPAREN; 1603 SSYM[‘)‘]=RPAREN; 1604 SSYM[‘=‘]=EQL; 1605 SSYM[‘,‘]=COMMA; 1606 SSYM[‘.‘]=PERIOD; //SSYM[‘#‘]=NEQ; 1607 SSYM[‘;‘]=SEMICOLON; 1608 SSYM[‘&‘]=AND; 1609 SSYM[‘!‘]=NOT; 1610 1611 SSYM[‘[‘]=LBK;//一维数组的左括号[ 1612 SSYM[‘]‘]=RBK;//一维数组的右括号] 1613 1614 1615 strcpy(MNEMONIC[LIT],"LIT"); 1616 strcpy(MNEMONIC[OPR],"OPR"); 1617 strcpy(MNEMONIC[LOD],"LOD"); 1618 strcpy(MNEMONIC[STO],"STO"); 1619 strcpy(MNEMONIC[CAL],"CAL"); 1620 strcpy(MNEMONIC[INI],"INI"); 1621 strcpy(MNEMONIC[JMP],"JMP"); 1622 strcpy(MNEMONIC[JPC],"JPC"); 1623 1624 strcpy(MNEMONIC[GAR],"GAR");//根据栈顶的偏移地址从数组中取值到新的栈顶(删除次栈顶,即偏移量) 1625 strcpy(MNEMONIC[TAR],"TAR");//根据栈顶的偏移地址从数组中取值到新的栈顶(不删除偏移量) 1626 strcpy(MNEMONIC[DEL],"DEL");//删除栈顶 1627 strcpy(MNEMONIC[SAR],"SAR");//根据次栈顶的偏移地址把栈顶的值存入数组 1628 strcpy(MNEMONIC[JUD],"JUD");//判断数组是否越界 1629 1630 DECLBEGSYS=(int*)malloc(sizeof(int)*SYMMAX); 1631 STATBEGSYS=(int*)malloc(sizeof(int)*SYMMAX); 1632 FACBEGSYS =(int*)malloc(sizeof(int)*SYMMAX); 1633 for(int j=0; j<SYMMAX; j++) 1634 { 1635 DECLBEGSYS[j]=0; 1636 STATBEGSYS[j]=0; 1637 FACBEGSYS[j] =0; 1638 } 1639 DECLBEGSYS[CONSTSYM]=1; 1640 DECLBEGSYS[VARSYM]=1; 1641 DECLBEGSYS[PROCSYM]=1; 1642 STATBEGSYS[BEGINSYM]=1; 1643 STATBEGSYS[CALLSYM]=1; 1644 STATBEGSYS[IFSYM]=1; 1645 STATBEGSYS[WHILESYM]=1; 1646 STATBEGSYS[WRITESYM]=1; 1647 FACBEGSYS[IDENT] =1; 1648 FACBEGSYS[NUMBER]=1; 1649 FACBEGSYS[LPAREN]=1; 1650 1651 //首先加入初始化开始符号集: 1652 STATBEGSYS[DPLUS]=1; 1653 STATBEGSYS[DMINUS]=1; 1654 FACBEGSYS[DPLUS]=1; 1655 FACBEGSYS[DMINUS]=1; 1656 1657 if ((FIN=fopen((Form1->EditName->Text+".PL0").c_str(),"r"))!=0) 1658 { 1659 FOUT=fopen((Form1->EditName->Text+".COD").c_str(),"w"); 1660 Form1->printfs("=== COMPILE PL0 ==="); 1661 fprintf(FOUT,"=== COMPILE PL0 ===\n"); 1662 ERR=0; 1663 CC=0; 1664 CX=0; 1665 LL=0; 1666 CH=‘ ‘; 1667 GetSym(); 1668 if (SYM!=PROGSYM) Error(0); 1669 else 1670 { 1671 GetSym(); 1672 if (SYM!=IDENT) Error(0); 1673 else 1674 { 1675 GetSym(); 1676 if (SYM!=SEMICOLON) Error(5); 1677 else GetSym(); 1678 } 1679 } 1680 Block(0,0,SymSetAdd(PERIOD,SymSetUnion(DECLBEGSYS,STATBEGSYS))); 1681 if (SYM!=PERIOD) Error(9); 1682 if (ERR==0) Interpret(); 1683 else 1684 { 1685 Form1->printfs("ERROR IN PL/0 PROGRAM"); 1686 fprintf(FOUT,"ERROR IN PL/0 PROGRAM"); 1687 } 1688 fprintf(FOUT,"\n"); 1689 fclose(FOUT); 1690 } 1691 } 1692 //---------------------------------------------------------------------------
时间: 2024-12-26 03:05:07