⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 y.tab.c

📁 这是我自己实现的一个微小的编译程序,附可执行代码的虚拟机,是理解编译原理的绝好材料.
💻 C
📖 第 1 页 / 共 3 页
字号:
	//return TRUE;
}

void emitCode( enum code_ops operation, int src1 ,int src2 , int dest )
{ 
	code[code_off].op  = operation;
 	code[code_off].src1.isrc1 = src1;
 	code[code_off].src2 = src2;
 	code[code_off].dest = dest;
 	code_off++;
}

void emitFCode( enum code_ops operation, double src1 ,int src2 , int dest )
{
	code[code_off].op  = operation; 
 	code[code_off].src1.fsrc1 = src1;     
 	code[code_off].src2 = src2;     
 	code[code_off].dest = dest;     
 	code_off++;                     	
}

void backpatch( struct Jmplist * list, int jmp_dest)	/*把指令序号i所相应的指令地址回填到由指针p指向的转移指令中*/
{
	struct Jmplist * temp=list;			/*回填后释放内存,*/
	while(list!=NULL)
	{
		code[list->index].dest = jmp_dest;
		list=list->next;
		free(temp);				/*释放内存*/
		temp=list;
	}
}

struct Jmplist * merge(struct Jmplist * list1,struct Jmplist * list2)
{
	list1->next = list2;
	return list1;
}

struct Jmplist * makelist(int i)				/*建立仅含有指令诒i的新转移指令表,回头该表的指针*/
{
	struct Jmplist * list = (struct Jmplist *)malloc(sizeof(struct Jmplist));
	list->index = i;
	list->next = NULL;
	return list;
}

void yyerror(char * s)
{
	fflush(stdout);
	printf("ERROR:line %d",yylineno);
}
void type_error()
{
	printf("ERROR: line %d type error",yylineno);
}
#line 445 "y.tab.c"
#define YYABORT goto yyabort
#define YYACCEPT goto yyaccept
#define YYERROR goto yyerrlab

#if YYDEBUG
#ifdef __cplusplus
extern "C" char *getenv();
#else
extern char *getenv();
#endif
#endif

int
yyparse()
{
    register int yym, yyn, yystate;
    register YYSTYPE *yyvsp;
    register short *yyssp;
    short *yysse;
#if YYDEBUG
    register YYCONST char *yys;

    if (yys = getenv("YYDEBUG"))
    {
        yyn = *yys;
        if (yyn >= '0' && yyn <= '9')
            yydebug = yyn - '0';
    }
#endif

    yynerrs = 0;
    yyerrflag = 0;
    yychar = (-1);

    if (yyss == 0)
    {
        yyss = (short *) yymalloc (YYSTACKSIZE * sizeof (short));
        if (yyss == 0)
          goto yyabort;
        yyvs = (YYSTYPE *) yymalloc (YYSTACKSIZE * sizeof (YYSTYPE));
        if (yyvs == 0)
        {
            yyfree (yyss);
            goto yyabort;
        }
        yystacksize = YYSTACKSIZE;
    }
    yysse = yyss + yystacksize - 1;
    yyssp = yyss;
    yyvsp = yyvs;
    *yyssp = yystate = 0;
    goto yyloop;

yypush_lex:
    yyval = yylval;
    yystate = yytable[yyn];
yypush:
    if (yyssp >= yysse)
    {
        int depth = yyssp - yyss;
        if (yygrow() != 0)
             goto yyoverflow;
        yysse = yyss + yystacksize -1;
        yyssp = depth + yyss;
        yyvsp = depth + yyvs;
    }
    *++yyssp = yystate;
    *++yyvsp = yyval;

yyloop:
    if (yyn = yydefred[yystate]) goto yyreduce;
    yyn = yysindex[yystate];
    if (yychar < 0)
    {
        if ((yychar = yylex()) < 0) yychar = 0;
#if YYDEBUG
        if (yydebug)
        {
            yys = 0;
            if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
            if (!yys) yys = "illegal-symbol";
            printf("yydebug: state %d, reading %d (%s)\n", yystate,
                    yychar, yys);
        }
#endif
    }
    if (yyn != 0
        && ((yyn += yychar), ((unsigned)yyn <= (unsigned)YYTABLESIZE))
        && yycheck[yyn] == yychar)
    {
#if YYDEBUG
        if (yydebug)
            printf("yydebug: state %d, shifting to state %d\n",
                    yystate, yytable[yyn]);
#endif
        if (yyerrflag > 0)  --yyerrflag;
        yychar = (-1);
        goto yypush_lex;
    }
    yyn = yyrindex[yystate];
    if (yyn != 0
        && ((yyn += yychar), ((unsigned)yyn <= (unsigned)YYTABLESIZE))
        && yycheck[yyn] == yychar)
    {
        yyn = yytable[yyn];
        goto yyreduce;
    }
    if (yyerrflag) goto yyinrecovery;
#ifdef lint
    goto yynewerror;
#endif
yynewerror:
    yyerror("syntax error");
#ifdef lint
    goto yyerrlab;
#endif
yyerrlab:
    ++yynerrs;
yyinrecovery:
    if (yyerrflag < 3)
    {
        yyerrflag = 3;
        for (;;)
        {
            yyn = yysindex[*yyssp];
            if (yyn != 0
                && ((yyn += YYERRCODE), ((unsigned)yyn <= (unsigned)YYTABLESIZE))
                && yycheck[yyn] == YYERRCODE)
            {
#if YYDEBUG
                if (yydebug)
                    printf("yydebug: state %d, error recovery shifting\
 to state %d\n", *yyssp, yytable[yyn]);
#endif
                goto yypush_lex;
            }
            else
            {
#if YYDEBUG
                if (yydebug)
                    printf("yydebug: error recovery discarding state %d\n",
                            *yyssp);
#endif
                if (yyssp <= yyss) goto yyabort;
                --yyssp;
                --yyvsp;
            }
        }
    }
    else
    {
        if (yychar == 0) goto yyabort;
#if YYDEBUG
        if (yydebug)
        {
            yys = 0;
            if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
            if (!yys) yys = "illegal-symbol";
            printf("yydebug: state %d, error recovery discards token %d (%s)\n",
                    yystate, yychar, yys);
        }
#endif
        yychar = (-1);
        goto yyloop;
    }
yyreduce:
#if YYDEBUG
    if (yydebug)
        printf("yydebug: state %d, reducing by rule %d (%s)\n",
                yystate, yyn, yyrule[yyn]);
#endif
    yym = yylen[yyn];
    yyval = yyvsp[1-yym];
    switch (yyn)
    {
case 1:
#line 77 "grammer.y"
{int i;printf("sym_off(符号个数)=%d\ncode_off(代码行数)=%d\n",sym_off,code_off);YYACCEPT;}
break;
case 2:
#line 79 "grammer.y"
{offset = 0;}
break;
case 3:
#line 80 "grammer.y"
{}
break;
case 4:
#line 81 "grammer.y"
{}
break;
case 5:
#line 83 "grammer.y"
{int p = lookup(yyvsp[-2].idname);
							 if(p!=-1){printf("error: line %d variable %s redefinition",yylineno,name+yyvsp[-2].idname);exit(1);}
							 
							 /*$2.sym_off=p;*/
							 
							 enterID(sym_off,yyvsp[-2].idname,symtab[yyvsp[0].sym_off].type);
							 yyvsp[-2].sym_off=sym_off++;
							 addType(yyvsp[-2].sym_off,symtab[yyvsp[0].sym_off].type);/*变量合法,add type and alloc memery space*/}
break;
case 6:
#line 92 "grammer.y"
{yyval.sym_off=sym_off++;symtab[yyval.sym_off].type=REAL;}
break;
case 7:
#line 93 "grammer.y"
{yyval.sym_off=sym_off++;symtab[yyval.sym_off].type=INT;}
break;
case 8:
#line 95 "grammer.y"
{backpatch(symtab[yyvsp[-1].sym_off].nextlist,symtab[yyvsp[0].sym_off].place);}
break;
case 9:
#line 97 "grammer.y"
{yyval.sym_off=sym_off++;
							 symtab[yyval.sym_off].nextlist=symtab[yyvsp[-1].sym_off].nextlist;
							 }
break;
case 10:
#line 101 "grammer.y"
{backpatch(symtab[yyvsp[-3].sym_off].nextlist,symtab[yyvsp[-1].sym_off].place);
							 yyval.sym_off=yyvsp[0].sym_off;						}
break;
case 11:
#line 103 "grammer.y"
{yyval.sym_off=yyvsp[0].sym_off;}
break;
case 12:
#line 105 "grammer.y"
{yyval.sym_off=yyvsp[0].sym_off;}
break;
case 13:
#line 106 "grammer.y"
{yyval.sym_off=yyvsp[0].sym_off;}
break;
case 14:
#line 107 "grammer.y"
{yyval.sym_off=yyvsp[0].sym_off;}
break;
case 15:
#line 108 "grammer.y"
{yyval.sym_off=yyvsp[0].sym_off;}
break;
case 16:
#line 109 "grammer.y"
{yyval.sym_off=yyvsp[0].sym_off;}
break;
case 17:
#line 110 "grammer.y"
{yyval.sym_off=yyvsp[0].sym_off;}
break;
case 18:
#line 112 "grammer.y"
{if(symtab[yyvsp[-7].sym_off].type==BOOL/*&&symtab[$4.sym_off].type==symtab[$6.sym_off].type*/)
							 {/*不对语句设置类型*/
							  yyval.sym_off = sym_off++;
							  backpatch(symtab[yyvsp[-7].sym_off].truelist,symtab[yyvsp[-6].sym_off].place);
							  backpatch(symtab[yyvsp[-7].sym_off].falselist,symtab[yyvsp[-2].sym_off].place);
							  symtab[yyval.sym_off].nextlist = merge(symtab[yyvsp[-4].sym_off].nextlist,symtab[yyvsp[-1].sym_off].nextlist);
							  /*symtab[$$.sym_off].nextlist = merge(symtab[$$.sym_off].nextlist,symtab[$6.sym_off].nextlist); //开始按照教材上写,在ELSE前有符号N,再加上这一句,不能正确回填,去掉后正常*/
							 }
							 else type_error();}
break;
case 19:
#line 121 "grammer.y"
{if(symtab[yyvsp[-4].sym_off].type==BOOL)
							  {
							 	yyval.sym_off = sym_off++;
							 	backpatch(symtab[yyvsp[-4].sym_off].truelist,symtab[yyvsp[-3].sym_off].place);
							 	symtab[yyval.sym_off].nextlist=merge(symtab[yyvsp[-4].sym_off].falselist,symtab[yyvsp[-1].sym_off].nextlist);
							  }
							  else type_error();}
break;
case 20:
#line 129 "grammer.y"
{yyval.sym_off=sym_off++;symtab[yyval.sym_off].place=code_off;}
break;
case 21:
#line 131 "grammer.y"
{
								backpatch(symtab[yyvsp[0].sym_off].nextlist,symtab[yyvsp[-4].sym_off].place);
								backpatch(symtab[yyvsp[-3].sym_off].truelist,symtab[yyvsp[-1].sym_off].place);
								symtab[yyval.sym_off].nextlist=symtab[yyvsp[-3].sym_off].falselist;
								/*emitCode(op_jmp,-1,-1,symtab[$2.sym_off].place);*/
							}
break;
case 22:
#line 138 "grammer.y"
{int temp=0;
							 int p=lookup(yyvsp[-2].idname);
							 if(p==-1){printf("ERROR: line %d identifier %s undefined.",yylineno,name+yyvsp[-2].idname);exit(1);}
							 yyvsp[-2].sym_off=p;
							 yyval.sym_off=sym_off++;
							 
							 if(symtab[yyvsp[-2].sym_off].type==symtab[yyvsp[0].sym_off].type)
							 {
							 	symtab[yyval.sym_off].nextlist = makelist(code_off+1);
							 	emitCode(op_mov,symtab[yyvsp[0].sym_off].place,-1,symtab[yyvsp[-2].sym_off].place);
							 	emitCode(op_jmp,-1,-1,-1);
							 }
							 else if(symtab[yyvsp[-2].sym_off].type==REAL&&symtab[yyvsp[0].sym_off].type==INT)/*需要类型转换*/
							 {
							 	/*symtab[$3.sym_off].type=REAL;				//不能修改变量类型,原为bug*/
							 	symtab[yyval.sym_off].nextlist = makelist(code_off+3);
							 	temp=mem_off;
							 	emitCode(op_mov,symtab[yyvsp[0].sym_off].place,-1,temp);
							 	emitCode(op_inttoreal,temp,-1,temp);/*考虑到表达式的值只是临时变量,所以就在其上类型转换*/
							 	emitCode(op_mov,temp,-1,symtab[yyvsp[-2].sym_off].place);
							 	emitCode(op_jmp,-1,-1,-1);
							 }
							 else if(symtab[yyvsp[-2].sym_off].type==INT&&symtab[yyvsp[0].sym_off].type==REAL)/*需要类型转换*/
							 {
							 	/*symtab[$3.sym_off].type=INT;*/
							 	symtab[yyval.sym_off].nextlist = makelist(code_off+3);	/*此处设置不正确,导致bug*/
							 	temp=mem_off;
							 	emitCode(op_mov,symtab[yyvsp[0].sym_off].place,-1,temp);
							 	emitCode(op_realtoint,temp,-1,temp);/*考虑到表达式的值只是临时变量,所以就在其上类型转换*/
							 	emitCode(op_mov,temp,-1,symtab[yyvsp[-2].sym_off].place);
							 	emitCode(op_jmp,-1,-1,-1);
							 }
							 else type_error();}
break;
case 23:
#line 172 "grammer.y"
{int p=lookup(yyvsp[0].idname);
							 if(p==-1){printf("ERROR: line %d identifier %s is undefined.",yylineno,name+yyvsp[0].idname);exit(1);}
							 yyvsp[0].sym_off=p;
							 yyval.sym_off=sym_off++;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -