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

📄 grammer.y

📁 这是我自己实现的一个微小的编译程序,附可执行代码的虚拟机,是理解编译原理的绝好材料.
💻 Y
📖 第 1 页 / 共 2 页
字号:
							}
	;
T	:T '*' F					{int temp=0;
							 $$.sym_off=sym_off++;
							 if((symtab[$1.sym_off].type==INT)&&(symtab[$3.sym_off].type==INT))
							 {
							 	symtab[$$.sym_off].type=INT;
							 	symtab[$$.sym_off].place = mem_off++;
							 	emitCode(op_mult,symtab[$1.sym_off].place,symtab[$3.sym_off].place,symtab[$$.sym_off].place);
							 }
							 else if((symtab[$1.sym_off].type==INT)&&(symtab[$3.sym_off].type==REAL))
							 {
							 	symtab[$$.sym_off].type=REAL;
							 	symtab[$$.sym_off].place = mem_off++;
							 	//symtab[$1.sym_off].type=REAL;		/*如果存储是常量或变量被以后用到,为避免再次转换,所以要设置类型,否则生成代码产生错误结果*/
							 	temp=mem_off;
							 	emitCode(op_mov,symtab[$1.sym_off].place,-1,temp);
							 	emitCode(op_inttoreal,temp,-1,temp);
							 	emitCode(op_fmult,temp,symtab[$3.sym_off].place,symtab[$$.sym_off].place);
							 }
							 else if((symtab[$1.sym_off].type==REAL)&&(symtab[$3.sym_off].type==INT))
							 {
							 	symtab[$$.sym_off].type=REAL;
							 	symtab[$$.sym_off].place = mem_off++;
							 	//symtab[$1.sym_off].type=REAL;		/*如果存储是常量或变量被以后用到,为避免再次转换,所以要设置类型,否则生成代码产生错误结果*/
							 	temp=mem_off;
							 	emitCode(op_mov,symtab[$1.sym_off].place,-1,temp);
							 	emitCode(op_inttoreal,temp,-1,temp);
							 	emitCode(op_fmult,temp,symtab[$3.sym_off].place,symtab[$$.sym_off].place);
							 	
							 }
							 else if((symtab[$1.sym_off].type==REAL)&&(symtab[$3.sym_off].type==REAL))
							 {
							 	symtab[$$.sym_off].type=REAL;
							 	symtab[$$.sym_off].place = mem_off++;
							 	emitCode(op_fmult,symtab[$1.sym_off].place,symtab[$3.sym_off].place,symtab[$$.sym_off].place);
							 	
							 }
							 else
							 {
							 	type_error();
							 }
							 
							}
	|T '/' F					{int temp=0;
							 $$.sym_off=sym_off++;
							 if((symtab[$1.sym_off].type==INT)&&(symtab[$3.sym_off].type==INT))
							 {
							 	symtab[$$.sym_off].type=INT;
							 	symtab[$$.sym_off].place = mem_off++;
							 	emitCode(op_div,symtab[$1.sym_off].place,symtab[$3.sym_off].place,symtab[$$.sym_off].place);
							 }
							 else if((symtab[$1.sym_off].type==INT)&&(symtab[$3.sym_off].type==REAL))
							 {
							 	symtab[$$.sym_off].type=REAL;
							 	symtab[$$.sym_off].place = mem_off++;
							 	//symtab[$1.sym_off].type=REAL;		/*如果存储是常量或变量被以后用到,为避免再次转换,所以要设置类型,否则生成代码产生错误结果*/
							 	temp=mem_off;
							 	emitCode(op_mov,symtab[$1.sym_off].place,-1,temp);
							 	emitCode(op_inttoreal,temp,-1,temp);
							 	emitCode(op_fdiv,temp,symtab[$3.sym_off].place,symtab[$$.sym_off].place);
							 }
							 else if((symtab[$1.sym_off].type==REAL)&&(symtab[$3.sym_off].type==INT))
							 {
							 	symtab[$$.sym_off].type=REAL;
							 	symtab[$$.sym_off].place = mem_off++;
							 	//symtab[$1.sym_off].type=REAL;		/*如果存储是常量或变量被以后用到,为避免再次转换,所以要设置类型,否则生成代码产生错误结果*/
							 	temp=mem_off;
							 	emitCode(op_mov,symtab[$1.sym_off].place,-1,temp);
							 	emitCode(op_inttoreal,temp,-1,temp);
							 	emitCode(op_fdiv,temp,symtab[$3.sym_off].place,symtab[$$.sym_off].place);
							 	
							 }
							 else if((symtab[$1.sym_off].type==REAL)&&(symtab[$3.sym_off].type==REAL))
							 {
							 	symtab[$$.sym_off].type=REAL;
							 	symtab[$$.sym_off].place = mem_off++;
							 	emitCode(op_fdiv,symtab[$1.sym_off].place,symtab[$3.sym_off].place,symtab[$$.sym_off].place);
							 	
							 }
							 else
							 {
							 	type_error();
							 }
							}
	|F						{
							 	$$.sym_off=$1.sym_off;
							}
	;
F	:'(' E ')'					{$$.sym_off=$1.sym_off;}
	|integerConst					{$$.sym_off=sym_off++;
							 symtab[$$.sym_off].type=INT;
							 symtab[$$.sym_off].place=mem_off++;
							 emitCode(op_cmov,$1.ival,-1,symtab[$$.sym_off].place);
							}
	|realConst					{$$.sym_off=sym_off++;
							 symtab[$$.sym_off].type=REAL;
							 symtab[$$.sym_off].place=mem_off++;
							 emitFCode(op_fcmov,$1.dval,-1,symtab[$$.sym_off].place);
							}
	|identifier					{int p=lookup($1.idname);
							 if(p==-1){printf("ERROR:line %d variable %s is undefined.",yylineno,name+$1.idname);exit(1);}
							 $$.sym_off=p;
							}
	;
BE	:AndBE						{$$.sym_off=$1.sym_off;}
	|AndBE OR M1 BE					{$$.sym_off=sym_off++;
							 if((symtab[$1.sym_off].type==BOOL)&&(symtab[$3.sym_off].type==BOOL))
							 {
							 	backpatch(symtab[$1.sym_off].falselist,symtab[$3.sym_off].place);
							 	symtab[$$.sym_off].truelist=merge(symtab[$1.sym_off].truelist,symtab[$4.sym_off].truelist);
							 	symtab[$$.sym_off].falselist=symtab[$4.sym_off].falselist;
							 	//symtab[$$.sym_off].place=mem_off++;
							 	//emitCode(op_or,symtab[$1.sym_off],place,symtab[$3.sym_off].place,symtab[$$.symtab].place);
							 }
							 else
							 {
							 	type_error();	
							 }
							}
	|AndBE XOR M1 BE				{$$.sym_off=sym_off++;
							 if((symtab[$1.sym_off].type==BOOL)&&(symtab[$4.sym_off].type==BOOL))
							 {
							 	backpatch(symtab[$1.sym_off].truelist,symtab[$3.sym_off].place);
							 	backpatch(symtab[$1.sym_off].falselist,symtab[$3.sym_off].place);
							 	backpatch(symtab[$4.sym_off].truelist,code_off);
							 	backpatch(symtab[$4.sym_off].falselist,code_off);
							 	symtab[$$.sym_off].place=mem_off++;
							 	emitCode(op_xor,symtab[$1.sym_off].place,symtab[$3.sym_off].place,symtab[$$.sym_off].place);
							 	symtab[$$.sym_off].truelist=symtab[$$.sym_off].falselist=NULL;	/*不需要回填*/
							 }
							 else
							 {
							 	type_error();	
							 }
							}
	;
AndBE	:NotBE						{$$.sym_off=$1.sym_off;}
	|NotBE AND  M1 AndBE				{$$.sym_off=sym_off++;
							 if((symtab[$1.sym_off].type==BOOL)&&(symtab[$4.sym_off].type==BOOL))
							 {
							 	backpatch(symtab[$1.sym_off].truelist,symtab[$2.sym_off].place);
							 	symtab[$$.sym_off].truelist=symtab[$3.sym_off].truelist;
							 	symtab[$$.sym_off].falselist=merge(symtab[$1.sym_off].falselist,symtab[$4.sym_off].falselist);
							 	symtab[$$.sym_off].place=mem_off++;
							 	emitCode(op_and,symtab[$1.sym_off].place,symtab[$3.sym_off].place,symtab[$$.sym_off].place);
							 }
							 else
							 {
							 	type_error();	
							 }
							}	
	;
NotBE 	:RelBE						{$$.sym_off=$1.sym_off;}
	|NOT '(' BE ')'					{$$.sym_off=sym_off++;
							 if(symtab[$3.sym_off].type==BOOL)
							 {
							 	symtab[$$.sym_off].place=mem_off++;
							 	symtab[$$.sym_off].truelist=symtab[$3.sym_off].falselist;
							 	symtab[$$.sym_off].falselist=symtab[$3.sym_off].truelist;
							 	//emitCode(op_neg,symtab[$3.sym_off].place,-1,symtab[$$.sym_off],place);
							 }
							 
							}
RelBE	:E RelOP E					{$$.sym_off=sym_off++;
							 symtab[$$.sym_off].place=mem_off++;
							 symtab[$$.sym_off].type=BOOL;
							 symtab[$$.sym_off].truelist=makelist(code_off+2);
							 symtab[$$.sym_off].falselist=makelist(code_off+1);
							 switch($2.relop)
							 {
							 	case RA:operator=op_a;break;
							 	case RAE:operator=op_ae;break;
							 	case RE:operator=op_e;break;
							 	case RB:operator=op_b;break;
							 	case RBE:operator=op_be;break;
							 	
							 	
							 }/*经过试验,关系操作操作数可以是不同类型,不用转换*/
							 emitCode(operator,symtab[$1.sym_off].place,symtab[$3.sym_off].place,symtab[$$.sym_off].place);
							 emitCode(op_zjmp,symtab[$$.sym_off].place,-1,-1);/*不成立时为0跳转*/
							 emitCode(op_jmp,-1,-1,-1);
							}
	;

%%


int lookup(int nameoff)					/*查找标识符表*/
{
	int i,rel;
	for(i=0;i<sym_off;i++)
	{
		if(symtab[i].class==identifier)
		{
			rel=strcmp(name+symtab[i].idname,name+nameoff);
			if(rel==0){return i;}
		}
	}
	return -1;
}

void enterID(int offset,int nameoff,int type)
{
	symtab[offset].idname=nameoff;
	symtab[offset].type=type;
	symtab[offset].class=identifier;
}

void addType(int sym_off,int type)
{
	//symtab[sym_off].type = type;
	symtab[sym_off].place = mem_off++;
	//attrib[i].place = offset;
	//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);
}

⌨️ 快捷键说明

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