码迷,mamicode.com
首页 > 其他好文 > 详细

编译原理课设参考

时间:2016-01-03 00:25:24      阅读:561      评论:0      收藏:0      [点我收藏+]

标签:

期末到了,忙课设好久了,在编译原理的课设上面走了好多的弯路,也好久没有碰前端的东西了,心感惭愧,那我就把我最近忙的一些东西贡献出来,希望可以帮助到那些感觉这门科目很难的同学,祝大家可以学好每一门学科~

  下面是我们学校的学习要求,我全部已经完成,时间仓促,大家仅供参考。转载请注明出处。

  

基本内容(成绩范围:“中”、“及格”或“不及格”)

(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 //---------------------------------------------------------------------------
View Code

 

编译原理课设参考

标签:

原文地址:http://www.cnblogs.com/zyyz/p/5095512.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!