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

📄 c0compiler.cpp

📁 简单的c0编译器
💻 CPP
📖 第 1 页 / 共 3 页
字号:
#include<stdio.h>
#include<ctype.h>
#include<string.h>
#include<stdlib.h>
#include"C0Compiler.h"

int linenum=1;					//源程序行号
char name[MAXC][MAXWORD];		//存标识符
int NumOfC=1;					//符号表内元素的个数
Character Char[MAXC];			//符号表
int numoflev[MAXLEV];			//各层的表中变量数

opr  opra[MAXOP];				//存指令
int oprnum;						//指令数

int go[MAXGO];					//运行栈
int dl[MAXGOLEV],bl[MAXGOLEV];	//运行栈辅助指针


int errornum=0,error[MAXERROR],errorline[MAXERROR];

int gonum=0,dlnum=0,blnum=0;

int type=0;
int snum=0;
int start;
int lev=1;
int breakopr,Isbreak=0;	
int typeofexp1=11, typeofexp2=12;
int oprnumcase=0;
int Isret=1;


//错误处理
void error_msg(int i)
{
	fprintf(FOUT,"line(%d)\terror%d:\t\t%s\n",errorline[errornum],i,err_msg[i]);
}
 

//字符获取和处理
int getsym()
{
	char ch;						
	int i,j,m;

	ch=fgetc(FIN);
	while(isspace(ch))//处理空格
	{
		putc(ch,FOUT);
		if(ch=='\n')
		{
			linenum++;
			printf("%d:\t",linenum);
		}
		ch=fgetc(FIN);
	}

	i=0;					
	Word[i]=ch;
	i++;

	//token处理	
	if(isalpha(ch))
	{
		putc(ch,FOUT);
		ch=fgetc(FIN);
		while(isalpha(ch)||isdigit(ch))
		{
			Word[i]=ch;
			i++;

			if(i==MAXWORD)
			{
				errorline[errornum]=linenum;
				error[errornum++]=1;
				i--;
				Word[i]='\0';
				putc(ch,FOUT);
				ch=fgetc(FIN);

				while(isalpha(ch)||isdigit(ch))
				{
					putc(ch,FOUT);
				}
				ungetc(ch,FIN);
				return 1;//是标识符
			}
			putc(ch,FOUT);
			ch=fgetc(FIN);	
		}
		ungetc(ch,FIN);
		Word[i]='\0';

		for(m=0;m<kk;m++)
		{
			if(!(strcmp(Keyword[m],Word)))	//读取的字符串符合对key word的判断
			{
				return m+10;//返回相应的keyword的对应数字
			}
		}
		if(m==kk){
			return 1;//不是key word,是标识符
		}
	}
	
	//数值处理
	if(isdigit(ch))
	{
		putc(ch,FOUT);

		while(isdigit((ch=fgetc(FIN))))
		{
			putc(ch,FOUT);
			Word[i++]=ch;
			if(i==MAXWORD)
			{
				errorline[errornum]=linenum;
				error[errornum++]=1;
				Word[--i]='\0';
				ch=fgetc(FIN);
				while(isdigit(ch))
				{
					putc(ch,FOUT);
				}
				num=atoi(Word);//将字符串转化为对应的数字
				ungetc(ch,FIN);
				return 2;//是数字
			}

		}
		ungetc(ch,FIN);
		Word[i]='\0';
		num=atoi(Word);//将字符串转化为对应的数字
		return 2;//是数字
	}

	
	//分界符
	i=34;
	putc(ch,FOUT);
	switch(ch){
	case'\'':
			ch=fgetc(FIN);
			if(ch=='+'||ch=='-'||ch=='*'||ch=='\''||isalpha(ch)) //对应于printf语句中的各种参数
			{
				cischar=ch;
				putc(ch,FOUT);
				if ((ch=fgetc(FIN))=='\'')
				{
					putc(ch,FOUT);
					return 4;//字符
				}
				else 
				{
					putc(ch,FOUT);
					errorline[errornum]=linenum;
					error[errornum++]=3;
					return -1;
				}
			}
	case'"'://处理“”
			j=0;
			while((ch=fgetc(FIN))!='"')//若不是非空串""
			{
				putc(ch,FOUT);
				sisstring[j++]=ch;

				if(j==MAXLENGTH)
				{
					printf("warning!字符串过长\n");
					sisstring[--j]='\0';
					putc(ch,FOUT);

					ch=fgetc(FIN);
					while(ch!='"')
					{
						putc(ch,FOUT);
						j++;
						if(ch==EOF||j>100)	//字符串过长或缺少反引号
						{
							errorline[errornum]=linenum;
							error[errornum++]=5;
							return -1;
						}
					}
					return 5;//返回字符串
				}
			}
			putc(ch,FOUT);
			sisstring[j]='\0';//字符串结尾
			return 5;//返回空字符串

    case'}':
		return 35;
	case'(':
		i++; 
		return 37;
	case')':
		i++; 
		return 36;
	case';':
		i++; 
		return 38;
	case',':
		i++; 
		return 39;
	case '{':
		i++; 
		return 40;
		
	case'/':
		if((ch=getc(FIN))=='/')//若为单行注释标志
		{
			putc(ch,FOUT);
			while((ch=fgetc(FIN))!='\n')
				putc(ch,FOUT);//注释内容不处理,直接输出
			putc(ch,FOUT);
			linenum++;
			printf("%d:\t",linenum);
			return (getsym());//递归调用,处理下一行代码
		}
		ungetc(ch,FIN);	
		return 34; //仅为/
	case'*':
		return 33;
	case '-':
	case'+':
		if(sym!=0&&sym!=1&&sym!=2)//不在等式中
		{
			j=0;
			Word[j++]=ch;
			ch=fgetc(FIN);
			if(isdigit(ch))
			{	
				Word[j++]=ch;
				putc(ch,FOUT);
				while(isdigit(ch=fgetc(FIN)))
				{
					Word[j++]=ch;
					putc(ch,FOUT);
					if(i==MAXWORD)
					{
						errorline[errornum]=linenum;
						error[errornum++]=1;
						Word[--j]='\0';
						ch=fgetc(FIN);
						while(isdigit(ch))
						{
							putc(ch,FOUT);
						}
						num=atoi(Word);
						ungetc(ch,FIN);
						return 2;//带符号的数字
					}
				}
				ungetc(ch,FIN);
				Word[j]='\0';
				num=atoi(Word);
				return 2;//带符号的数字
			}
		}
		else			//是运算符
		{
			if(ch=='-')
				return 32;
			if(ch=='+')
				return 31;
		}

	case'<':
		if((ch=fgetc(FIN))=='=')
		{
			putc(ch,FOUT);
			return 50;//	<=
		}
		else{				
			ungetc(ch,FIN);
			return 46;//	<
		}
	case'>':					
		if((ch=fgetc(FIN))=='=')
		{
			putc(ch,FOUT);
			return 49;//	>=
		}
		else	
		{				
			ungetc(ch,FIN);
			return 45;//	>
		}
	case'=':	
		if((ch=fgetc(FIN))=='=')
		{
			putc(ch,FOUT);
			return 47;//	==
		}
		else	
		{					
			ungetc(ch,FIN);
			return 51;//	=
		}
	case'!':							
		if((ch=fgetc(FIN))=='=')
		{
			putc(ch,FOUT);
			return 48;//	!=
		}
		else
		{							//不存在单独的!作为操作符
			ungetc(ch,FIN);
			errorline[errornum]=linenum;
			error[errornum++]=2;
		}
	}
	return 0;//出错
}


//分析程序
int program()			
{
	int   i;
	char c;
	printf("%d:\t",linenum);
	sym=getsym();
	if(sym==10)
	{
		sym=getsym();
		if(constdeclaration())
		{
			while((c=fgetc(FIN))!=EOF)
			{	
				putc(c,FOUT);
				if(c=='\n')
				{
					linenum++;
					printf("%d:\t",linenum);
				}
			}
			printf("\n");
			return 1;
		}
	}
	if(sym==11||sym==12) 
	{
		i=sym;
		sym=getsym();
		if(sym==1)
		{
			strcpy(name[NumOfC],Word);
			sym=getsym();
			if(sym!=39&&sym!=38&&sym!=37)
			{
				errorline[errornum]=linenum;
				error[errornum++]=22;
				while((c=fgetc(FIN))!=EOF)
					{	
						putc(c,FOUT);
						if(c=='\n')
						{
							linenum++;
							printf("%d:\t",linenum);
						}
					}
				printf("\n");
				return 1;
			}

			if(sym==38||sym==39)
			{
				if( vardefine(i))
				{
					while((c=fgetc(FIN))!=EOF)
					{	
						putc(c,FOUT);
						if(c=='\n')
						{
							linenum++;
							printf("%d:\t",linenum);
						}
					}
					printf("\n");
					return 1;
				}
			}

			while(sym==37)
			{
				if(returnfunction(i))
				{
					while((c=fgetc(FIN))!=EOF)
					{	
						putc(c,FOUT);
						if(c=='\n')
						{
							linenum++;
							printf("%d:\t",linenum);
						}
					}
					printf("\n");
					return 1;
				}

				if(sym==11||sym==12)
				{
					sym=getsym();
					if(sym==1)
					{
						strcpy(name[NumOfC],Word);
						if((sym=getsym())==37)
							continue;
						else 
						{
							errorline[errornum]=linenum;
							error[errornum++]=17;
							while((c=fgetc(FIN))!=EOF)
							{	
								putc(c,FOUT);
								if(c=='\n')
								{
									linenum++;
									printf("%d:\t",linenum);
								}
							}
							printf("\n");
							return 1;
						}
					}
					else
					{
						errorline[errornum]=linenum;
						error[errornum++]=27;
						while((c=fgetc(FIN))!=EOF)
						{	
							putc(c,FOUT);
							if(c=='\n')
							{
								linenum++;
								printf("%d:\t",linenum);
							}
						}
						printf("\n");
						return 1;
					}
				}
				else 
					break;
			}
			
		}
		else
		{
			errorline[errornum]=linenum;
			error[errornum++]=27;
			while((c=fgetc(FIN))!=EOF)
			{	
				putc(c,FOUT);
				if(c=='\n')
				{
					linenum++;
					printf("%d:\t",linenum);
				}
			}
			printf("\n");
			return 1;
		}
	}
	if(sym==13)
	{
		sym=getsym();
		while(sym==1)
			if(voidfunction())
			{
				while((c=fgetc(FIN))!=EOF)
				{	
					putc(c,FOUT);
					if(c=='\n')
					{
						linenum++;
						printf("%d:\t",linenum);
					}
				}
				printf("\n");
				return 1;
			}
		if(sym==14)
		{
			if(mainfunction())
			{
				while((c=fgetc(FIN))!=EOF)
				{	
					putc(c,FOUT);
					if(c=='\n')
					{
						linenum++;
						printf("%d:\t",linenum);
					}
				}
				printf("\n");
				return 1;
			}
			else 
				return 0;
		}
	}
	else 
	{
		errorline[errornum]=linenum;
		error[errornum++]=15;
		while((c=fgetc(FIN))!=EOF)
		{	
			putc(c,FOUT);
			if(c=='\n')
			{
				linenum++;
				printf("%d:\t",linenum);
			}
		}
		printf("\n");
		return 1;
	}
	return 0;
}


//分析常量说明部分  
int constdeclaration()					
{
	 if(sym==11||sym==12)
	 {
		 if(!constdefine(sym))
		 {
			 if(sym==38)
			 {
				 if((sym=getsym())==10)
				 {
					 sym=getsym();
					 return(constdeclaration());
				 }
				 else 
					 return 0;
			 }
			 else 
			 {
				 errorline[errornum]=linenum;
				 error[errornum++]=22;
				 return 1;
			 }
		 }
		 else 
			 return 1;
	 }
	 else
	 {
		 errorline[errornum]=linenum;
		 error[errornum++]=4;
		 return 1;
	 }
}



//分析常量定义
int constdefine(int type )						
{ 
	if((sym=getsym())==1)
	{
		strcpy(name[NumOfC],Word);
		if((sym=getsym())==51)
		{
			sym=getsym();
			if(sym==2&&type==11||sym==4&&type==12)
			{
				if(enter(lev,type,4))
					 return 1;
				if((sym=getsym())==39)
					return(constdefine(type));
			}
			else 
			{
				errorline[errornum]=linenum;
				error[errornum++]=28;
				return 1;
			}
		}
		else
		{ 
			errorline[errornum]=linenum;
			error[errornum++]=9;
			return 1;
		}
	}
	else
	{ 
		errorline[errornum]=linenum;
		error[errornum++]=27;
		return 1;
	}
	return 0;
}


 
//分析变量说明部分  
int vardefine(int type)		
{
	if(enter(lev,type,0))
		return 1;
	if(sym==39)
	{
		if((sym=getsym())==1)
		{
			strcpy(name[NumOfC],Word);
			sym=getsym();
			return(vardefine(type));
		}
		else	
		{
			errorline[errornum]=linenum;
			error[errornum++]=27;
			return 1;
		}
	}
	if(sym==38)
	{
		sym=getsym();
		if(sym==12||sym==11)
		{
			int i=sym;
			if((sym=getsym())==1)
			{
				strcpy(name[NumOfC],Word);
				sym=getsym();
				if(sym==39||sym==38)
				{
					if(vardefine(i))
						return 1;
				}
				else if(sym==37)
					return 0;
				else 
				{
					errorline[errornum]=linenum;
					error[errornum++]=22;
					return 1;
				}
			}
			else 
			{
				errorline[errornum]=linenum;
				error[errornum++]=27;
				return 1;
			}
		}
		else
			return 0;
	}
	else 
	{
		errorline[errornum]=linenum;
		error[errornum++]=22;
		return 1;
	}
	return 0;
}



//把变量填入符号表
int enter(int lev,int type,int kind)			
{
	if(NumOfC<MAXC-1)
	{
		if(charcheck()&&kind!=3)
		{
			errorline[errornum]=linenum;
			error[errornum++]=8;
			return 1;
		}
		Char[NumOfC].lev=lev;
		Char[NumOfC].kind=kind;
		Char[NumOfC].type=type;
		Char[NumOfC].name=name[NumOfC];
		if(kind==0||kind==3)
			Char[NumOfC].adr=++numoflev[lev];
		else	
			Char[NumOfC].adr=oprnum;
	
			if(kind==4)
			{
				if(type==11)

⌨️ 快捷键说明

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