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

📄 c--.y

📁 简单实现C--语言的编译器
💻 Y
📖 第 1 页 / 共 3 页
字号:
		ttp = insert($2,tp);   //插入
		$$ = ttp;
	}
	}
       |   ID
	{  
	struct table *tp = table_stack[table_len-1];
       symbol *ttp;

	trace("fun_tag => callconvent  ID\n");  
	if((ttp = lookup_all($1,tp))!=0){   //已经在符号表出现(声明)
		if(ttp->type == FUN_DECLAR){  //函数声明
			$$ = ttp;
		}
		else if(ttp->type == FUN_DEFINE){  //先定义
			fprintf(errfile,"line %d : function %s define repeatedly\n",nline,$1);
			is_error++;
			$$ = NULL;
		}
		else{  // 函数名可能和一变量名相同
			fprintf(errfile,"line %d : warning the function argvment(s) is expected\n");
			$$ = NULL;
		}
	}
	else{	
		ttp = insert($1,tp);   //插入
		$$ = ttp;
	}
	}
       ;	
params  :    param_list 
	{  
	   trace("params => param_list \n");  
          offset_stack[offset_len-1] = 0; 
	   $$ = $1;
         }
      |   VOID
	{  $$ = 0;  }
      ;
param_list  :    param_list   ',' param 
	{  trace("param_list => param_list , param \n");  
	    $$ = $3;
	    $$->next = $1;   /*c-- 函数参数从右到左顺序压栈*/
	}
      |   param
	{  trace("param_list => param\n");  
	   $$ = $1; 
	}
      ;
param  :    type_spec ID 
	{
	struct table * tp = table_stack[table_len-1];  //当前层
	symbol *p;
	int width;
	paramtp *i;

	trace("param => type_spec ID\n");  
 	if(lookup($2,tp)!=0){  
		fprintf(errfile,"line %d : %s had been defined!",nline,$2);
		is_error++; 
		return 0;
	}
	else{
		p = insert($2,tp); //可能在此时创建一个新的符号表
		width = 0;    //类型长度
		p->isargv = 1;
	       p->offset = offset_stack[offset_len-1];
		p->type = $1;
		if($1 == INT){
			width = 4;
		}
 	       else if($1 == CHAR){
			width = 1;
              }
		offset_stack[offset_len-1] += width;

              i = (paramtp *)malloc(sizeof(paramtp)); /*插入参数表*/
		$$ = i; 
		$$->next = NULL;                       
     		$$->type = p->type ;
          
	}
	}
      |   type_spec   '*'  ID 
	{  
	struct table *tp = table_stack[table_len-1];  //当前层
	symbol *p;
	int width;
	paramtp *i;

	trace("param => type_spec * ID \n");  
	if(lookup($3,tp)!=0){
		fprintf(errfile,"line %d : %s had been defined!",nline,$3);
		is_error++; 
		return 0;
	}
	else{
		p = insert($3,tp);
		width = 0;    //类型长度
	       p->isargv = 1;
	       p->offset = offset_stack[offset_len-1];
		if($1 == INT){
			width = 4;
			p->type = INT_POINT;
		}
 	       else if($1 == CHAR){
			width = 4;
			p->type = CHAR_POINT;
              }
		else if($1 == VOID){
			width = 4;
			p->type = VOID_POINT;
		}
		offset_stack[offset_len-1] += width;

              i = (paramtp *)malloc(sizeof(paramtp)); /*插入参数表*/
		$$ = i;
		$$->type = p->type;                       
     		$$->next = NULL;
	}
	}
      |   type_spec ID  '['    ']'  
	{  
	struct table * tp = table_stack[table_len-1];  //当前层
	symbol *p;
	int width;
       paramtp *i;

	trace("param => type_spec ID [ ]\n");  
	if(lookup($2,tp)!=0){
		fprintf(errfile,"line %d : %s had been defined!",nline,$2);
		is_error++;
		return 0;
	}
	else{
		p = insert($2,tp);
		width = 0;    //类型长度
		p->isargv = 1;
	       p->offset = offset_stack[offset_len-1];
		if($1 == INT){
			width = 4;
			p->type = INT_ARRAY;
		}
 	       else if($1 == CHAR){
			width = 4;
			p->type = CHAR_ARRAY;
              }
		offset_stack[offset_len-1] += width;

              i = (paramtp *)malloc(sizeof(paramtp)); /*插入参数表*/
		$$ = i;                       
     		$$->next = NULL;
		$$->type = p->type; 
	}	
	} 
      ;
comp_stmt  :    '{'  local_declars stmt_list  '}'
	{ 
	is_first++; 
	if(is_first==1) fprintf(yyout,"	.code\n");

	if(is_funret){   //函数有返回值
		if($3.is_const){ 
			$$.is_const = 1;
			$$.value = $3.value;
		}
		else{
			$$.is_const  =0;
		}
	}
	$$.code = $3.code;  
	}
      ;
local_declars  :    local_declars var_declar
      |   
	{  trace(" local_declars => ε\n");  }
      ;

stmt_list  :    stmt_list stmt 
	{   
	
	char  code[1000];

	if(is_funret){   //函数有返回值
		if($2.is_const){ 
			$$.is_const = 1;
			$$.value = $2.value;
		}
		else{
			$$.is_const  =0;
		}
	}

	if($1.code != NULL && $2.code != NULL){
		$$.code = (char *)malloc(strlen($1.code) + strlen($2.code)+1);
              strcpy(code,$1.code);
              strcat(code,$2.code);
            	strcpy($$.code,code);  
	}
	else if($1.code != NULL && $2.code == NULL) {
		$$.code = (char *)malloc(strlen($1.code) +1);
              strcpy(code,$1.code);
		strcpy($$.code,code); 
	}
	else if($1.code == NULL && $2.code != NULL) {
		$$.code = (char *)malloc(strlen($2.code) +1);
              strcpy(code,$2.code);
		strcpy($$.code,code); 
	}
	else $$.code = "";
      }
      |      
	{  
	$$.code = "";  
	trace("empty stmt_list\n");
	}
      ;

stmt  :    expr_stmt 
	{  trace("stmt => expr_stmt\n");  // 语句类型
 	}
      |   comp_stmt 
	{  trace("stmt => comp_stmt\n");  }
      |   if_stmt 
	{  trace("stmt => if_stmt\n"); }
      |   while_stmt 
	{  trace("stmt => while_stmt\n");  }
      |   return_stmt
	{  
	trace("stmt => return_stmt\n");  

	if(is_funret){   //函数有返回值
		if($1.is_const){ 
			$$.is_const = 1;
			$$.value = $1.value;
		}
		else{
			$$.is_const  =0;
		}
	}
	//$$.code = $1.code;
	}
      ;

expr_stmt  :    expr    ';'
	{  
	if(verbose)   fprintf(stderr, "expr_stmt => expr \n");
	$$ = $1;
	} 
      |     ';'
	{  trace("expr_stmt => ;\n");  
	   $$.code = "";
	}

        ;

if_stmt  :   IF  '('    expr   ')'    stmt    %prec LOW_ELSE	
	{  
	char code[1000];
	int len;
	char *E_false;
	trace("if_stmt => if ( expr ) stmt\n"); 
	
	if($3.is_const){
		if($3.value != 0 ){
			if($5.code != NULL){
				strcpy(code,$5.code);
				len = strlen(code);
				$$.code = (char *)malloc(len+1);
				strcpy($$.code,code)	;
			}
		}
		else	$$.code = "";
	}
	else{
		E_false = newlabel();

		strcpy(code,$3.code);
		len = strlen(code);
		sprintf(&code[len],"%s\n",E_false);
		len = strlen(code);
		if($5.code != NULL){
			strcat(code,$5.code);
			len = strlen(code);
		}
		sprintf(&code[len],"%s:\n",E_false);
		len = strlen(code);
		$$.code = (char *)malloc(len + 1);
		strcpy($$.code,code);
	}
	} 
      |   IF   '('    expr   ')'    stmt ELSE stmt
	{  
	char code[1000];
	int len;
	char *E_false;
	char *S_next;

	trace("if_stmt => if ( expr ) stmt else stmt\n"); 
	if($3.is_const){
		if($3.value != 0 ){
			if($5.code != NULL){
				strcpy(code,$5.code);
				len = strlen(code);
				$$.code = (char *)malloc(len+1);
				strcpy($$.code,code)	;
			}	
		}
		else{
			if($7.code != NULL){
				strcpy(code,$7.code);
				len = strlen(code);
				$$.code = (char *)malloc(len+1);
				strcpy($$.code,code)	;
			}
		}
	}
	else{
		E_false = newlabel();
		S_next = newlabel();
		
		strcpy(code,$3.code);  
		len = strlen(code);
		sprintf(&code[len],"%s\n",E_false);
		len = strlen(code);
		if($5.code !=NULL){
			strcat(code,$5.code);   // 真
			len = strlen(code);
		}
		sprintf(&code[len],"	jmp	%s\n",S_next);
		len = strlen(code);
		sprintf(&code[len],"%s:\n",E_false); //label E_false
		len = strlen(code);
		if($7.code != NULL){
			strcat(code,$7.code);   //假
			len = strlen(code);
		}
		sprintf(&code[len],"%s:\n",S_next);  // label S_next
		len = strlen(code);
		$$.code = (char *)malloc(len + 1);
		strcpy($$.code,code);
	}
	}
      ;
while_stmt  :    WHILE   '('    expr   ')'    stmt
	{  
	char code[1000];
	int len;
	char *S_begin;
	char *S_next;

	trace("while_stmt => while ( expr ) stmt\n");  
	if($3.is_const){
		if($3.value != 0){
			S_begin = newlabel();
			strcpy(code,S_begin);
			len = strlen(code);
			if($5.code != NULL){
				strcat(code,$5.code);
				len = strlen(code);
			}
			sprintf(&code[len],"	jmp	%s\n",S_begin);
			len = strlen(code);
			$$.code = (char *)malloc(len +1);
			strcpy($$.code,code);
		}
		else $$.code = "";	
	}
	else{
		S_begin = newlabel();
		S_next = newlabel();
		//strcpy(code,S_begin);   //  此处用两种都可以
		sprintf(code,"%s:\n",S_begin);

		len = strlen(code);
		strcat(code,$3.code);
		len = strlen(code);
		sprintf(&code[len],"%s\n",S_next);
		len = strlen(code);
		if($5.code != NULL){
			strcat(code,$5.code);
			len = strlen(code);
		}
		sprintf(&code[len],"	jmp	%s\n",S_begin);
		len = strlen(code);
		sprintf(&code[len],"%s:\n",S_next);
		len = strlen(code);
		$$.code = (char *)malloc(len +1);
		strcpy($$.code,code);
	}
	}
      ;
return_stmt  :    RETURN   ';' 
	{  
	trace("return_stmt => return ; \n");  
	is_funret = 0;
	}
      |   RETURN expr   ';'
	{  
	//char code[100];

	trace("return_stmt => return expr ;\n"); 
	is_funret = 1;
	if($2.is_const){
		$$.is_const = 1;
		//sprintf(&code[0],"	mov	ebx , %d\n",$2.value);		
		$$.value = $2.value;
	}  
	else{
		$$.is_const = 0;
		//sprintf(&code[0],"	mov	ebx , [ebp-%d] ; %s\n",$2.place->offset+4,$2.place->name);
		temp_ret = $2.place;  //临时存放返回的单元 可以改用ebx 寄存器来实现
	}
	//$$.code = (char *)malloc(strlen(code)+1);
	//strcpy($$.code,code);
	}
      ;

expr  :    var  '='  expr 
	{  
	char code[1000];
	int len; 

	if($1->type != $3.type){     /* 表达式类型检查 */
		fprintf(errfile,"line %d : expression type wrong \n",nline);
		is_error++; 
		return 0;
	}
	else{
		$$.type = $1->type;
		
		if ($3.is_const){  // expr为常量的情况
			sprintf(code,"	mov	edx  ,	%d\n",$3.value);
			len = strlen(code);
			sprintf(&code[len], "	mov	dword ptr [ebp-%d], edx;%s\n", $1->offset+4,$1->name);  
       	}
		else { 
			if($3.code != NULL){
              		strcpy(code, $3.code);
              		len = strlen(code);  /* $3 的代码接在 $1 的代码后面 */
				sprintf(&code[len],"	mov	edx ,dword ptr [ebp-%d] ; %s\n",$3.place->offset+4,$3.place->name);
			}
			else {
				sprintf(code,"	mov	edx , dword ptr [ebp-%d] ; %s\n",$3.place->offset+4,$3.place->name);  // 一个操作数
			}
			len = strlen(code);
              	sprintf(&code[len], "	mov	dword ptr [ebp-%d] , edx ; %s\n", $1->offset+4,$1->name); 
		} 
		len =strlen(code);
		$$.code = (char *)malloc(len+1);
       	strcpy($$.code, code);
       }
	}	
      |    simple_expr
	{   $$ = $1; }
      ;



var  :    ID
	{  
	symbol *p;
	struct table * tp = table_stack[table_len-1];  //当前层

	if (verbose) fprintf(stderr, "look for %s\n", $1);
	if( (	p = lookup_all($1,tp)) == 0){    /*所有层中查找不到*/
		fprintf(errfile, "line %d : undeclared identifier: %s \n",nline,$1);
		is_error++;    
		return 0; 
       }
	else{
		if( p->scope != level && p->isargv == 1){    /* 有找到,但是其他函数的形参 */
			fprintf(errfile, "line %d : undeclared identifier: %s \n",nline,$1);
			is_error++;
			return 0;
	   	}
		else{
			if(p->type != INT && p->type !=CHAR){  /*  类型只允许int char  */
		 		fprintf(errfile, "line %d : type unexpected\n:\n", nline);
		 		is_error++;  
				return 0;
	             }
			else	$$ = p	;    // 同为symbol 类型
		}
	}
 
	} 
      |   ID  '['  expr    ']' 
	{  
	symbol *p;
	struct table * tp = table_stack[table_len-1];

	trace("var => ID  [ expr ]\n");  
	if(( p = lookup_all($1, tp)) == 0){
	        fprintf(errfile, "line %d :undeclared identifier: %s \n",nline,$1); 
	        is_error++;  
		return 0;
	}
	 /* 数组类型 */
	if(p->type == INT_ARRAY)	$$->type = INT;
	else if(p->type == CHAR_ARRAY)	$$->type = CHAR;
	else if(p->type == INT_POINT_ARRAY)	$$->type = INT_POINT;
	else if(p->type == CHAR_POINT_ARRAY)	$$->type = CHAR_POINT;
	else{  //无其他类型
		fprintf(errfile,"nline %d :type unexpected\n",nline); 
	       is_error++;
		return 0;
	}
	//....        
	}
      ;

simple_expr  :    add_expr relop add_expr
	{  
	char rop[4];
	char code[1000];
	int len;

	trace("simple_expr => add_expr relop add_expr\n");  
	if($1.type != INT && $1.type != CHAR || $3.type != INT && $3.type != CHAR){ //只允许int char型
		fprintf(errfile,"line %d : type unexpected\n",nline);   	
		is_error++;  
		return 0;
	}
	else{	
		$$.type = INT;   
		strcpy(rop,$2.code);  //op 
		rop[strlen(rop)] = '\0';

		if($1.is_const && $3.is_const){   //两个均是常数
			if( (strcmp(rop,"le") == 0) && $1.value <= $3.value)  $$.value = 1;
			else if((strcmp(rop,"l") == 0) && $1.value < $3.value)   $$.value = 1;
			else if((strcmp(rop,"g") == 0) && $1.value > $3.value)   $$.value = 1;
			else if((strcmp(rop,"ge") == 0) && $1.value >= $3.value)   $$.value = 1;
			else if((strcmp(rop,"e") == 0) && $1.value == $3.value)   $$.value = 1;
			else if((strcmp(rop,"ne") == 0) && $1.value != $3.value)   $$.value = 1;
			else  $$.value = 0;
		}
		else {
			if(!$1.is_const && $3.is_const){
				sprintf(code,"	mov	edx ,dword ptr [ebp-%d] ; %s\n",$1.place->offset+4,$1.place->name);
				len = strlen(code);
				sprintf(&code[len],"	cmp	edx , 	%d\n",$3.value);
				len = strlen(code);
				if(strcmp(rop,"le")==0) 	sprintf(&code[len],"	jg	short	"); 
				else if(strcmp(rop,"l")==0)	sprintf(&code[len],"	jge	short	"); 
				else if(strcmp(rop,"g")==0)	sprintf(&code[len],"	jle	short	"); 
				else if(strcmp(rop,"ge")==0) sprintf(&code[len],"	jl	short	"); 
				else if(strcmp(rop,"e")==0)	sprintf(&code[len],"	jne	short	"); 
				else if(strcmp(rop,"ne")==0)sprintf(&code[len],"	je	short	"); 
				len = strlen(code);
			}
			else if($1.is_const && !$3.is_const){
				sprintf(code,"	mov	edx ,dword ptr [ebp-%d] ; %s\n",$3.place->offset+4,$3.place->name);
				len = strlen(code);
				sprintf(&code[len],"	cmp	edx , 	%d\n",$1.value);
				len = strlen(code);
				if(strcmp(rop,"le")==0) 	sprintf(&code[len],"	jl	short	"); 
				else if(strcmp(rop,"l")==0)	sprintf(&code[len],"	jle	short	"); 
				else if(strcmp(rop,"g")==0)	sprintf(&code[len],"	jge	short	"); 
				else if(strcmp(rop,"ge")==0) sprintf(&code[len],"	jg	short	"); 
				else if(strcmp(rop,"e")==0)	sprintf(&code[len],"	jne	short	"); 
				else if(strcmp(rop,"ne")==0)sprintf(&code[len],"	je	short	"); 
				len = strlen(code);
			}
			else{
				sprintf(code,"	mov	edx , dword ptr [ebp-%d] ; %s\n",$1.place->offset+4,$1.place->name);
				len = strlen(code);

⌨️ 快捷键说明

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