语义分析和中间代码生成——哈工大编译原理课程(三)

   1 /*
   2 Author:ZhouLiyan*
   3 Date:2016.08.01
   4 Loc:Haerbin Institute Of Technology
   5 */
   6 
   7 #include <stdio.h>
   8 #include <stdlib.h>
   9 #include <string.h>
  10 #include <ctype.h>
  11 #include <math.h>
  12 
  13 #include <token_analyze.h>
  14 #include <operator.h>
  15 #include <data_struct.h>
  16 #include <FourElemFormula.h>
  17 #include <table.h>
  18 #include <queue.h>
  19 #include <symboltable.h>
  20 #include <stack.h>
  21 #include <linkedlist.h>
  22 #include <debug.h>
  23 
  24 symtbl *initst;
  25 
  26 FILE *fp;   //获取文件的指针
  27 
  28 int newflag = 0;        //标志是否新读入一个token
  29 int tempcount = 0;
  30 
  31 stack s1;
  32 symstack s2;
  33 stack off;
  34 sstack tbl;
  35 queue idli;
  36 queue actualpali;
  37 intqueue indexli;
  38 
  39 pstack state = &s1;
  40 psymstack symbol = &s2;
  41 pstack offset = &off;
  42 psstack tblptr = &tbl;
  43 pqueue idlist = &idli;
  44 pqueue actualpalist = &actualpali;
  45 pintqueue indexlist = &indexli;
  46 Identifier *templink;           //存放临时变量的链表
  47 
  48 pFour fmlay[300]={NULL};           //typedef FourElemFormula* pFour
  49 int fmlap = 1;
  50 
  51 Token ReadToken();    /*make(返回结构体)从文件中读取一行,返回Token*/
  52 void Reduction_Goto(int k);     /*按第k个产生式规约*/
  53 Identifier* lookup(char *name,symtbl* nowsym);       /*返回name节点在符号表中的指针,如不存在返回null*/
  54 
  55 void gencode(int op,char *arg1,char *arg2,char* ret);
  56 void backpatch(LabelNode* lis,int labelnum);
  57 
  58 int main()
  59 {
  60     Token token = (Token)malloc(sizeof(To));
  61     int index;
  62     int statenum;
  63 
  64     MakeNull(state);
  65     MakeNullsym(symbol);
  66     MakeNull(offset);
  67     MakeNulls(tblptr);
  68     MakeNULLQueue(idlist);
  69     MakeNULLQueue(actualpalist);
  70     IntMakeNULLQueue(indexlist);
  71     initList(&templink);
  72 
  73     if(token_analyze() == 1)        //词法分析失败
  74     {
  75         return 0;
  76     }
  77 
  78 
  79     fp = fopen("lex.txt","r");
  80 
  81     token->symbolnum = 0;
  82     push(state,0);
  83     pushsym(symbol,token);
  84     //printf("stack				production");
  85 
  86     while(1)
  87     {
  88         //printf("
");
  89         //PrintStack(state);
  90         //printf("%c",'&');
  91         //PrintSymStack(symbol);
  92 
  93         if(newflag == 0)
  94         {
  95             token = ReadToken();
  96         }
  97         statenum = state->elem[state->top];
  98 
  99         if(yypact[statenum] == YYPACT_NINF)     /*按默认产生式规约*/
 100         {
 101             if(yydefact[statenum] == 0)
 102             {
 103                 printf("grammar error!
");
 104                 break;
 105             }
 106             else if(yydefact[statenum] == 1)
 107             {
 108                 printf("accept!
");
 109                 PrintSymTable(initst);
 110                 PrintFmla(fmlay,fmlap);
 111                 break;
 112             }
 113             else
 114             {
 115                 Reduction_Goto(yydefact[statenum]);
 116                 newflag = 1;
 117             }
 118         }
 119         else
 120         {
 121             index = yypact[statenum] + token->symbolnum;
 122             if((index >= LCHECK) || (yycheck[index] != token->symbolnum)) /*按默认产生式规约*/
 123             {
 124                 if(yydefact[statenum] == 0)
 125                 {
 126                     printf("grammar error!
");
 127                     break;
 128                 }
 129                 else if(yydefact[statenum] == 1)
 130                 {
 131                     printf("accept!
");
 132                     PrintSymTable(initst);
 133                     PrintFmla(fmlay,fmlap);
 134                     break;
 135                 }
 136                 else
 137                 {
 138                     Reduction_Goto(yydefact[statenum]);
 139                     newflag = 1;
 140                 }
 141             }
 142             else
 143             {
 144                 if(yytable[index] == YYTABLE_NINF)
 145                 {
 146                     printf("grammar error
");
 147                     break;
 148                 }
 149                 else if(yytable[index] == 0)
 150                 {
 151                     if(yydefact[statenum] == 0)
 152                     {
 153                         printf("grammar error!
");
 154                         break;
 155                     }
 156                     else if(yydefact[statenum] == 1)
 157                     {
 158                         printf("accept!
");
 159                         PrintSymTable(initst);
 160                         PrintFmla(fmlay,fmlap);
 161                         break;
 162                     }
 163                     else
 164                     {
 165                         Reduction_Goto(yydefact[statenum]);
 166                         newflag = 1;
 167                     }
 168                 }
 169                 else if(yytable[index] < 0)
 170                 {
 171                     Reduction_Goto(-yytable[index]);    /*按产生式规约,变负*/
 172                     newflag = 1;
 173                 }
 174                 else
 175                 {
 176                     push(state,yytable[index]);
 177                     pushsym(symbol,token);
 178                     newflag = 0;
 179                 }
 180             }
 181         }
 182     }
 183 
 184 
 185     clearFmlay(fmlay,fmlap);
 186     clearList(templink);
 187     fclose(fp);
 188     return 0;
 189 }
 190 
 191 
 192 void Reduction_Goto(int k)      /*按第k个产生式规约,k为正数,output文件编号加1才是k*/
 193 {
 194     int len = yyr2[k];
 195     int array[len];         /*array放产生式的右部各个元素*/
 196     int i,index;
 197     int symbolnum,statenum;
 198     Token t = (Token)malloc(sizeof(To));    //申请的空间不会被释放
 199     t->addr = NULL;
 200     t->offset = NULL;
 201     t->truelist = NULL;
 202     t->falselist = NULL;
 203     t->nextlist = NULL;
 204 
 205     symtbl *st;     /*翻译用的变量*/
 206     char id100[64];    //case 100
 207     char type47[64];
 208 
 209     int m;
 210     Identifier *temp = NULL;
 211 
 212     switch(k)
 213     {
 214     case 3:         //program: program_heading semicolon muldec_m1 block DOT
 215         {
 216             addwidth(tblptr->elem[tblptr->top],offset->elem[offset->top]);
 217             pops(tblptr);
 218             pop(offset);
 219             break;
 220         }
 221     case 4:         //muldec_m1: /* empty */
 222         {
 223             st = mktable(NULL);
 224             initst = st;
 225             pushs(tblptr,st);
 226             push(offset,0);
 227             break;
 228         }
 229     case 6:     //identifier_list: identifier_list comma identifier
 230         {
 231             Enqueue(idlist,symbol->elem[symbol->top]->name);
 232             break;
 233         }
 234     case 7:     //identifier_list:identifier
 235         {
 236             Enqueue(idlist,symbol->elem[symbol->top]->name);
 237             break;
 238         }
 239     case 9:    //constant: non_string
 240         {
 241             t->i = symbol->elem[symbol->top]->i;
 242             break;
 243         }
 244     case 10:    //constant: sign non_string
 245         {
 246             if(symbol->elem[symbol->top+1]->type == 0)
 247             {
 248                 t->i = symbol->elem[symbol->top]->i;
 249             }
 250             else    //==1
 251             {
 252                 t->i = -symbol->elem[symbol->top]->i;
 253             }
 254             break;
 255         }
 256     case 11:    //sign: PLUS
 257         {
 258             t->type = 0;
 259             break;
 260         }
 261     case 12:    //sign:MINUS
 262         {
 263             t->type = 1;
 264             break;
 265         }
 266     case 13:   // non_string: DIGSEQ
 267         {
 268             t->i = symbol->elem[symbol->top]->i;
 269             break;
 270         }
 271     case 14:        //type_denoter: identifier
 272         {
 273             strcpy(type47,symbol->elem[symbol->top]->name);
 274             if(strcmp(type47,"integer") == 0)
 275             {
 276                 t->type = 0;
 277                 t->i = 4;
 278             }
 279             else if(strcmp(type47,"real") == 0)
 280             {
 281                 t->type = 1;
 282                 t->i = 8;
 283             }
 284             break;
 285         }
 286     case 15:    //type_denoter:  new_type
 287         {
 288             t->type = symbol->elem[symbol->top]->type;
 289             t->i = symbol->elem[symbol->top]->i;
 290             break;
 291         }
 292     case 16:        //new_type:new_structured_type
 293         {
 294             t->type = symbol->elem[symbol->top]->type;
 295             t->i = symbol->elem[symbol->top]->i;
 296             break;
 297         }
 298     case 17:        //new_ordinal_type: subrange_type
 299         {
 300             t->i = symbol->elem[symbol->top]->i;
 301             t->type = symbol->elem[symbol->top]->type;
 302             break;
 303         }
 304     case 18:    //subrange_type: constant DOTDOT constant
 305         {
 306             t->i = symbol->elem[symbol->top]->i;
 307             t->type = symbol->elem[symbol->top+2]->i;
 308             break;
 309         }
 310     case 19:    //new_structured_type: structured_type
 311         {
 312             t->type = symbol->elem[symbol->top]->type;
 313             t->i = symbol->elem[symbol->top]->i;
 314             break;
 315         }
 316     case 20:    //structured_type: array_type
 317         {
 318             t->type = symbol->elem[symbol->top]->type;
 319             t->i = symbol->elem[symbol->top]->i;
 320             break;
 321         }
 322     case 21:        //array_type: ARRAY LBRAC index_list RBRAC OF component_type
 323         {
 324             t->type = symbol->elem[symbol->top]->type + 2;
 325             t->i = symbol->elem[symbol->top+3]->i * 4 * (symbol->elem[symbol->top]->type+1);
 326             break;
 327         }
 328     case 22:    //index_list: index_list comma index_type
 329         {
 330             t->i = symbol->elem[symbol->top+2]->i * (symbol->elem[symbol->top]->i - symbol->elem[symbol->top]->type+1);
 331             IntEnqueue(indexlist,symbol->elem[symbol->top]->type);
 332             IntEnqueue(indexlist,symbol->elem[symbol->top]->i);
 333             break;
 334         }
 335     case 23:    //index_list: index_type
 336         {
 337             t->i = symbol->elem[symbol->top]->i - symbol->elem[symbol->top]->type+1;
 338             IntEnqueue(indexlist,symbol->elem[symbol->top]->type);
 339             IntEnqueue(indexlist,symbol->elem[symbol->top]->i);
 340             break;
 341         }
 342     case 24:    //index_type: ordinal_type
 343         {
 344             t->i = symbol->elem[symbol->top]->i;
 345             t->type = symbol->elem[symbol->top]->type;
 346             break;
 347         }
 348     case 25:    //ordinal_type: new_ordinal_type
 349         {
 350             t->i = symbol->elem[symbol->top]->i;
 351             t->type = symbol->elem[symbol->top]->type;
 352             break;
 353         }
 354     case 26:    //component_type: type_denoter
 355         {
 356             t->type = symbol->elem[symbol->top]->type;
 357             break;
 358         }
 359     case 31:        //variable_declaration: identifier_list COLON type_denoter
 360         {
 361             while(Dequeue(idlist,id100) == 1)
 362             {
 363                 enter(tblptr->elem[tblptr->top],id100,symbol->elem[symbol->top]->type,offset->elem[offset->top],indexlist);
 364                 offset->elem[offset->top] = offset->elem[offset->top]+symbol->elem[symbol->top]->i;
 365             }
 366             break;
 367         }
 368     case 37:       //procedure_declaration:procedure_heading semicolon muldec_m2 procedure_block
 369         {
 370             st = tblptr->elem[tblptr->top];
 371             addwidth(st,offset->elem[offset->top]);
 372             pops(tblptr);
 373             pop(offset);
 374             enterproc(tblptr->elem[tblptr->top],symbol->elem[symbol->top+3]->name,st);    //需要词法分析器的第二个值id.name!!!!!
 375             break;
 376         }
 377     case 38:       //muldec_m2
 378         {
 379             st = mktable(tblptr->elem[tblptr->top]);
 380             pushs(tblptr,st);
 381             push(offset,0);
 382             break;
 383         }
 384     case 39:       //procedure_heading: procedure_identification
 385         {
 386             strcpy(t->name,symbol->elem[symbol->top]->name);
 387             break;
 388         }
 389     case 40:       //procedure_heading:procedure_identification formal_parameter_list
 390         {
 391             strcpy(t->name,symbol->elem[symbol->top+1]->name);
 392             break;
 393         }
 394     case 46:       //value_parameter_specification: identifier_list COLON identifier//just for correcting
 395         {
 396             MakeNULLQueue(idlist);
 397             break;
 398         }
 399     case 47:       //variable_parameter_specification: VAR identifier_list COLON identifier//just for correcting
 400         {
 401             MakeNULLQueue(idlist);
 402             break;
 403         }
 404     case 48:       //procedure_identification: PROCEDURE identifier
 405         {
 406             strcpy(t->name,symbol->elem[symbol->top]->name);
 407             break;
 408         }
 409 
 410 
 411 
 412     case 51:       //compound_statement: PBEGIN statement_sequence END
 413         {
 414             t->nextlist = symbol->elem[symbol->top+1]->nextlist;
 415             break;
 416         }
 417     case 52:       //statement_sequence: statement_sequence semicolon ctrl_m statement
 418         {
 419             backpatch(symbol->elem[symbol->top+3]->nextlist,symbol->elem[symbol->top+1]->quad);
 420             t->nextlist = symbol->elem[symbol->top]->nextlist;
 421             break;
 422         }
 423     case 53:       //statement_sequence: statement
 424         {
 425             t->nextlist = symbol->elem[symbol->top]->nextlist;
 426             break;
 427         }
 428     case 54:       //statement: open_statement
 429         {
 430             t->nextlist = symbol->elem[symbol->top]->nextlist;
 431             break;
 432         }
 433     case 55:       //statement: closed_statement
 434         {
 435             t->nextlist = symbol->elem[symbol->top]->nextlist;
 436             break;
 437         }
 438     case 56:       //open_statement: non_labeled_open_statement
 439         {
 440             t->nextlist = symbol->elem[symbol->top]->nextlist;
 441             break;
 442         }
 443     case 57:       //closed_statement: non_labeled_closed_statement
 444         {
 445             t->nextlist = symbol->elem[symbol->top]->nextlist;
 446             break;
 447         }
 448     case 60:       //non_labeled_closed_statement:compound_statement
 449         {
 450             t->nextlist = symbol->elem[symbol->top]->nextlist;
 451             break;
 452         }
 453     case 61:       //non_labeled_closed_statement: repeat_statement
 454         {
 455             t->nextlist = symbol->elem[symbol->top]->nextlist;
 456             break;
 457         }
 458     case 62:       //non_labeled_closed_statement:closed_if_statement
 459         {
 460             t->nextlist = symbol->elem[symbol->top]->nextlist;
 461             break;
 462         }
 463     case 63:       //non_labeled_closed_statement:closed_while_statement
 464         {
 465             t->nextlist = symbol->elem[symbol->top]->nextlist;
 466             break;
 467         }
 468     case 64:       //non_labeled_closed_statement: closed_for_statement
 469         {
 470             t->nextlist = symbol->elem[symbol->top]->nextlist;
 471             break;
 472         }
 473     case 66:       //non_labeled_open_statement:open_if_statement
 474         {
 475             t->nextlist = symbol->elem[symbol->top]->nextlist;
 476             break;
 477         }
 478     case 67:       //non_labeled_open_statement:open_while_statement
 479         {
 480             t->nextlist = symbol->elem[symbol->top]->nextlist;
 481             break;
 482         }
 483     case 68:       //non_labeled_open_statement: open_for_statement
 484         {
 485             t->nextlist = symbol->elem[symbol->top]->nextlist;
 486             break;
 487         }
 488 
 489     case 69:   //repeat_statement: REPEAT ctrl_m statement_sequence UNTIL repeat_n boolean_expression
 490         {
 491             backpatch(symbol->elem[symbol->top+3]->nextlist,symbol->elem[symbol->top+1]->quad);
 492             backpatch(symbol->elem[symbol->top]->falselist,symbol->elem[symbol->top+4]->quad);
 493             t->nextlist = symbol->elem[symbol->top]->truelist;
 494             break;
 495         }
 496 
 497     case 70:          //open_while_statement: WHILE ctrl_m boolean_expression DO ctrl_m open_statement
 498         {
 499             backpatch(symbol->elem[symbol->top]->nextlist,symbol->elem[symbol->top+4]->quad);
 500             backpatch(symbol->elem[symbol->top+3]->truelist,symbol->elem[symbol->top+1]->quad);
 501             t->nextlist = symbol->elem[symbol->top+3]->falselist;
 502             sprintf(id100,"%d",symbol->elem[symbol->top+4]->quad);
 503             gencode(GOTO,"-","-",id100);
 504             break;
 505         }
 506     case 71:       //closed_while_statement: WHILE ctrl_m boolean_expression DO ctrl_m closed_statement
 507         {
 508             backpatch(symbol->elem[symbol->top]->nextlist,symbol->elem[symbol->top+4]->quad);
 509             backpatch(symbol->elem[symbol->top+3]->truelist,symbol->elem[symbol->top+1]->quad);
 510             t->nextlist = symbol->elem[symbol->top+3]->falselist;
 511             sprintf(id100,"%d",symbol->elem[symbol->top+4]->quad);
 512             gencode(GOTO,"-","-",id100);
 513             break;
 514         }
 515     case 72:       //open_for_statement: FOR control_variable ASSIGNMENT initial_value direction final_value DO for_m open_statement
 516         {
 517             backpatch(symbol->elem[symbol->top]->nextlist,symbol->elem[symbol->top+1]->i);
 518             sprintf(id100,"%d",symbol->elem[symbol->top+1]->i);
 519             gencode(GOTO,"-","-",id100);
 520             t->nextlist = symbol->elem[symbol->top+1]->nextlist;
 521             break;
 522         }
 523     case 73:       //closed_for_statement: FOR control_variable ASSIGNMENT initial_value direction final_value DO for_m closed_statement
 524         {
 525             backpatch(symbol->elem[symbol->top]->nextlist,symbol->elem[symbol->top+1]->i);
 526             sprintf(id100,"%d",symbol->elem[symbol->top+1]->i);
 527             gencode(GOTO,"-","-",id100);
 528             t->nextlist = symbol->elem[symbol->top+1]->nextlist;
 529             break;
 530         }
 531     case 74:       //open_if_statement: IF boolean_expression THEN ctrl_m statement
 532         {
 533             backpatch(symbol->elem[symbol->top+3]->truelist,symbol->elem[symbol->top+1]->quad);
 534             mergelist(symbol->elem[symbol->top+3]->falselist,symbol->elem[symbol->top]->nextlist);
 535             t->nextlist = symbol->elem[symbol->top+3]->falselist;
 536             break;
 537         }
 538     case 75:   //open_if_statement: IF boolean_expression THEN ctrl_m closed_statement ctrl_n ELSE ctrl_m open_statement
 539         {
 540             backpatch(symbol->elem[symbol->top+7]->truelist,symbol->elem[symbol->top+5]->quad);
 541             backpatch(symbol->elem[symbol->top+7]->falselist,symbol->elem[symbol->top+1]->quad);
 542             mergelist(symbol->elem[symbol->top+3]->nextlist,symbol->elem[symbol->top]->nextlist);
 543             mergelist(symbol->elem[symbol->top+3]->nextlist,symbol->elem[symbol->top+4]->nextlist);
 544             t->nextlist = symbol->elem[symbol->top+3]->nextlist;
 545             break;
 546         }
 547     case 76:   //closed_if_statement: IF boolean_expression THEN ctrl_m closed_statement ctrl_n ELSE ctrl_m closed_statement
 548         {
 549             backpatch(symbol->elem[symbol->top+7]->truelist,symbol->elem[symbol->top+5]->quad);
 550             backpatch(symbol->elem[symbol->top+7]->falselist,symbol->elem[symbol->top+1]->quad);
 551             mergelist(symbol->elem[symbol->top+3]->nextlist,symbol->elem[symbol->top]->nextlist);
 552             mergelist(symbol->elem[symbol->top+3]->nextlist,symbol->elem[symbol->top+4]->nextlist);
 553             t->nextlist = symbol->elem[symbol->top+3]->nextlist;
 554             break;
 555         }
 556 
 557 
 558 
 559     case 77:           //assignment_statement: variable_access ASSIGNMENT expression
 560         {
 561             if(symbol->elem[symbol->top+2]->offset == NULL)
 562             {
 563                 gencode(ASSIGN,symbol->elem[symbol->top]->addr->name,"-",symbol->elem[symbol->top+2]->addr->name);
 564             }
 565             else
 566             {
 567                 gencode(OFFE,symbol->elem[symbol->top+2]->addr->name,symbol->elem[symbol->top+2]->offset->name,symbol->elem[symbol->top]->addr->name);
 568             }
 569             break;
 570         }
 571     case 78:               //variable_access: identifier
 572         {
 573             Identifier *idaddr = lookup(symbol->elem[symbol->top]->name,tblptr->elem[tblptr->top]);
 574             if(idaddr)
 575             {
 576                 t->addr = idaddr;
 577                 t->offset = NULL;
 578             }
 579             else
 580             {
 581                 printf("Variable %s wasn't defined in this procedure!
",symbol->elem[symbol->top]->name);
 582                 exit(1);
 583             }
 584             break;
 585         }
 586     case 79:           //variable_access: indexed_variable
 587         {
 588             t->addr = symbol->elem[symbol->top]->addr;
 589             t->offset = symbol->elem[symbol->top]->offset;
 590             break;
 591         }
 592     case 80:           //indexed_variable: index_expression_list RBRAC
 593         {
 594             t->addr = insertHeadList(&templink,&tempcount);
 595             t->offset = insertHeadList(&templink,&tempcount);
 596             itoa(*(symbol->elem[symbol->top+1]->offset->arrayex),id100,10);
 597             gencode(ASSIGN,id100,"-",t->addr->name);
 598             itoa(4*(symbol->elem[symbol->top+1]->offset->type-1),id100,10);
 599             gencode(MUL,symbol->elem[symbol->top+1]->addr->name,id100,t->offset->name);
 600             break;
 601         }
 602     case 81:           //index_expression_list: index_expression_list comma index_expression
 603         {
 604             temp = insertHeadList(&templink,&tempcount);
 605             m = symbol->elem[symbol->top+2]->i + 1;
 606             itoa(*(symbol->elem[symbol->top+2]->offset->arrayex+3+2*(m-1)),id100,10);
 607             gencode(MUL,symbol->elem[symbol->top+2]->addr->name,id100,temp->name);
 608             gencode(PLUS,temp->name,symbol->elem[symbol->top]->addr->name,temp->name);
 609             t->offset = symbol->elem[symbol->top+2]->offset;
 610             t->addr = temp;
 611             t->i = m;
 612             break;
 613         }
 614     case 82:          //index_expression_list: identifier LBRAC index_expression
 615         {
 616             Identifier *idaddr = lookup(symbol->elem[symbol->top+2]->name,tblptr->elem[tblptr->top]);
 617             if(idaddr == NULL)
 618             {
 619                 exit(1);
 620             }
 621             t->offset = idaddr;
 622             t->addr = symbol->elem[symbol->top]->addr;
 623             t->i = 1;
 624             break;
 625         }
 626     case 83:       //index_expression: expression
 627         {
 628             t->addr = symbol->elem[symbol->top]->addr;
 629             break;
 630         }
 631 
 632 
 633     case 84:       //procedure_statement: identifier params
 634         {
 635             m = 0;
 636             while(Dequeue(actualpalist,id100))
 637             {
 638                 m++;
 639                 gencode(PARAM,"-","-",id100);
 640             }
 641             sprintf(id100,"%d",m);
 642             if(strcmp(symbol->elem[symbol->top+1]->name,"read") == 0||strcmp(symbol->elem[symbol->top+1]->name,"readln") == 0)
 643             {
 644                 gencode(CALL,"SYSIN",id100,"-");
 645             }
 646             else if(strcmp(symbol->elem[symbol->top+1]->name,"write") == 0)     //1型
 647             {
 648                 gencode(CALL,"SYSOUT",id100,"1");
 649             }
 650             else if(strcmp(symbol->elem[symbol->top+1]->name,"writeln") == 0)   //2型
 651             {
 652                 gencode(CALL,"SYSOUT",id100,"2");
 653             }
 654             else
 655             {
 656                 gencode(CALL,symbol->elem[symbol->top+1]->name,id100,"-");
 657             }
 658             break;
 659         }
 660     case 85:       //procedure_statement: identifier
 661         {
 662             gencode(CALL,symbol->elem[symbol->top]->name,"0","-");
 663             break;
 664         }
 665     case 87:       //actual_parameter_list: actual_parameter_list comma actual_parameter
 666         {
 667             Enqueue(actualpalist,symbol->elem[symbol->top]->addr->name);
 668             break;
 669         }
 670     case 88:       //actual_parameter_list: actual_parameter
 671         {
 672             //MakeNULLQueue(actualpalist);
 673             Enqueue(actualpalist,symbol->elem[symbol->top]->addr->name);
 674             break;
 675         }
 676     case 89:       //actual_parameter: expression
 677         {
 678             t->addr = symbol->elem[symbol->top]->addr;
 679             break;
 680         }
 681 
 682 
 683     case 90:       //control_variable: identifier
 684         {
 685             strcpy(t->name,symbol->elem[symbol->top]->name);
 686             break;
 687         }
 688     case 91:       //initial_value: expression
 689         {
 690             t->addr = symbol->elem[symbol->top]->addr;
 691             break;
 692         }
 693     case 92:       //direction: TO
 694         {
 695             t->type = 0;
 696             break;
 697         }
 698     case 93:       //direction: DOWNTO
 699         {
 700             t->type = 1;
 701             break;
 702         }
 703     case 94:       //final_value: expression
 704         {
 705             t->addr = symbol->elem[symbol->top]->addr;
 706             break;
 707         }
 708 
 709 
 710     case 95:       //boolean_expression: expression
 711         {
 712             t->truelist = symbol->elem[symbol->top]->truelist;
 713             t->falselist = symbol->elem[symbol->top]->falselist;
 714             break;
 715         }
 716     case 96:       //expression: simple_expression
 717         {
 718             t->addr = symbol->elem[symbol->top]->addr;
 719             t->truelist = symbol->elem[symbol->top]->truelist;
 720             t->falselist = symbol->elem[symbol->top]->falselist;
 721             break;
 722         }
 723     case 97:       //expression: simple_expression relop simple_expression
 724         {
 725             t->truelist = makelist(fmlap);
 726             t->falselist = makelist(fmlap+1);
 727             switch(symbol->elem[symbol->top+1]->type)
 728             {
 729             case 0:     //EQUAL
 730                 {
 731                     gencode(EQ,symbol->elem[symbol->top+2]->addr->name,symbol->elem[symbol->top]->addr->name,"-");
 732                     break;
 733                 }
 734             case 1:     //NOTEQUAL
 735                 {
 736                     gencode(NE,symbol->elem[symbol->top+2]->addr->name,symbol->elem[symbol->top]->addr->name,"-");
 737                     break;
 738                 }
 739             case 2:     //LT
 740                 {
 741                     gencode(LT,symbol->elem[symbol->top+2]->addr->name,symbol->elem[symbol->top]->addr->name,"-");
 742                     break;
 743                 }
 744             case 3:     //GT
 745                 {
 746                     gencode(GT,symbol->elem[symbol->top+2]->addr->name,symbol->elem[symbol->top]->addr->name,"-");
 747                     break;
 748                 }
 749             case 4:     //LE
 750                 {
 751                     gencode(LE,symbol->elem[symbol->top+2]->addr->name,symbol->elem[symbol->top]->addr->name,"-");
 752                     break;
 753                 }
 754             case 5:     //GE
 755                 {
 756                     gencode(GE,symbol->elem[symbol->top+2]->addr->name,symbol->elem[symbol->top]->addr->name,"-");
 757                     break;
 758                 }
 759             }
 760             gencode(GOTO,"-","-","-");
 761             break;
 762         }
 763     case 98:       //simple_expression: term
 764         {
 765             t->addr = symbol->elem[symbol->top]->addr;
 766             t->truelist = symbol->elem[symbol->top]->truelist;
 767             t->falselist = symbol->elem[symbol->top]->falselist;
 768             break;
 769         }
 770     case 99:          //simple_expression: simple_expression addop boolean_m term
 771         {
 772             t->addr = insertHeadList(&templink,&tempcount);
 773             if(symbol->elem[symbol->top+2]->type == 0)          //+
 774             {
 775                 gencode(PLUS,symbol->elem[symbol->top+3]->addr->name,symbol->elem[symbol->top]->addr->name,t->addr->name);
 776             }
 777             if(symbol->elem[symbol->top+2]->type == 1)          //-
 778             {
 779                 gencode(SUB,symbol->elem[symbol->top+3]->addr->name,symbol->elem[symbol->top]->addr->name,t->addr->name);
 780             }
 781             if(symbol->elem[symbol->top+2]->type == 2)          //OR
 782             {
 783                 backpatch(symbol->elem[symbol->top+3]->falselist,symbol->elem[symbol->top+1]->quad);
 784                 clear_label_list(symbol->elem[symbol->top+3]->falselist);
 785                 mergelist(symbol->elem[symbol->top+3]->truelist,symbol->elem[symbol->top]->truelist);
 786                 t->truelist = symbol->elem[symbol->top+3]->truelist;
 787                 t->falselist = symbol->elem[symbol->top]->falselist;
 788             }
 789             break;
 790         }
 791     case 100:       //term: factor
 792         {
 793             t->addr = symbol->elem[symbol->top]->addr;
 794             t->truelist = symbol->elem[symbol->top]->truelist;
 795             t->falselist = symbol->elem[symbol->top]->falselist;
 796             break;
 797         }
 798     case 101:       //term: term mulop boolean_m factor //STAR SLASH DIV MOD AND
 799         {
 800             t->addr = insertHeadList(&templink,&tempcount);
 801             switch(symbol->elem[symbol->top+2]->s[0])
 802             {
 803             case '*':
 804                 {
 805                     gencode(MUL,symbol->elem[symbol->top+3]->addr->name,symbol->elem[symbol->top]->addr->name,t->addr->name);
 806                     break;
 807                 }
 808             case '/':
 809                 {
 810                     gencode(RDIV,symbol->elem[symbol->top+3]->addr->name,symbol->elem[symbol->top]->addr->name,t->addr->name);
 811                     break;
 812                 }
 813             case '\':
 814                 {
 815                     gencode(DIV,symbol->elem[symbol->top+3]->addr->name,symbol->elem[symbol->top]->addr->name,t->addr->name);
 816                     break;
 817                 }
 818             case '%':
 819                 {
 820                     gencode(MOD,symbol->elem[symbol->top+3]->addr->name,symbol->elem[symbol->top]->addr->name,t->addr->name);
 821                     break;
 822                 }
 823             case '&':
 824                 {
 825                     backpatch(symbol->elem[symbol->top+3]->truelist,symbol->elem[symbol->top+1]->quad);
 826                     clear_label_list(symbol->elem[symbol->top+3]->truelist);
 827                     t->truelist = symbol->elem[symbol->top]->truelist;
 828                     mergelist(symbol->elem[symbol->top+3]->falselist,symbol->elem[symbol->top]->falselist);
 829                     t->falselist = symbol->elem[symbol->top+3]->falselist;
 830                     break;
 831                 }
 832             }
 833             break;
 834         }
 835     case 102:       //factor: sign factor
 836         {
 837             t->addr = insertHeadList(&templink,&tempcount);
 838             if(symbol->elem[symbol->top+1]->type == 0)
 839             {
 840                 gencode(ASSIGN,symbol->elem[symbol->top]->addr->name,"-",t->addr->name);
 841             }
 842             if(symbol->elem[symbol->top+1]->type == 1)
 843             {
 844                 gencode(MINUS,symbol->elem[symbol->top]->addr->name,"-",t->addr->name);
 845             }
 846             break;
 847         }
 848     case 103:       //factor: exponentiation
 849         {
 850             t->addr = symbol->elem[symbol->top]->addr;
 851             t->truelist = symbol->elem[symbol->top]->truelist;
 852             t->falselist = symbol->elem[symbol->top]->falselist;
 853             break;
 854         }
 855     case 104:       //exponentiation: primary
 856         {
 857             t->addr = symbol->elem[symbol->top]->addr;
 858             t->truelist = symbol->elem[symbol->top]->truelist;
 859             t->falselist = symbol->elem[symbol->top]->falselist;
 860             break;
 861         }
 862     case 105:       //primary: variable_access
 863         {
 864             if(symbol->elem[symbol->top]->offset == NULL)       //简单变量
 865             {
 866                 t->addr = symbol->elem[symbol->top]->addr;
 867             }
 868             else
 869             {
 870                 t->addr = insertHeadList(&templink,&tempcount);
 871                 gencode(EOFF,symbol->elem[symbol->top]->addr->name,symbol->elem[symbol->top]->offset->name,t->addr->name);
 872             }
 873             break;
 874         }
 875     case 106:       //primary: unsigned_constant
 876         {
 877             t->addr = insertHeadList(&templink,&tempcount);
 878             if(symbol->elem[symbol->top]->type == 0)            //integer
 879             {
 880                 itoa(symbol->elem[symbol->top]->i,id100,10);
 881                 gencode(ASSIGN,id100,"-",t->addr->name);
 882             }
 883             if(symbol->elem[symbol->top]->type == 1)            //real
 884             {
 885                 sprintf(id100,"%f",symbol->elem[symbol->top]->f);
 886                 gencode(ASSIGN,id100,"-",t->addr->name);
 887             }
 888             if(symbol->elem[symbol->top]->type == 2)        //CHARACTER_STRING
 889             {
 890                 gencode(ASSIGN,symbol->elem[symbol->top]->s,"-",t->addr->name);
 891             }
 892             break;
 893         }
 894     case 107:       //primary: LPAREN expression RPAREN
 895         {
 896             t->addr = symbol->elem[symbol->top+1]->addr;
 897             t->truelist = symbol->elem[symbol->top+1]->truelist;
 898             t->falselist = symbol->elem[symbol->top+1]->falselist;
 899             break;
 900         }
 901     case 108:       //primary: NOT primary
 902         {
 903             t->truelist = symbol->elem[symbol->top]->falselist;
 904             t->falselist = symbol->elem[symbol->top]->truelist;
 905             break;
 906         }
 907 
 908 
 909     case 109:       //unsigned_constant: unsigned_number
 910         {
 911             if(symbol->elem[symbol->top]->type == 0)
 912             {
 913                 t->type = 0;
 914                 t->i = symbol->elem[symbol->top]->i;
 915             }
 916             if(symbol->elem[symbol->top]->type == 1)
 917             {
 918                 t->type = 1;
 919                 t->f = symbol->elem[symbol->top]->f;
 920             }
 921             break;
 922         }
 923     case 110:       //unsigned_constant: CHARACTER_STRING
 924         {
 925             t->type = 2;
 926             strcpy(t->s,symbol->elem[symbol->top]->s);
 927             break;
 928         }
 929     case 111:       //unsigned_number: unsigned_integer
 930         {
 931             t->type = 0;
 932             t->i = symbol->elem[symbol->top]->i;
 933             break;
 934         }
 935     case 112:       //unsigned_number: unsigned_real
 936         {
 937             t->type = 1;
 938             t->f = symbol->elem[symbol->top]->f;
 939             break;
 940         }
 941     case 113:       //unsigned_integer: DIGSEQ
 942         {
 943             t->i = symbol->elem[symbol->top]->i;
 944             break;
 945         }
 946     case 114:       //unsigned_real: REALNUMBER
 947         {
 948             t->f = symbol->elem[symbol->top]->f;
 949             break;
 950         }
 951 
 952     case 115:       //addop: PLUS
 953         {
 954             t->type = 0;
 955             break;
 956         }
 957     case 116:       //addop: MINUS
 958         {
 959             t->type = 1;
 960             break;
 961         }
 962     case 117:       //addop: OR
 963         {
 964             t->type = 2;
 965             break;
 966         }
 967     case 118:       //mulop: STAR
 968         {
 969             t->s[0] = '*';
 970             break;
 971         }
 972     case 119:       //mulop: SLASH
 973         {
 974             t->s[0] = '/';
 975             break;
 976         }
 977     case 120:       //mulop: DIV
 978         {
 979             t->s[0] = '\';
 980             break;
 981         }
 982     case 121:       //mulop: MOD
 983         {
 984             t->s[0] = '%';
 985             break;
 986         }
 987     case 122:       //mulop: AND
 988         {
 989             t->s[0] = '&';
 990             break;
 991         }
 992 
 993     case 123:       //relop: EQUAL
 994         {
 995             t->type = 0;
 996             break;
 997         }
 998     case 124:       //relop: NOTEQUAL
 999         {
1000             t->type = 1;
1001             break;
1002         }
1003     case 125:       //relop: LT
1004         {
1005             t->type = 2;
1006             break;
1007         }
1008     case 126:       //relop: GT
1009         {
1010             t->type = 3;
1011             break;
1012         }
1013     case 127:       //relop:LE
1014         {
1015             t->type = 4;
1016             break;
1017         }
1018     case 128:       //relop: GE
1019         {
1020             t->type = 5;
1021             break;
1022         }
1023 
1024     case 129:       //identifier: IDENTIFIER
1025         {
1026             strcpy(t->name,symbol->elem[symbol->top]->name);
1027             break;
1028         }
1029 
1030     case 132:       //boolean_m: /* empty */
1031         {
1032             t->quad = fmlap;
1033             break;
1034         }
1035     case 133:       //ctrl_m: /* empty */
1036         {
1037             t->quad = fmlap;
1038             break;
1039         }
1040     case 134:       //ctrl_n: /* empty */
1041         {
1042             t->nextlist = makelist(fmlap);
1043             gencode(GOTO,"-","-","-");
1044             break;
1045         }
1046     case 135:       //repeat_n: /* empty */
1047         {
1048             t->quad = fmlap;
1049             break;
1050         }
1051     case 136:       //for_m: /* empty */ stack:FOR control_variable ASSIGNMENT initial_value direction final_value DO ..
1052         {
1053             strcpy(t->name,symbol->elem[symbol->top+5]->name);      //id
1054             gencode(ASSIGN,symbol->elem[symbol->top+3]->addr->name,"-",t->name);
1055             temp = insertHeadList(&templink,&tempcount);            //final_value
1056             gencode(ASSIGN,symbol->elem[symbol->top+1]->addr->name,"-",temp->name);
1057             m = fmlap;
1058             sprintf(id100,"%d",m+2);
1059             gencode(GOTO,"-","-",id100);
1060             t->i = m+1;
1061 
1062             if(symbol->elem[symbol->top+2]->type == 0)        //to
1063             {
1064                 gencode(PLUS,t->name,"1",t->name);
1065                 gencode(GT,t->name,temp->name,"-");
1066             }
1067             else if(symbol->elem[symbol->top+2]->type == 1)     //downto
1068             {
1069                 gencode(SUB,t->name,"1",t->name);
1070                 gencode(LT,t->name,temp->name,"-");
1071             }
1072             t->nextlist = makelist(fmlap-1);
1073             break;
1074         }
1075     }
1076 
1077 
1078     for(i = 0;i < len;i++)
1079     {
1080         pop(state);
1081     }
1082     for(i = 0;i < len;i++)
1083     {
1084         array[i] = popsym(symbol);
1085     }
1086     t->symbolnum = yyr1[k];
1087     pushsym(symbol,t);
1088 
1089     //printf("&&");
1090     /*
1091     printf("%s",yytname[yyr1[k]]);      //begin打印产生式
1092     printf("%s","->");
1093     for(i = len - 1 ;i >= 0;i--)
1094     {
1095         printf("%s ",yytname[array[i]]);
1096     }
1097     printf("
");                       ///end
1098     */
1099 
1100     //printf("
");
1101     //PrintStack(state);
1102     //printf("%c",'&');
1103     //PrintSymStack(symbol);
1104 
1105     symbolnum = symbol->elem[symbol->top]->symbolnum - TN;    /*执行goto动作*/
1106     statenum = state->elem[state->top];
1107 
1108     if(yypgoto[symbolnum] == YYPACT_NINF)
1109     {
1110         push(state,yydefgoto[symbolnum]);
1111     }
1112     else
1113     {
1114         index = yypgoto[symbolnum] + statenum;
1115         if((index >= LCHECK) || (yycheck[index] != statenum))
1116         {
1117             push(state,yydefgoto[symbolnum]);
1118         }
1119         else
1120         {
1121             push(state,yytable[index]);
1122         }
1123     }
1124 }
1125 
1126 Token ReadToken()
1127 {
1128     char strLine[1024];
1129     char n1[10];
1130     char n2[1027];
1131     int i=0,j=0;
1132     int t1;
1133     Token rt = (Token)malloc(sizeof(To));
1134     rt->addr = NULL;
1135     rt->offset = NULL;
1136     rt->truelist = NULL;
1137     rt->falselist = NULL;
1138     rt->nextlist = NULL;
1139 
1140     if(feof(fp)||(NULL == fgets(strLine,1024,fp)))
1141     {
1142         rt->symbolnum = 0;
1143         return rt;
1144     }
1145 
1146     for(i=1;;i++)
1147     {
1148         if(strLine[i] == ',')
1149         {
1150             n1[i-1] = '';
1151             t1 = atoi(n1);
1152             break;
1153         }
1154         n1[i-1] = strLine[i];
1155     }
1156     rt->symbolnum = yytranslate[t1];
1157     i++;
1158 
1159     switch(t1)
1160     {
1161     case 36:        //id
1162         {
1163             while(strLine[i] != ')')
1164             {
1165                 n2[j] = strLine[i];
1166                 j++;
1167                 i++;
1168             }
1169             n2[j] = '';
1170             strcpy(rt->name,n2);
1171             break;
1172         }
1173     case 37:        //int
1174         {
1175             while(strLine[i] != ')')
1176             {
1177                 n2[j] = strLine[i];
1178                 j++;
1179                 i++;
1180             }
1181             n2[j] = '';
1182             rt->i = atoi(n2);
1183             break;
1184         }
1185     case 38:        //float
1186         {
1187             while(strLine[i] != ')')
1188             {
1189                 n2[j] = strLine[i];
1190                 j++;
1191                 i++;
1192             }
1193             n2[j] = '';
1194             rt->f = atof(n2);
1195             break;
1196         }
1197     case 39:        //string
1198         {
1199             while(strLine[i] != ')')
1200             {
1201                 n2[j] = strLine[i];
1202                 j++;
1203                 i++;
1204             }
1205             n2[j] = '';
1206             strcpy(rt->s,n2);
1207             break;
1208         }
1209     }
1210     return rt;
1211 }
1212 
1213 
1214 void gencode(int op,char *arg1,char *arg2,char* ret)
1215 {
1216     fmlay[fmlap] = (pFour)malloc(sizeof(FourElemFormula));
1217     fmlay[fmlap]->op = op;
1218     strcpy(fmlay[fmlap]->arg1,arg1);
1219     strcpy(fmlay[fmlap]->arg2,arg2);
1220     strcpy(fmlay[fmlap]->ret,ret);
1221     fmlap++;
1222 }
1223 
1224 void backpatch(LabelNode* lis,int labelnum)
1225 {
1226     LabelNode* t = lis;
1227     char numstr[60];
1228     sprintf(numstr,"%d",labelnum);
1229 
1230     while(t != NULL)
1231     {
1232         strcpy(fmlay[t->label]->ret,numstr);
1233         t = t->next;
1234     }
1235 }
analysis&generate

一、声明语句

声明变量类型可以为:整型integer(type=0)、实型real(type=1)、整型数组array[] of integer

(type=2)、实型数组array[] of real(type=3)

支持嵌套过程,支持多维数组

基本思想为:需要三种数据结构:符号表(其结构见《符号表管理器》一节)、offset栈(整型)、tblptr栈(符号表指针型)。当遇到过程声明语句时,首先创建一张新的符号表,并在该符号表中为过程的名字创建相应的表项。新表中还有一个指针指向外围过程的符号表。同时初始化栈tblptr,将0压入offset栈中;当遇到一个过程声明语句时,执行的动作基本相同,还需要在外围过程的符号表中为过程创建一个新表项。当规约过程/进程语句结束后,将offset栈中的和填入tblptr中,弹出offset和tblptr中的一个元素;当遇到一条声明语句时,把对应的变量名和一些属性填入符号表中,增加offset栈顶的值。

例如如下的声明语句产生的符号表为

program TowersofHanoi;

var

   numdiscs : integer;

   num : real;

procedure DoTowers (NumDiscs, OrigPeg, NewPeg, TempPeg : integer);

var

   a,b : real;

   A : array[1..10,2..6,3..5] of real;

   c : integer;

   B : array[-3..6,5..9,7..16] of integer;

   d : real;

begin

   ……

end;

begin 

  ……

end.

 

此输出结果是为了方便观察符号表,实际的总体程序中这部分输出是不必要的

对于普通变量来说,打印它的名字、偏移、类型;对于数组变量来说,打印它的名字、维数ndim、每一维的最小下标值和维长。

二、赋值语句

支持数组元素的赋值

一维数组:addr(A[i])=(base-low1*w)+i*w=c+i*w,其中c是存放在符号表中数组元素的对应的表项中的

二维数组:addr(A[i1,i2])= base-(low1* n2 -low2)*w +(i1 * n2 + i2)*w=c+(i1*n2+i2)*w

其中c是存放在符号表中数组元素的对应的表项中的

多维数组:情形与二维数组类似

生成的中间代码形式为 语句标号:语句

基本思想:赋值语句的翻译结果是产生对应的中间代码。语句的左部可以使普通变量,也可以是数组元素,语句的右部可以是表达式,也可以是普通变量或数组元素。对于普通变量的翻译来说相对比较简单;对于数组元素的翻译需要根据其基地址和offset产生相应的中间代码。

例如对如下程序中的赋值语句产生的中间代码为

program Fibonacci;

var

   Fibonacci1, Fibonacci2 : integer;

   temp : integer;

   count : integer;

procedure DoTowers;

var

     M:integer;

     A : array[1..5, 1..10] of integer;

     B : real;

    

begin

     M := 9;

    A[1,10] := M;

    B := M + A[1,10];

end;

begin

   count := 0;

   Fibonacci1 := 0;

      Fibonacci2 := 1;

       repeat

      write (Fibonacci2:7);

      temp := Fibonacci2;

      Fibonacci2 := Fibonacci1 + Fibonacci2;

      Fibonacci1 := temp;

      count := count + 1

   until count = 10;

   if not (temp = 10) or (temp * 2 > 70) then

   begin

   writeln('a is not less than 20' );

   writeln (',');

   end

else

     begin

     writeln('a is not less than 20' );

     writeln('value of a is : ', count);

     end;

   writeln;

end.

中间代码imcode.txt:

 

三、布尔表达式(采用回填式翻译)

支持的运算符有:and/or/not/</>/<=/>=/!=/=

例如以下的布尔表达式生成的中间代码为

   repeat

     …

   until count = 10;

   if (temp = 10) and not (temp * 2 > 70) then

     begin

        writeln (' a is not less than 20');

     end;

   writeln;

中间代码

 

四、 if/while/for/repeat(采用回填式翻译)

①if-then语句                                          if-then-else语句

生成的代码结构为                                     生成的代码结构为

         

②while和for语句

④repeat语句

 

中间代码生成具体情况详见code.txt生成的中间代码imcode.txt

五、过程调用语句call id(E1, E2, …, En)

生成的中间代码形式为

param E1.addr

param E2.addr

……

param En.addr

call id.addr, n

六、输入输出语句

是特殊的过程调用语句,与普通过程调用语句的区别在于需要调用系统的输入输出函数SYSIN和SYSOUT

read/readln(En)生成的中间代码形式为

param En

call SYSIN,1

write(E1, E2)生成的中间代码形式为

param E1.addr

param E2.addr

call SYSOUT,2,1

writeln (E1, E2)生成的中间代码形式为

param E1.addr

param E2.addr

call SYSOUT,2,2

原文地址:https://www.cnblogs.com/zhouliyan/p/5941756.html