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

📄 yufafenxi.cpp

📁 编译原理中,一些解释器的实验~以及相关操作
💻 CPP
字号:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<malloc.h>

#define max 50
#define NULL 0
#define ERROR -1

int k=0;
int value=0;
int temp=0;
int flage0=1;
int flage1=0;
int flage2=0;
int count=-1;
int bdsNo=0;

struct Recode
{
	char idname[20];
	int idNo;
}id[20],newtemp[20];//标识符表结构

struct idtab
{
	char name[20];
	int type;//整型——2;字符型——1;
}bds[100];
//////////////////////////////////////////////栈//////////////////////////////////////////////////


struct stack
{
	int *base;
	int *top;
	int stacksize;
};


void Initstack(struct stack *p)
{
	p->base=(int*)malloc(max*sizeof(int));
	p->top=p->base;
	p->stacksize=max;
}//顺序表实现栈的初始化




void push(struct stack *p,int e)
{
	if((p->top-p->base)>=max)
	{
		p->base=(int*)realloc(p->base,(p->stacksize+1)*sizeof(int));
		p->top=p->base+p->stacksize;
		p->stacksize+=1;
	}
	*p->top++=e;
}//顺序表实现进栈

int pop(struct stack *p)
{
	int e;
	if(p->top==p->base)
	return(-1);
	e=*--p->top;
	return(e);
}//顺序表实现出栈

int Gettop(struct stack *s)
{
	int e;
	int *q;
	if(s->top!=s->base)
	{q=s->top;
	e=*(q-1);}
	return(e);

}

/////////////////////////////////////////////////////////////////////////////////////////////////////////


void Baoliuzi(char take[])
{   
	char *keyword[13]={"program","var","procedure","begin","end","if","then","else","while","do","call","integer","real"};

	int i=0;
		
	for(int j=0;j<13;j++)
	{
	   if(strcmp(take,keyword[j])==0)
		   switch(j)
	   {
		case 0:printf("program:(3,0)\n");flage0=0;break;
		case 1:printf("var:(4,0)\n");flage0=0;break;
		case 2:printf("procedure:(5,0)\n");flage0=0;break;
		case 3:printf("begin:(6,0)\n");flage0=0;break;
		case 4:printf("end:(7,0)\n");flage0=0;break;
		case 5:printf("if:(8,0)\n");flage0=0;break;
		case 6:printf("then:(9,0)\n");flage0=0;break;
		case 7:printf("else:(10,0)\n");flage0=0;break;
		case 8:printf("while:(11,0)\n");flage0=0;break;
		case 9:printf("do:(12,0)\n");flage0=0;break;
		case 10:printf("call:(13,0)\n");flage0=0;break;
        case 11:printf("integer:(14,0)\n");flage0=0;break;
		case 12:printf("real:(15,0)\n");flage0=0;break;
	   }//switch
	  }//for循环结束
	  
      if(flage0==1)
	   {   
		  
           strcpy(id[temp].idname,take);
		   
		   for(int x=0;x<temp;x++)
		   { 
			   if(strcmp(id[x].idname,id[temp].idname)==0)
			   {
				   flage1=1;
			       flage2=x;
			   }
			   
        
		   }
		   if(flage1==0)
		   {
			   value++;
		       id[temp].idNo=value;
			   printf("%s:(1,%d)\n",id[temp].idname,id[temp].idNo);
               strcpy(bds[bdsNo].name,id[temp].idname);
			   bds[bdsNo].type=1;
			   temp++;bdsNo++;
		   }
		   else if(flage1==1)
		   {
		       printf("%s:(1,%d)\n",id[flage2].idname,id[flage2].idNo);
               strcpy(bds[bdsNo].name,id[temp].idname);
			   bds[bdsNo].type=1;
			   bdsNo++;
			   
		   }
	   }
     flage0=1;
  
}

int Precede(int aa,int bb)
{
	int cc;
	if(bb==17&&aa!=33) 
		cc=-1;
	else if(aa==17&&bb!=33)
		cc=-1;
	else if(bb==33&&aa!=17)
		cc=1;
	else if(aa==33&&bb!=17)
		cc=1;
	else if(aa==17&&bb==33)
		cc=0;
	else
	{
		if(aa>bb||aa==bb)cc=1;
		if(aa<bb)cc=-1;
	}
	return(cc);
}

void ncount()
{
	count--;
}

void bdshi ( )
{//OP为运算符集合。
	struct stack optr;
	struct stack opnd;
	Initstack(&optr);    
	push (&optr,-1);
	Initstack(&opnd);
	int w=0;
//用其在bds[]中的序号来标记	 
	while(w!=bdsNo||Gettop(&optr)!=-1)
	{
		if((bds[w].type==1)||(bds[w].type==2)) //判断W是否 是运算符
		{
			push(&opnd,w);w++;
		} //不是运算符则进栈
		else switch (Precede(bds[Gettop(&optr)].type, bds[w].type))
		{
			case -1:// 新输入的算符 w 优先级高,w 进栈
				push(&optr, w ); w++;   break;
			case 0:       // 去括号并接收下一字符
				int x;x=pop(&optr);w++; break;
			case 1:    //新输入的算符优先级低,取栈顶算符 运算
				int t;
				t=pop(&optr);
				int b;
				b=pop(&opnd);
				int a;
				a=pop(&opnd);
				ncount();
				if(a<(-1)&&b>=0)
					printf("(%s,T%d,%s,T%d)",bds[t].name,-a,bds[b].name,-count);
				if(a>=0&&b<(-1))
					printf("(%s,%s,T%d,T%d)",bds[t].name,bds[a].name,-b,-count);
				if(a<(-1)&&b<(-1))
					printf("(%s,T%d,T%d,T%d)",bds[t].name,-a,-b,-count);
				if(a>=0&&b>=0) 
					printf("(%s,%s,%s,T%d)",bds[t].name,bds[a].name,bds[b].name,-count);
				printf("\n");
				push(&opnd,count);
				break;          
		}				
	}   	
}


void main()
{
	FILE *fp;
	if((fp=fopen("input.txt","r"))==NULL)
	{
		printf("cannot open this file\n");
		exit(0);
	}

	char s[500];
	char token[20];

	int i=0;
	while(!feof(fp))
	{ 
		fread(&s[i],sizeof(char),1,fp);
		i++;
	}

	s[i++]='\0';//把文件内容读到s数组中

	char ch;
	k=0;
	ch=s[k];

	while(ch!='\0')
	{
		int flage=1;
		if(ch>='a'&&ch<='z')
		{  
			int p=0;
			while((ch>='a'&&ch<='z')&&(flage==1)||(ch>='0'&&ch<='9'))
			{ 
				token[p++]=ch;
				ch=s[++k];

				if(p==8)
				{  
					int z=1;
					do
					{
						k++;
						ch=s[k];
						if(ch!=' '||ch!='\n')
							z=0;
					}
					while(z==1);
					flage=0;
				}
			}
			token[p++]='\0';
			Baoliuzi(token);
			
			if(ch==' ')
			{
				k++;ch=s[k];
			}
		}//保留字
		else if(ch==' ')
		{
			k++;ch=s[k];
		}//处理空格
		else if(ch=='\n')
		{
			k++;ch=s[k];
		}//处理回车
		else if(ch>='0'&&ch<='9')
		{ 
			int No=0;
			if(s[k+1]>='a'&&s[k+1]<='z')
			{ 
				int flag=1;
				printf("**error(1)**\n");
				do
				{
					k++;
					ch=s[k];
					if(ch!='\n'||ch!=' ')
						flag=0;
				}while(flag==1);
				k++;ch=s[k];
			}
			else
			{  
				int ei=0;
				while(ch>='0'&&ch<='9')
				{
					No=No*10+(ch-'0');
					bds[bdsNo].name[ei++]=(char)ch;
					ch=s[++k];
				}
				printf("%d:(2,%d)\n",No,No);
				bds[bdsNo].type=2;bdsNo++;
				if(ch==' ')
				{
					k++;ch=s[k];
				}
			}
		}//数字
		else 
		{
			switch(ch)
			{
			case '+':
				{
					printf("+:(17,0)\n");bds[bdsNo].name[0]='+';
					bds[bdsNo].type=18;bdsNo++;break;
				}
			case '-':
				{
					printf("-:(18,0)\n");bds[bdsNo].name[0]='-';
					bds[bdsNo].type=18;bdsNo++;break;
				}
			case '*':
				{
					printf("*:(19,0)\n");bds[bdsNo].name[0]='*';
					bds[bdsNo].type=19;bdsNo++;break;
				}
			case '/':
				{  
					char c;
					c=s[k+1];
					if(c!='*')
					{
						printf("/:(20,0)\n");bds[bdsNo].name[0]='/';
						bds[bdsNo].type=19;bdsNo++;break;
					}
					else 
					{   
						k++;
						ch=s[k];
						int fl=1;
						do
						{
							do
							{  
								k++;
								ch=s[k];
							}while(ch!='*');
							if(s[k+1]=='/')
							{
								k++;ch=s[k];fl=0;
							}
							else
							{
								do
								{  
									k++;
									ch=s[k];
								}while(ch!='*');
								if(s[k+1]=='/')
								{
									k++;ch=s[k];fl=0;
								}

							}
							if(s[k+1]=='\0')
								fl=0;
						}while(fl==1);
						break; 
					}
				}
			case '~':printf("~:(21,0)\n");break;
			case '<':
				{
					char c;
					c=s[k+1];
					if(c!='=')
					{
						printf("<:(22,0)\n");
						break;
					}
					else if(c=='>')
					{
						printf("<>:(27,0)\n");
						break;
					}
					else {
						printf("<=:(23,0)\n");
						k++;ch=s[k];
						break;
					}
				}
			case '>':
				{
					char c;c=s[k+1];
					if(c!='=')
					{
						printf(">:(24,0)\n");
						break;
					}
					else 
					{
						printf(">=:(25,0)\n");
						k++;
						ch=s[k];
						break;
					}
				}
			case '=':
				{
					printf("=:(16,0)\n");
					bds[bdsNo].name[0]='=';
					bds[bdsNo].type=16;
					bdsNo++;break;
				}
			case ':':
				{
					char c;c=s[k+1];
					if(c=='=')
					{
						printf(":=:(28,0)\n");
					    k++;ch=s[k];
						break;
					}
	
					else 
					{
						printf("::(34,0)\n");
						break;
					}
				}
			case ';':
				{
					printf(";:(29,0)\n");
					break;
				}
			case '.':
				{
					printf(".:(30,0)\n");
					break;
				}
			case ',':
				{
					printf(",:(31,0)\n");
					break;
				}
			case '(':
				{
					printf("(:(32,0)\n");
					bds[bdsNo].name[0]='(';
					bds[bdsNo].type=17;
					bdsNo++;break;
				}
			case ')':
				{
					printf("):(33,0)\n");
					bds[bdsNo].name[0]=')';
					bds[bdsNo].type=33;
					bdsNo++;
					break;
				}
			default:
				{
					if(s[k+1]!='\0'){
						printf("**error(1)**\n");
						break;
					}
					else break;
				}
			}//switch
			k++;ch=s[k];
		}//处理符号
	}
	printf("\n");
	bdshi();

	fclose(fp);
}

⌨️ 快捷键说明

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