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

📄 pl0.cpp

📁 是一个很好的编译器
💻 CPP
📖 第 1 页 / 共 3 页
字号:
            

/************  PL0.c  *************/

/* pl0 compiler source code */

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <ctype.h>
#include "set.h"
#include "pl0.h"
#include "set.cpp"
/*////////////////////////////////////////*/
/* print error message.*/


void error(int n)
{
    int i;
    
	printf("      ");
	for (i = 1; i <= cc - 1; i++)
		printf(" ");
	printf("^\n");
	printf("Error %3d: %s\n", n, err_msg[n]);
	err++;
} /* error*/

/*//////////////////////////////////////////////////////////////////*/
void getch(void)
{
	if (cc == ll)
	{
		if (feof(infile))
		{
			printf("\nPROGRAM  COMPLETE\n");
			exit(1);
		}
		ll = cc = 0;
		printf("%5d  ", cx);
		while (!feof(infile) && (ch=getc(infile))!='\n')
		{
			printf("%c", ch);
			line[++ll] = ch;
		} /* while*/
		printf("\n");
		line[++ll] = ' ';
	}
	ch = line[++cc];
} /* getch*/

/*/////////////////////////////////*/
/* gets a symbol from input stream.*/
void  getsym(void)
{
	int i, k;
	char a[MAXIDLEN + 1];
	FILE* hbin;
	char ichar='\n';
	hbin = fopen("wdsyml.txt", "a");
	while (isspace(ch))
		getch();

	if (isalpha(ch)!=0)
	{ /* symbol is a reserved word or an identifier.*/
		k = 0;
		do
		{
			if (k < MAXIDLEN)
				a[k++] = ch;
			getch();
		}while (isalnum(ch)!=0);//alpha or digit
		a[k]=0;
		
		strcpy(id, a);
		word[0] = id;
		i = NRW;
		while (strcmp(id, word[i--]));
		if (++i)
		{
			sym = wsym[i]; /* symbol is a reserved word*/
			printf("      %s_wsym[%d]\n",id,i);
			i=i+'0';
			if(i>'9')   i=i+7;

			fwrite(id,1,k+1,hbin);
			fwrite(&i,1,1,hbin);
			fwrite(&ichar,1,1,hbin);
		}
		else
		{//不是保留字,就是标识符
			sym = SYM_IDENTIFIER;   /* symbol is an identifier*/

			//加入识别数组的symbol 处理处理数组
			if(ch=='[')
			{
				sym=SYM_ARRAY;
				getch();
			}
//******************************

		}
	}
	else if (isdigit(ch)!=0)
	{ /* symbol is a number.*/
		
		sym = SYM_NUMBER;
		k = num = 0;
		do
		{
			num = num * 10 + ch - '0';
			k++;
			getch();
		}
		while (isdigit(ch));

		if (k > MAXNUMLEN)
			error(25);     /* The number is too great.*/

	}
	else if(ch == '=')  
	{
		sym=SYM_EQU;
		fwrite(&ch,1,1,hbin);
					fwrite(&ichar,1,1,hbin);
		getch();
		

	}
    else if(ch == ';')  
	{
		sym=SYM_SEMICOLON;
		fwrite(&ch,1,1,hbin);
					fwrite(&ichar,1,1,hbin);
		getch();

	}

	else if (ch == ':')
	{
				fwrite(&ch,1,1,hbin);
							fwrite(&ichar,1,1,hbin);
		getch();
		if (ch == '=')
		{
			sym = SYM_BECOMES; /* :=*/
					fwrite(&ch,1,1,hbin);
								fwrite(&ichar,1,1,hbin);
			getch();
		}
		else               /*加入的 ':'*/
		{
			sym = SYM_MAOHAO;
					fwrite(&ch,1,1,hbin);
								fwrite(&ichar,1,1,hbin);
			getch();

		}
	}
	else if (ch == '>')
	{		fwrite(&ch,1,1,hbin);
				fwrite(&ichar,1,1,hbin);
		getch();
		if (ch == '=')
		{
			sym = SYM_GEQ;     /* >=*/
					fwrite(&ch,1,1,hbin);
									fwrite(&ichar,1,1,hbin);
			getch();
		}
		else
		{
			sym = SYM_GTR;     /* >*/
					fwrite(&ch,1,1,hbin);
								fwrite(&ichar,1,1,hbin);
		}
	}
	else if(ch=='[') { sym=SYM_LP; getch();} /*加入的'['*/
	else if(ch==']') {sym=SYM_RP; getch();}  /*加入的']'*/
	else if(ch=='.')
	{ getch();
	  if(ch=='.')
	  {
		  sym=SYM_TWOPOINT;         /*加入的 '..'*/
		  getch();	
	  }
	  else sym=SYM_PERIOD; 
	}
	else if (ch == '<')
	{
							fwrite(&ch,1,1,hbin);
								fwrite(&ichar,1,1,hbin);
		getch();
		if (ch == '=')
		{
			sym = SYM_LEQ;     /* <=*/
								fwrite(&ch,1,1,hbin);
								fwrite(&ichar,1,1,hbin);
			getch();
		}
		else if (ch == '>')
		{
			sym = SYM_NEQ;     /* <>*/
								fwrite(&ch,1,1,hbin);
								fwrite(&ichar,1,1,hbin);
			getch();
		}
		else
		{
			sym = SYM_LES;     /* <*/
								fwrite(&ch,1,1,hbin);
								fwrite(&ichar,1,1,hbin);
		}
	}

	else if(ch=='$')       /* 加入的布尔运算符*/
	{
	  sym=SYM_AND;
		
	}
	else if(ch=='|')
	{
	 sym=SYM_OR;
		
	}
	else if(ch=='!') sym=SYM_NOT;   /*布尔运算符*/
    //加入以下部分为pl0的注释作准备  
	else if(ch=='(') 
	{					fwrite(&ch,1,1,hbin);
								fwrite(&ichar,1,1,hbin);
		getch();
		if(ch=='*') 
		{
			sym=SYM_EXPL1;
								fwrite(&ch,1,1,hbin);
								fwrite(&ichar,1,1,hbin);
			getch();
		}
		else sym=SYM_LPAREN;
	}

	 else if(ch=='*') 
	{						fwrite(&ch,1,1,hbin);
								fwrite(&ichar,1,1,hbin);
		getch();
		if(ch==')') 
		{
			sym=SYM_EXPL2;
								fwrite(&ch,1,1,hbin);
								fwrite(&ichar,1,1,hbin);
			getch();
		}
		else sym=SYM_TIMES;
	}
//***********************************//

	else
	{ /* other tokens*/
		i = NSYM;
		csym[0] = ch;
		while (csym[i--] != ch);
		if (++i)
		{
			sym = ssym[i];
			fwrite(&ch,1,1,hbin);
			fwrite(&ichar,1,1,hbin);
			getch();

		}

		else
		{
			printf("Fatal Error: %c  is an Unknown character.\n" ,ch );
			exit(1);
		}
	}

} /* getsym*/

//******************加入的处理pl0注释的函数************************
void explanation()
{
	while(ch!='*') getch();
	getsym(); if(sym==SYM_EXPL1) explanation();
	while(sym!=SYM_EXPL2) 
	{
		while(ch!='*') getch();
		if(ch=='*') getsym(); if(sym==SYM_EXPL1) explanation();
	}
	getsym(); if(sym==SYM_EXPL1) explanation();
	
}
/*//////////////////////////////////////////////////////////////////*/
/* generates (assembles) an instruction.*/
void gen(int x, int y, int z)
{
	if (cx > CXMAX)
	{
		printf("Fatal Error: Program too long.\n");
		exit(1);
	}
	code[cx].f = x;
	code[cx].l = y;
	code[cx++].a = z;
} /* gen*/

/*////////////////////////////////////////////////////////////////////*/
/* tests if error occurs and skips all symbols that do not belongs to s1 or s2.*/
void test(symset s1, symset s2, int n)
{
	symset s;

	if (! inset(sym, s1))
	{
		error(n);
		s = uniteset(s1, s2);
		while(! inset(sym, s))
			getsym(); if(sym==SYM_EXPL1) explanation();
		destroyset(s);
	}
} /* test*/

/*////////////////////////////////////////////////////////////////////*/
int dx;  /* data allocation index*/

/* enter object(constant, variable or procedre) into table.*/
void enter(int kind)
{
	mask* mk;
	////////////////////////////
	char str[100];
	char tempstr[10];

	char nl='_', nl1='\n';
	int  strlength;
	int i;
	FILE* ifile;
	if(!(ifile=fopen("ll1.txt","a"))){
		printf("can't be opened!");
		exit(1);
	}
	/////////////////////////////
	tx++;
	//printf("\n_%d_\n",tx);
	strcpy(table[tx].name, id);
	
	strcpy(str,table[tx].name);////////////////////
	table[tx].kind = kind;
	///////////////////////////////////
	sprintf(tempstr,"%d",kind);

	
 //    printf("\n%s\n",str);
	//strcat(str,&nl);
	///////////////////////////////////
	switch (kind)
	{
	case ID_CONSTANT:
		if (num > MAXADDRESS)
		{
			error(25); /* The number is too great.*/
			num = 0;
		}

	///	printf("\n%s\n",tempstr);
		table[tx].value = num;
		sprintf(tempstr,"%d",num);
    	printf("\n_%s_%d_%s\n",table[tx].name,table[tx].kind,tempstr);
		break;
	case ID_VARIABLE:
		mk = (mask*) &table[tx];
		mk->level = level;
		sprintf(str,"%d",level);
        //strcat(str,&nl);
		mk->address = dx++;
		sprintf(tempstr,"%d",dx);
		//strcat(str,tempstr);
		strlength=strlen(str);
		i=0;
		while((strlength--)>=0)
			fwrite(&str[i++],sizeof(char),1,ifile);
		printf("\n_%s_%d_%d_%d_\n",table[tx].name,table[tx].kind,mk->level,mk->address);
		break;
	case ID_PROCEDURE:
		mk = (mask*) &table[tx];
		mk->level = level;
		sprintf(tempstr,"%d",level);
		//strcat(str,&nl);
		//strcat(str,tempstr);
		strlength=strlen(str);
		i=0;
        while((strlength--)>=0)
		fwrite(&str[i++],sizeof(char),1,ifile);
		printf("\n_%s_%d_%d_%d_\n",table[tx].name,table[tx].kind,mk->level,mk->address);
		break;
	case ID_BOOL:        //加入的布尔类型
		mk =(mask *) &table[tx];
		mk->level=level;
		sprintf(tempstr,"%d",level);
		//strcat(str,&nl);
		//strcat(str,tempstr);
		mk->address=dx++;
        sprintf(tempstr,"%d",dx);
		//strcat(str,tempstr);
		strlength=strlen(str);
		i=0;
        while((strlength--)>=0)
		fwrite(&str[i++],sizeof(char),1,ifile);
		printf("\n_%s_%d_%d_%d_\n",table[tx].name,table[tx].kind,mk->level,mk->address);
		break;
	} /* switch*/
for(i=0;i<strlength;i++)
str[i]=0;	
} /* enter*/

/*////////////////////////////////////////////////////////////////////*/
/* locates identifier in symbol table.*/
int position(char* id)
{
	int i;
	strcpy(table[0].name, id);
	i = tx + 1;
	while (strcmp(table[--i].name, id) != 0);
	return i;
} /* position*/

/*/////////////////////////////////////////////////////////////////////*/
void constdeclaration()              
{                                     /*常量的声明*/
	if (sym == SYM_IDENTIFIER)
	{
		getsym(); if(sym==SYM_EXPL1) explanation();
		if (sym == SYM_EQU )
		{
			getsym(); if(sym==SYM_EXPL1) explanation();
	        if (sym == SYM_NUMBER)
			{
			    enter(ID_CONSTANT);
				getsym(); if(sym==SYM_EXPL1) explanation();		
			}
	    	else
			{
		      	error(2); //There must be a number to follow '='.
			}
		}
		else
		{
			error(3); /* There must be an '=' to follow the identifier.*/
		}
	}
	 else error(4); /* There must be an identifier to follow 'const', 'var', or 'procedure'.*/
} /* constdeclaration*/

/*////////////////////////////////////////////////////////////////////*/
void vardeclaration(void)           
{                                    /*标示符的声明 */
	if (sym == SYM_IDENTIFIER)
	{
		enter(ID_VARIABLE);
    	getsym(); 
		if(sym==SYM_EXPL1) explanation();  //处理pl0的注释             
	}

	else  error(4); /* There must be an identifier to follow 'const', 'var', or 'procedure'.*/
} /* vardeclaration*/

/************************************************/
void booldeclaration()
{
    if(sym==SYM_IDENTIFIER)
	{
		enter(ID_BOOL);
		getsym();
	}
    else error(4);
}
/***********************************************/

 void arraydeclaration()

 {
	 getsym();
	 if(sym==SYM_EXPL1) explanation();  //处理pl0的注释
	 if(sym==SYM_NUMBER)
	 {
		 m=num;
		 getsym(); 
		 if(sym==SYM_EXPL1) explanation();  //处理pl0的注释
		 if(sym==SYM_TWOPOINT)
		 {
			 getsym();
			 if(sym==SYM_EXPL1) explanation();  //处理pl0的注释
		 }
		 else error(30);
		 if(sym==SYM_NUMBER) n=num;
	 }
	 else error(26);
	 if(m>n) error(26);
	 else
	 {
		 for(;m<=n;m++)  enter(ID_VARIABLE);
	 }
	 getsym();
	 if(sym==SYM_EXPL1) explanation();//处理pl0的注释
	 if(sym==SYM_RP) 
	 {
		 getsym(); 
	     if(sym==SYM_EXPL1) explanation();//处理pl0的注释
	 }
	 else error(28);
 }

 void fdeclaration(void )   /*此函数是加入的pl0函数的处理过程*/
 {
   getsym(); 
   if(sym==SYM_EXPL1) explanation();//处理pl0的注释
    while(sym!=SYM_RPAREN)
   {
	   
	  if(sym==SYM_IDENTIFIER)
      vardeclaration();
     while (sym==SYM_COMMA)
     {
       getsym(); 
	   if(sym==SYM_EXPL1) explanation();//处理pl0的注释
       if(sym!=SYM_IDENTIFIER)
	   vardeclaration();
      } /*while*/
   }
    if(sym==SYM_RPAREN) 
	{
		getsym();
		if(sym==SYM_EXPL1) explanation();	//处理pl0的注释

	}
   
     else error(22);  
 }/*fdeclaration()*/
/*/////////////////////////////////////////////////////////////////////*/
void listcode(int from, int to)/*显示生成的代码函数*/
{
	int i;

	printf("\nGENERATE CODE AS FOLLOW:\n");
	for (i = from; i < to; i++)
	{
		printf("%5d %s\t%d\t%d\n", i, mnemonic[code[i].f], code[i].l, code[i].a);
	}

⌨️ 快捷键说明

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