![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
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\t\t\t\tproduction"); 85 86 while(1) 87 { 88 //printf("\n"); 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!\n"); 104 break; 105 } 106 else if(yydefact[statenum] == 1) 107 { 108 printf("accept!\n"); 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!\n"); 127 break; 128 } 129 else if(yydefact[statenum] == 1) 130 { 131 printf("accept!\n"); 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\n"); 147 break; 148 } 149 else if(yytable[index] == 0) 150 { 151 if(yydefact[statenum] == 0) 152 { 153 printf("grammar error!\n"); 154 break; 155 } 156 else if(yydefact[statenum] == 1) 157 { 158 printf("accept!\n"); 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!\n",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("\n"); ///end 1098 */ 1099 1100 //printf("\n"); 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] = '\0'; 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] = '\0'; 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] = '\0'; 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] = '\0'; 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] = '\0'; 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 }
一、声明语句
声明变量类型可以为:整型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