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

📄 compiler.c

📁 一个编译器的例子,基于c语言,在linux下开发 现在了简单的c语言例子
💻 C
📖 第 1 页 / 共 4 页
字号:
#include<stdlib.h>#include<stdio.h>#include "struct.h"#include "stack.h"char source_filename[255];             /* name of source file in new language    */char assembler_filename[255];          /* name of assembler for input to as      */char object_code_filename[255];        /* name of object code for as output      */char literals_filename[255];           /* name of file for string literals       */FILE *assembler_file;                  /* the destination file for the assembler */FILE *literals_file;                   /* the file holding the string literals   */int  isMain;        /*  0 other function ,  1  main function */int  findingFuncNode;    /* meet node "func" marked 1,  found func node ("ID")  marked 0 */int BOOLlabel=0;int  IFlabel = 0;                     /* IF label */int  FORlabel = 0;                  /* FOR label */int  SWITCHlabel = 0;             /* FOR label */int  CASElabel = 0;                 /* CASE label */int  WHILElabel = 0;                     /* WHILE label */int  DOlabel = 0;                     /* WHILE label */int  ANDlabel = 0;                     /* AND label */int  loopType=-1;                   /*  1 while,  2 do-while,  3  for,  4 switch */int  initOrder=0;void output_literal_file();void output_start( FILE *file, char *literals_filename);  void output_end( FILE *file); void code_gen_print(FILE *file, int i);void gen_data(FILE *file);void func_prologue(FILE *file);void func_epilogue(FILE *file);void code_gen(FILE *file, symnode *tree);void gen_func(FILE *file, symnode *tree);symnode *get_func_name(symnode *tree);void gen_func_content(FILE *file,symnode *tree);void gen_println(FILE *file, symnode *tree);void print_char_array(FILE *file, int len);void print_nl(FILE *file);void gen_assign(FILE *file, symnode *tree);void gen_operation(FILE *file, symnode *tree);void gen_global_vals(FILE *file,symnode *tree);void getIDAddr(symrec *id, char addr[]);void gen_OffsetIDAddress( FILE *file, symnode *tree);void gen_init_vals(FILE  *file, symnode *tree);void gen_init_array(FILE *file, symnode *tree, int isGlobal, int idOffset);void gen_assign(FILE *file, symnode *tree);void gen_return(FILE *file, symnode *tree);void gen_assign_op(FILE *file, symnode *tree);void gen_unary_op(FILE *file, symnode *tree);void gen_logic_and(FILE *file);void gen_logic_or(FILE *file);void gen_if(FILE *file, symnode *tree);void gen_switch(FILE *file, symnode *tree);void gen_case_condition(FILE *file, symnode *tree);void gen_case(FILE *file, symnode *tree);void gen_for(FILE *file, symnode *tree);void gen_while(FILE *file, symnode *tree);void gen_dowhile(FILE *file, symnode *tree);void gen_break(FILE *file);void gen_continue(FILE *file);void gen_relation_code(FILE *file, symnode *tree);//void getRelationOp(symnode *tree, char *label1, char *label2, char *jmp);void getOperator(const char*, char * operator);/*************************************************************//* output the string literals in the following form   *//*   literalN:   .string  "actual string\n"           *//*   ready for inclusion in filename.S                *//*   note: .string adds a trailing \0                 */                                                      void output_literal_file(FILE *literals_file, int literal_count, char literals[255][255]){   int i;  fprintf(literals_file, "\t\t# this is the file of string literals\n");  for( i=0; i < literal_count ; i++ ) {         fprintf( literals_file, "literal%d:\t.string %s\n", i, literals[i] );         fprintf( literals_file, "\tlen%d = . - literal%d\n", i, i );  } // fprintf( literals_file, "newline:\t.string \"\\n\"\n"); // fprintf( literals_file, "\tnl_length = . - newline\n");} // end output_literal_file/**************************************************************//* tidy up at the end of the assembler file *//* and output the exit code                 */  void output_end( FILE *file){   //func_epilogue(file);  fprintf( file, "\t%s\n", "movl $SYS_exit,%eax\t# load the exit call number");  fprintf( file, "\t%s\n", "movl $0,%ebx\t\t# load the exit code");  fprintf( file, "\t%s\n", "int $0x80\t\t# and exit!");  fprintf( file, "\t\t\t\t# end of the file\n");} // end output_end/*************************************************************//* output the start of the assembler to file           *//* include the literal file: literals_filename         *//* include the defines.h system call numbers           *//* declare .data and .text sections                    *//* declare _start global                               */void output_start( FILE *file, char *literals_filename){   fprintf( file, "\t\t\t\t# start of the file\n");  //fprintf( file, ".data\n");  fprintf( file, ".include \"defines.h\"\t\t# system call numbers\n");  fprintf( file, ".include \"%s\"\t# include the string literal file\n", literals_filename);  //fprintf( file, "\n.text\n");  fprintf( file, "\t.global _start\t\n");  fprintf( file, "\t.bss\n");  fprintf( file, "\t.align\t%d\n",4);  gen_data(file);} // end output_start   //allocate the memory for global variables void gen_data(FILE *file){  int size=0;  size=sizeOfVals("Global");    fprintf(file, "_data:\n");  if(size!=0)         fprintf(file, "\t%s\t\t%d\t%s\n",".skip",size,"# global variables' size");  fprintf(file, "%s\n",".text");  fprintf(file, "\t%s\t%d\n",".align",4);  //fprintf( file, "_start:\n");  }void code_gen(FILE *file, symnode *tree){   if (tree==NULL) return;    code_gen(file, tree->next);  if(strcmp(tree->name,"func")==0){      findingFuncNode = 1;      gen_func(file,tree->sibling);       return;  }   code_gen(file, tree->sibling);   }symnode *get_func_name(symnode *tree){     symnode *tmp=NULL;     if(tree==NULL) return NULL;          if(strcmp(tree->name,"ID")==0 &&          tree->symTab->nameType==1) return tree;     tmp=get_func_name(tree->next);     if(tmp!=NULL) return tmp;     tmp=get_func_name(tree->sibling);     return tmp;}//the procedure prologuevoid func_prologue(FILE *file){   fprintf( file, "\t%s\n", "pushl %ebp\t\t# save the ebp address");   fprintf( file, "\t%s, %s\n", "movl %esp","%ebp");  }//procedure epiloguevoid func_epilogue(FILE *file){     fprintf( file, "\t%s, %s\n", "movl %ebp","%esp");     fprintf( file, "\t%s\n", "popl %ebp\t\t# restore the ebp address");}void gen_global_vals(FILE *file, symnode *tree){     if(tree==NULL) return;     if(strcmp(tree->name,"func")==0) return;          if(strcmp(tree->name,"iDecLst")==0){        gen_init_vals(file, tree);            return;     }     gen_global_vals(file, tree->next);     gen_global_vals(file, tree->sibling);}void gen_func(FILE *file, symnode *tree){  symrec *funcNode=NULL;  funcNode = get_func_name(tree)->symTab;    if(strcmp(funcNode->name,"main")==0)  {    isMain = 1;               fprintf( file, "_start:\n");    }else{       isMain = 0;       fprintf( file, "%s:\n", funcNode->name);  }  func_prologue(file);   if(isMain==1)   gen_func_content(file, symRoot);        fprintf(file,"\t%s $%d, %s\t\t# allocate space for local variables\n",                                    "subl",sizeOfVals(funcNode->name),"%esp");    //gen_local_val(file, funcNode->name);  gen_func_content(file, tree);  }// the value of the variablesvoid getIDAddr(symrec *id, char addr[]){   int size;   if (strcmp(id->scope, "Global")==0){        size = offsetAtID("Global",id->order);        if(id->isArray){	    size=size - 4*id->numArray;	}else	    size-=4;	        sprintf(addr, "_data+%d%c",size ,'\0');	return ;   }      if(id->isFuncArg){        sprintf(addr, "%d%s", offsetOfPara(id->scope, id->argOrder),"(%ebp)" );	return ;          }else{      	int offset=0;	offset = offsetAtID(id->scope, id->order);	if (offset ==0)	      sprintf(addr, "%s","%ebp");        else              sprintf(addr, "-%d%s", offset,"(%ebp)");	return ;          }   return ;   }// dynamicly calculate the address for variablesvoid gen_OffsetIDAddress( FILE *file, symnode *tree){        int offset=0;	int size=0;	char addr[255];        if(tree==NULL) return ;	gen_OffsetIDAddress(file, tree->next);	gen_OffsetIDAddress(file, tree->sibling);	if(strcmp(tree->name, "ID")==0){	     getIDAddr(tree->symTab, addr);	     if(tree->symTab->isFuncArg)	     	     fprintf(file, "\t%s %s, %s\n", "movl", addr, "%eax");	     else 	             fprintf(file, "\t%s %s, %s\n", "leal", addr, "%eax");	     fprintf(file, "\t%s\n", "pushl %eax");	     //printf("id: %s   type: %d\n", tree->symTab->name, tree->symTab->type);	     switch(tree->symTab->type){	     case 0:	     case 1:  push(1.0);break;	     case 2:  push(2.0);break;             default: push(-1.0);break;	     }	     	     return;	}		if(strcmp(tree->name, "member")==0){	    offset=sizeAtMember(tree->symTab->structtype, tree->value);	    fprintf(file, "\t%s%d\n", "pushl $", offset);	    pop();	     switch(getMemberType(tree->symTab->structtype, tree->value)){	     case 0:	     case 1:  push(1.0);break;	     case 2:  push(2.0);break;             default: push(-1.0);break;	     }	    	    return;	}		if(strcmp(tree->name, "exp")==0){		gen_assign(file, tree);		pop();				//pop();		//if((tree->symTab->isFuncArg==0) && strcmp(tree->symTab->scope, "Global")!=0)		  //  fprintf(file,"\t%s\n", "negl %eax");	     		if( (strcmp(tree->value, tree->symTab->name)==0)&&(tree->symTab->type==5)){                           // array of struct		     size=sizeOfStruct(tree->symTab->structtype);		     fprintf(file, "\t%s\n", "popl %eax");		     fprintf(file, "\t%s%d, %s\n", "imull $",size,"%eax");		     fprintf(file, "\t%s\n", "pushl %eax");		}else		     fprintf(file, "\t%s\n", "sall $2, (%esp)");	     	        	         	        return;	}		if(strcmp(tree->name, "offset")==0){	     fprintf(file, "\t%s\n", "popl %ebx");             fprintf(file, "\t%s\n", "popl %eax");  	     	     fprintf(file, "\t%s\n", "addl %ebx, %eax"); // should be subl for local variables	     fprintf(file, "\t%s\n", "pushl %eax");	     return;	}		}// when meet node "iDecLst",  do the followingvoid gen_init_vals(FILE  *file, symnode *tree){      symnode *id;      int isGlobal=0;      int idOffset=0;      id = tree;      while(id!=NULL){          if(strcmp(id->name,"ID")==0) break;	  id=id->next;      }            if(id->symTab->type!=5 && id->symTab->isArray!=1){                  gen_assign(file, tree->next);	   fprintf(file, "\t%s\n", "popl %eax");	   pop();      }else{           idOffset=offsetAtID(id->symTab->scope, id->symTab->order);	  //printf("name: %s, scope: %s, order: %d,idOffset %d\n", id->symTab->name, id->symTab->scope,id->symTab->order,idOffset);          if(strcmp(id->symTab->scope, "Global")==0){              idOffset=idOffset-4*id->symTab->numArray;	      isGlobal=1;	  }          gen_init_array(file, tree->next->sibling, isGlobal, idOffset);      }}void gen_init_array(FILE *file, symnode *tree, int isGlobal, int idOffset){       int i=0;       if(tree==NULL) return;        gen_init_array(file, tree->next, isGlobal, idOffset);       gen_init_array(file, tree->sibling, isGlobal, idOffset);              if((strcmp(tree->name, "INT_V")==0) || (strcmp(tree->name, "FLT_V")==0)){           if(isGlobal)        	fprintf(file, "\t%s $%s, %s%d\n", "movl", tree->value, "_data+",idOffset+initOrder*4);           else	        fprintf(file, "\t%s $%s, %d%s\n", "movl", tree->value,(-1)*(idOffset-initOrder*4), "(%ebp)");	   initOrder++;		   return;       }              if(strcmp(tree->name, "CHAR_V")==0){           if(isGlobal)        	fprintf(file, "\t%s $%s, %s%d\n", "movl", tree->value, "_data+",idOffset+initOrder*4);           else	        fprintf(file, "\t%s $%s, %d%s\n", "movl", tree->value,(-1)*(idOffset-initOrder*4), "(%ebp)");	   initOrder++;	   return;       }       if(strcmp(tree->name, "STRING")==0){            // printf("char: %s\n", tree->value);             for(i=0;i<strlen(literals[tree->strIndex])-2; i++){                   if(isGlobal)        	         fprintf(file, "\t%s $%d, %s%d\n", "movl", (int)(literals[tree->strIndex][i+1]), "_data+",idOffset+i*4);                   else	                 fprintf(file, "\t%s $%d, %d%s\n", "movl", (int)(literals[tree->strIndex][i+1]),(-1)*(idOffset-i*4), "(%ebp)");	      }	      if(isGlobal)	        	fprintf(file, "\t%s, %s%d\n", "movl $0", "_data+",idOffset+i*4);	      else	      		fprintf(file, "\t%s, %d%s\n", "movl $0", (-1)*(idOffset-i*4), "(%ebp)");	      	      return;       }              }void gen_unary_op(FILE *file, symnode *tree){     float a;     if(tree==NULL) return;     if(strcmp(tree->sibling->name, "unaryOp")==0){        printf("--compiling error(line %d): invalid operand with increment or decrement\n",tree->sibling->line);	exit(0) ;     }     gen_OffsetIDAddress(file, tree->sibling);// id address already on top of stack     fprintf(file, "\t%s\n","popl %eax");     a=pop();          if(strcmp(tree->value, "O+")==0){    // if it's id++        if(a!=2.0){          	fprintf(file, "\t%s\n","push (%eax)");	  	fprintf(file, "\t%s\n","incl (%eax)"); 	}else{		fprintf(file, "\t%s\n","push (%eax)");		fprintf(file, "\t%s\n", "fld1");		fprintf(file, "\t%s\n", "flds (%eax)");		fprintf(file, "\t%s\n", "faddp %st, %st(1)");		fprintf(file, "\t%s\n", "fstps (%eax)");	}     }     if(strcmp(tree->value, "O-")==0){    // if it's id--        if(a!=2.0){          	fprintf(file, "\t%s\n","push (%eax)");	  	fprintf(file, "\t%s\n","decl (%eax)"); 	}else{               	fprintf(file, "\t%s\n", "push (%eax)");		fprintf(file, "\t%s\n", "fld1");	  	fprintf(file, "\t%s\n", "flds (%eax)");		fprintf(file, "\t%s\n", "fsubp %st, %st(1)");		fprintf(file, "\t%s\n", "fstps (%eax)"); 	}     }

⌨️ 快捷键说明

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