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

📄 y.tab.c

📁 简单实现C--语言的编译器
💻 C
📖 第 1 页 / 共 5 页
字号:
       	yyval._expr.is_const = 1;
		if(yyvsp[-2]._expr.type != INT && yyvsp[-2]._expr.type != CHAR || yyvsp[0]._expr.type != INT && yyvsp[0]._expr.type != CHAR ){
			fprintf(errfile,"line %d : type unexpected \n",nline);
		 	is_error++; 
			return 0 ;
		}
       	else{
			yyval._expr.type = INT;	
              	if (yyvsp[-1]._op == '+')   yyval._expr.value = yyvsp[-2]._expr.value + yyvsp[0]._expr.value;  /* .value属性表示其值 */
			else   yyval._expr.value = yyvsp[-2]._expr.value - yyvsp[0]._expr.value; 
       	}
	} 
	else {  /* 存在未知变量*/
              op = (yyvsp[-1]._op == '+')? "add" : "sub";
              yyval._expr.place = newtemp();  /* 申请一个临时变元t? */
              yyval._expr.is_const = 0;
              is_one_var = 0;
	
		/* load the first oprand(操作数) */
              if (yyvsp[-2]._expr.is_const)    sprintf(code, "    mov     eax, %d\n", yyvsp[-2]._expr.value); 
		else{
			sprintf(code, "    	mov    eax, dword ptr [ebp-%d];%s\n", yyvsp[-2]._expr.place->offset + 4, yyvsp[-2]._expr.place->name);  
              }
		len = strlen(code);

		if (yyvsp[0]._expr.is_const)    sprintf(&code[len], "	%s	eax, %d\n", op, yyvsp[0]._expr.value); /*add  eax, ..*/
		else{
			sprintf(&code[len], "	%s	eax, dword ptr [ebp-%d] ;%s\n", op,yyvsp[0]._expr.place->offset+4,yyvsp[0]._expr.place->name);  /* 或 sub  eax, ...*/
		}
		len = strlen(code);                                               
              sprintf(&code[len],"	mov	dword ptr [ebp-%d], eax	;%s\n", yyval._expr.place->offset+4, yyval._expr.place->name);  
							/* mov	[ebp-..],eax;%s   其中%s 为[]地址上对应的变元的name  */
              yyval._expr.code = (char *)malloc(strlen(code)+1);
              strcpy(yyval._expr.code, code);  
	}
       }
break;
case 52:
#line 1203 "c--.y"
{  
	char code[1000]; 
       int len;
       char *op; 

	if (verbose) fprintf(stderr, "term => term mulop unary_expr   mulop=%c\n", yyvsp[-1]._op);  
	if (yyvsp[-2]._expr.is_const && yyvsp[0]._expr.is_const) {  /* constant folding */
              yyval._expr.is_const = 1;
		if(yyvsp[-2]._expr.type != INT && yyvsp[-2]._expr.type != CHAR || yyvsp[0]._expr.type != INT && yyvsp[0]._expr.type != CHAR ){
			fprintf(errfile,"line %d : type unexpected \n",nline);
			is_error++; 
			return 0;
		}
		else{
			yyval._expr.type = INT; 
              	if (yyvsp[-1]._op == '*')	yyval._expr.value = yyvsp[-2]._expr.value * yyvsp[0]._expr.value; 
			else if(yyvsp[-1]._op == '/'){
				if(yyvsp[0]._expr.value == 0) fprintf(errfile,"line %d : fatal error by 0\n",nline);
				yyval._expr.value = yyvsp[-2]._expr.value / yyvsp[0]._expr.value; 
			}
			else     yyval._expr.value = yyvsp[-2]._expr.value % yyvsp[0]._expr.value; 
        	}
	}
	else {
              yyval._expr.place = newtemp();  /* 申请一个临时变元t */
              yyval._expr.is_const = 0;
             
		if(yyvsp[-1]._op == '%') op = "mod";   /*汇编好象没这个??*/
              else op = (yyvsp[-1]._op == '*')? "mul" : "div";
 
		if (yyvsp[-2]._expr.is_const)    sprintf(code, "    mov     eax, %d\n", yyvsp[-2]._expr.value); 
		else{
			sprintf(code, "    mov    eax, dword ptr [ebp-%d];%s\n", yyvsp[-2]._expr.place->offset + 4, yyvsp[-2]._expr.place->name);  
      			len = strlen(code);
              }

		if (yyvsp[0]._expr.is_const)    sprintf(&code[len], "		%s	eax, %d\n", op, yyvsp[0]._expr.value); /*add  eax, ..*/
		else{
			sprintf(&code[len], "	%s	dword ptr [ebp-%d] ;%s\n", op,yyvsp[0]._expr.place->offset+4,yyvsp[0]._expr.place->name); 
			len = strlen(code);                                               
		}
              sprintf(&code[len],"	mov	dword ptr [ebp-%d], eax	;%s\n", yyval._expr.place->offset+4, yyval._expr.place->name);   /* z这里只考虑没进位的情况,乘的结果保留在低位*/
							/* mov	[ebp-..],eax;%s   其中%s 为[]地址上对应的变元的name  */
              yyval._expr.code = (char *)malloc(strlen(code)+1);
              strcpy(yyval._expr.code, code); 
       } 
      	}
break;
case 54:
#line 1254 "c--.y"
{  
	char code [1000];
       int len;
       char *op;

	trace("unary_expr => unaryop unary_expr\n");  
	if(yyvsp[0]._expr.is_const) {
		yyval._expr.is_const = 1;
		if(yyvsp[0]._expr.type != INT && yyvsp[0]._expr.type != CHAR){
			fprintf(errfile,"line %d : type unexpected \n",nline);
			is_error++; 
			return 0;
		}
 		else{	
			yyval._expr.type = INT;
			if (yyvsp[-1]._op == '!'){
				if(yyvsp[0]._expr.value == 1 )	yyval._expr.value =  0;  /*   '!'*/
				else   yyval._expr.value = 0 ;
			}
			else
				yyval._expr.value = 0 - yyvsp[0]._expr.value; 
		}
	}
	else{
		op = (yyvsp[-1]._op == '-')?"uminus":"not";    /* 取反操作   汇编没这个符号??*/
		yyval._expr.place = newtemp();  /* 申请一个临时变元t */
              yyval._expr.is_const = 0;

		if (yyvsp[0]._expr.is_const)	sprintf(code, "	mov	eax, %d\n", 0 - yyvsp[0]._expr.value); 
		else{
			sprintf(code, "	mov	eax,dword ptr [ebp-%d] ;%s\n", yyvsp[0]._expr.place->offset + 4, yyvsp[0]._expr.place->name);  
		}
		len = strlen(code);
		sprintf(&code[len], "	mov	dword ptr [ebp-%d], eax	;%s\n", yyval._expr.place->offset + 4, yyval._expr.place->name);  
		
		yyval._expr.code = (char *)malloc(strlen(code)+1);
              strcpy(yyval._expr.code, code);
	}
	}
break;
case 56:
#line 1298 "c--.y"
{  trace("factor => ( expr )\n");  
	yyval._expr = yyvsp[-1]._expr;
	}
break;
case 57:
#line 1302 "c--.y"
{  
	yyval._expr.is_const = 0; 
	yyval._expr.place = yyvsp[0]._sym;  
	yyval._expr.type = yyvsp[0]._sym->type;
	yyval._expr.code = NULL;
	}
break;
case 58:
#line 1309 "c--.y"
{  
	trace("factor => call\n");
	yyval._expr.type = yyvsp[0]._expr.place->ret;

	if(is_funret){   /* 有函数返回值*/
		if(yyvsp[0]._expr.place->ret_const){  /*返回的是常数*/
			yyval._expr.is_const = 1;
			yyval._expr.value = yyvsp[0]._expr.place->retvalue;
		}
		else{
			yyval._expr.is_const = 0;
			yyval._expr.place = temp_ret;
		}
	is_funret = 0;   /* 这样处理不够恰当,当函数被多次调用时*/
	}

	yyval._expr.code = yyvsp[0]._expr.code;   /*代码上传*/

	}
break;
case 59:
#line 1329 "c--.y"
{  
	yyval._expr.is_const = 1; 
	yyval._expr.value = atoi(yyvsp[0]._ident);  
	yyval._expr.type = INT;
	yyval._expr.code = NULL;
	}
break;
case 60:
#line 1336 "c--.y"
{
	char text[100];
	int i = 0;  	

	yyval._expr.is_const = 1;
	yyval._expr.type = CHAR_POINT;
	yyval._expr.aa = data_place;   /*不这样就经常会出现死循环*/
	yyval._expr.place = yyvsp[0]._sym;
	yyval._expr.code = NULL;

	strcpy(text,yytext);
	while(text[i+1] != '\"'){
		text[i] = text[i+1];
		i++;
	}
	if(text[i-1]=='n' && text[i-2] == '\\'){  /*有带回车 , \ 和 n是分开的字符*/
		text[i-2] = '\0';
		const_strings[n_const_strings].is_n = 1;
		const_strings[n_const_strings].index = data_place;
		const_strings[n_const_strings].value = (char *)malloc(strlen(text)+1);
		strcpy(const_strings[n_const_strings].value,text);
		/*const_strings[n_const_strings].value = text;*/
		data_place += strlen(text) + 2;	
	}
	else{
		text[i] = '\0';
		const_strings[n_const_strings].is_n = 0;
		const_strings[n_const_strings].index = data_place;
		const_strings[n_const_strings].value = (char *)malloc(strlen(text)+1);
		strcpy(const_strings[n_const_strings].value,text);   /*为什么这样才不会被改变*/
		/*const_strings[n_const_strings].value = text;*/
		data_place += strlen(text) + 1;	
	}
	/*printf("%d   %s\n",0,const_strings[0].value );*/
	/*printf("%d   %s\n",1,const_strings[1].value );*/
	n_const_strings++;  /*常量串的个数*/
	
	}
break;
case 61:
#line 1375 "c--.y"
{  
	yyval._expr.is_const = 1;
	yyval._expr.place = yyvsp[0]._sym;
	yyval._expr.type = CHAR;
	yyval._expr.value = yytext[0];  /*字符可以当成是数*/
	yyval._expr.code =NULL;
	}
break;
case 62:
#line 1385 "c--.y"
{  
	char code[1000];  /*代码*/
	symbol *p;
	paramtp *i,*j;
	int len,t;
	int arg_num=0;
	struct table * tp = table_stack[table_len-1];

	trace("call => ID ( args )\n");
	if((p = lookup_all(yyvsp[-3]._ident ,tp))==0){    /*没找到有定义*/
		fprintf(errfile,"line %d:%s error have not defined\n",nline,yyvsp[-3]._ident);
		is_error++; 
		return 0;
	}
	else{  /* 找到同名标识符*/
		if(p->type == FUN_DEFINE || p->type == FUN_DECLAR){ /*  定义或是声明*/
			for(i = p->paramer,j = yyvsp[-1]._param;i!=NULL &&j!=NULL;i=i->next,j=j->next){ /* 检查参数*/
				if(i->type != j->type)	break;	
				arg_num++;	/*记录参数个数*/
			}
			if(i!=NULL || j!=NULL){
				fprintf(errfile,"line %d : the type or number of function argvments is unexpected!\n",nline);
				is_error++;
				return 0; 
			}
			else 	yyval._expr.place = p;  
		}
		else{  /* 找到的不是函数定义或声明,可能是普通变量*/
			fprintf(errfile,"line %d :%s error have not define \n",nline,yyvsp[-3]._ident);
			is_error++;
			return 0;
		}
	}

	/* 过程调用所对应的代码
	......push ..
	......push ..
	......call ..   */
	
	if(yyvsp[-1]._param->code != NULL){
		strcpy(code,yyvsp[-1]._param->code);  /* push ... 函数参数  但是$3 没有.code ? */
		len = strlen(code);

		t = is_C(yyvsp[-3]._ident);
		if(t==1){  /*判断是否为C 的函数*/
			sprintf(&code[len],"	call	_%s\n",yyvsp[-3]._ident);
			len = strlen(code);
			sprintf(&code[len],"	pop	ecx\n");
			len = strlen(code);
			sprintf(&code[len],"	add	esp,%d\n",4*arg_num);
		}
		else{
			sprintf(&code[len],"	call	%s\n",yyvsp[-3]._ident);
			len = strlen(code);
			sprintf(&code[len],"	add	esp,%d\n",4*arg_num);
			len = strlen(code);
		}
	}
	else{
		t= is_C(yyvsp[-3]._ident);
		if( t==1){  /*判断是否为C 的函数*/
			sprintf(&code[0],"	call	_%s\n",yyvsp[-3]._ident);
			len = strlen(code);
			sprintf(&code[len],"	pop	ecx\n");
		}
		else{
			sprintf(&code[0],"	call	%s\n",yyvsp[-3]._ident);
			len = strlen(code);
		}
	}
	len = strlen(code);
	yyval._expr.code = (char *)malloc(strlen(code)+1);   
	strcpy(yyval._expr.code, code);

	}
break;
case 63:
#line 1463 "c--.y"
{  
	trace("args => arg_list\n");
 	yyval._param->code = yyvsp[0]._param->code;  
	}
break;
case 64:
#line 1468 "c--.y"
{  
	trace("args => ε\n");
 	 yyval._param->code = NULL;
	}
break;
case 65:
#line 1476 "c--.y"
{  
  	int len;
	char code[1000];
	paramtp *i;
	trace("arg_list => arg_list , expr\n");  
	
	i = (paramtp *)malloc(sizeof(paramtp)); 
	yyval._param = i;    /* 插入参数表 */
	yyval._param->next = yyvsp[-2]._param;                     
     	yyval._param->type = yyvsp[0]._expr.type ;

	if(yyvsp[0]._expr.code == NULL){
	if(yyvsp[0]._expr.is_const){   /* 常量参数 */
		if(yyvsp[0]._expr.type == INT)	sprintf(code,"	push       %d\n",yyvsp[0]._expr.value);
		else if(yyvsp[0]._expr.type == CHAR)  sprintf(code,"	push	'%c'\n",yyvsp[0]._expr.value);
		else{
			if( yyvsp[0]._expr.aa == 0)	sprintf(code,"	push	  offset s@\n");
			else	sprintf(code,"	push      offset  s@+%d\n",yyvsp[0]._expr.aa);  /*??偏移量如何求得*/
		}
	}
	else{
		sprintf(code,"	push	dword ptr [ebp-%d] ; %s\n",yyvsp[0]._expr.place->offset+4,yyvsp[0]._expr.place->name);   /* 变量*/
	}
	}
	else{     
		strcpy(code,yyvsp[0]._expr.code);
		len = strlen(code);
		if(yyvsp[0]._expr.is_const){ 
			if(yyvsp[0]._expr.type == INT)	sprintf(&code[len],"	push       %d\n",yyvsp[0]._expr.value);
			else if(yyvsp[0]._expr.type == CHAR)  sprintf(&code[len],"	push	'%c'\n",yyvsp[0]._expr.value);
			else{
				if( yyvsp[0]._expr.aa == 0)	sprintf(&code[len],"	push	  offset s@\n");
				else	sprintf(&code[len],"	push      offset  s@+%d\n",yyvsp[0]._expr.aa);  /*??偏移量如何求得*/
			}
		}
		else{
			sprintf(&code[len],"	push	dword ptr [ebp-%d] ; %s\n",yyvsp[0]._expr.place->offset+4,yyvsp[0]._expr.place->name);   
		}
	}   
	len = strlen(code);
	strcat(code,yyvsp[-2]._param->code);   /* $1 放在 $3  的后面,遵循从右向左压栈的顺序*/
	len = strlen(code);
	yyval._param->code = (char *)malloc(len + 1);
	strcpy(yyval._param->code,code);

	}
break;
case 66:
#line 1523 "c--.y"
{ 
	int len;
	char code[1000];
	paramtp *i;
	trace("arg_list => expr\n"); 
 
	i = (paramtp *)malloc(sizeof(paramtp)); 	/* 插入参数表 */
	yyval._param = i; 
	yyval._param->next = NULL;                       
     	yyval._param->type = yyvsp[0]._expr.type;
	
	if(yyvsp[0]._expr.code == NULL){
	if(yyvsp[0]._expr.is_const){   /* 常量参数 */
		if(yyvsp[0]._expr.type == INT)	sprintf(code,"	push       %d\n",yyvsp[0]._expr.value);
		else if(yyvsp[0]._expr.type == CHAR)  sprintf(code,"	push	'%c'\n",yyvsp[0]._expr.value);
		else{
			if( yyvsp[0]._expr.aa == 0)	sprintf(code,"	push	  offset s@\n");
			else	sprintf(code,"	push      offset  s@+%d\n",yyvsp[0]._expr.aa);  /*偏移量如何求得*/
		}
	}
	else{
	      sprintf(code,"	push	dword ptr [ebp-%d] ; %s\n",yyvsp[0]._expr.place->offset+4,yyvsp[0]._expr.place->name);   /* */
	}
	}

	else{       /*前面的参数  */
		strcpy(code,yyvsp[0]._expr.code);
		len = strlen(code);
		if(yyvsp[0]._expr.is_const){
			if(yyvsp[0]._expr.type == INT)	sprintf(&code[len],"	push       %d\n",yyvsp[0]._expr.value);
			else if(yyvsp[0]._expr.type == CHAR)  sprintf(&code[len],"	push	'%c'\n",yyvsp[0]._expr.value);
			else{
				if( yyvsp[0]._expr.aa == 0)	sprintf(&code[len],"	push	  offset s@\n");
				else	sprintf(&code[len],"	push      offset  s@+%d\n",yyvsp[0]._expr.aa);  /*??偏移量如何求得*/
			}
		}
		else{
			sprintf(&code[len],"	push	dword ptr [ebp-%d] ; %s\n",yyvsp[0]._expr.place->offset+4,yyvsp[0]._expr.place->name);  
		}
	}    
	len = strlen(code);
	yyval._param->code = (char *)malloc(len + 1);
	strcpy(yyval._param->code,code);

	}
break;
case 67:
#line 1571 "c--.y"
{  trace("callconvent =>  __cdecl\n");  }
break;
case 68:
#

⌨️ 快捷键说明

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