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

📄 bianyi.cpp

📁 另一版本的词法分析器
💻 CPP
字号:
#include<iostream.h>
#include<stdio.h>
/*定义的原始产生式的类型号,以后程序通过它进行检索
#define id 1
#define const 10
#define := 2
#define + 3
#define - 4
#define * 5
#define / 6
#define ( 21
#define ) 22
#define > 23
#define < 24
#define = 25
#define if 100
#define then 101
#define while 102
#define do 103
#define else 104
#define S->id:=E 1
#define E->E+E 2
#define E->E-E 3
#define E->E*E 4
#define E->E/E 5
#define E->-E 6
#define E->(E) 7
#define E->id 8
#define E->num 9
#define C->E>E 10
#define C->E<E 11
#define S->if C then S 12
#define C->E=E 13
#define S->if C then S else S 14
#define S->while C do S  15*/

int lookhead;		//当前待分析的单词

/*保存语法分析产生的树结构数组,在构造分析树的过程中为
每个产生式赋予一个唯一的编号,该数组的
www[][1]第一唯数表示哪个编号的产生式
www[][2]……右部第一个非终结符产生的产生式编号,第二个……产生式编号*/
int w[20][20];

/*保存各产生式的有关标号
[][0]begin,[][1]next,[][2]true,[][3]false标号的符号表序号*/
int label[20][4];	

/*符号表,数组中每一个元素存储输入的标识符和数字,以及在程序中产生的
临时变量newtemp()和标号newlabel()的字符串表示形式,可通过序号检索*/
char chart[70][40];

int number,		//产生式的编号
	code=0,		//符号表序号
/*生新的临时变量名中起作用chart[30]~char[50]保存产生的临时变量名*/
	temp=30,
	temp1='0',	//用来生成不同临时变量的chart[][*]
/*在新的标号名中起作用,同temp,temp1*/
	stemp=50,stemp1='0';

/*====================词法分析子程序==================*/
/*每次调用可以从输入流中划分出一个单词
返值int:单词的属性值
         结尾返回	   0
	     错误字符返回-1
输入ch:	当前读入字符*/
int cifa()			//这是一个全局函数
{
	int ch,i=0;
	int isletter(int);
	int isdigit(int);
	int rightchar(char);
	int key(char *a);

	ch=getc(stdin);
	while ((ch==' ')||(ch==10))
			 ch=getc(stdin);
	if(ch==-1) return(0);
	if ((!rightchar(ch))&&(ch!=-1))
	{
		cout<<"\nerror %c isn't in my language"<<ch;
		return(-1);
	}
	if (isdigit(ch))
	{
		code++;
		while(isdigit(ch))
		{
			chart[code][i]=ch;
			ch=getc(stdin);
			i++;
		}
		chart[code][i]=0;
		ungetc(ch,stdin);
		return(10);
	}
	if(isletter(ch))
	{
		code++;
		while (isletter(ch)||isdigit(ch))
		{
			chart[code][i]=ch;
			ch=getc(stdin);
			i++;
		}
		chart[code][i]=0;
		ungetc(ch,stdin);
		return(key(chart[code]));
	}
	if(ch==':')
	{
		ch=getc(stdin);
		if(ch=='=')
			return (2);
		else
			return(0);
	}
	if(ch=='+')  return (3);
	if(ch=='-')  return (4);
	if(ch=='*')  return (5);
	if(ch=='/')  return (6);
	if(ch=='(')  return (21);
	if(ch==')')  return (22);
	if(ch=='>')  return (23);
	if(ch=='<')  return (24);
	if(ch=='=')  return (25);
}
//--------------cifa()的子函数--------------
int isletter(int ch)	//是否为字母 true 1 false 0
{
	if(((ch>='a')&&(ch<='z'))||((ch>='A')&&(ch<='Z')))
		return(1);
	else return(0);
}
int isdigit(int ch)		//是否为数字 true 1 false 0
{
	if((ch>='0')&&(ch<='9'))
		return(1);
	else return(0);
}
int rightchar(char ch)	//是否合法的字符 true 1 false 0
{
   if   (((ch>='0')&&(ch<='9'))
	   ||((ch>='a')&&(ch<='z'))
	   ||((ch>='A')&&(ch<='Z'))
	   ||(ch==10)||(ch==':')||(ch=='=')
	   ||(ch=='+')||(ch=='-')||(ch=='*')||(ch=='/')
	   ||(ch=='(')||(ch==')')||(ch=='>')||(ch=='<'))
	   return(1);
	   else return(0);
}
int key(char *a)		//是否关键字  true 关键字属性值 false 1
{
  if ((a[0]=='i')&&(a[1]=='f')&&(a[2]==0))//if
	  return(100);
  if ((a[0]=='t')&&(a[1]=='h')&&(a[2]=='e')&&(a[3]=='n')&&(a[4]==0))
	  return(101);						  //then	
  if ((a[0]=='w')&&(a[1]=='h')&&(a[2]=='i')&&(a[3]=='l')&&(a[4]=='e')&&(a[5]==0))
	  return(102);						  //while	
  if ((a[0]=='d')&&(a[1]=='o')&&(a[2]==0))
	  return(103);						  //else	
  if ((a[0]=='e')&&(a[1]=='l')&&(a[2]=='s')&&(a[3]=='e')&&(a[4]==0))
	  return(104);
  return(1);
}
/*=====================语法分析======================*/
/*匹配一个单词,并且调用下一个单词
参数:匹配的单词——用属性值表示
返值:成功 1 失败 0*/
int match(int t)		//全局函数!
{
    int cifa();
	if (lookhead==t)
	{
		lookhead=cifa();
		return(1);
	}
	else return(0);
}
//语法分析递归子程序之一
int s1()
{
   int c1();
   int e1();
   //int match(int);
   int a,b,c,d,a1,i,j;
   switch(lookhead)
   {
   case 1:
	   a1=code;
	   a=match(1);
	   b=match(2);
	   c=e1();
	   number++;
	   if(a&&b&&c)
	   {
	   /*cout<<("S->id:=E");*/
	   w[number][0]=1;
	   w[number][1]=c;
	   w[number][2]=a1;
	   w[number][3]=0;
	   /*cout<<("   number=%d,	style=%d,	next1=%d,	id=%s\n",	number,1,c,chart[a1]);*/
	   if((lookhead==0)||(lookhead==104))
		   return(number);
	   else return(0);
	   }
	   else
		   return(0);
   case 100:
	   a=match(100);
	   b=c1();
	   c=match(101);
	   d=s1();
	   if (lookhead!=104)
	   {
		   if(lookhead!=0) return(0);
		   number++;
		   if(a&&b&&c&&d)
		   {
			   /*cout<<("S->if C then S");*/
			   w[number][0]=12;
			   w[number][1]=b;
			   w[number][2]=d;
			   w[number][3]=0;
			   /*cout<<("		number=%d,	style=%d,	next1=%d,	next2=%d\n",number,12,b,d);*/
			   return(number);
		   }
		   else
			   return(0);
	   }
	   else
	   {
		   i=match(104);
		   if (lookhead==0) return(0);
		   j=s1();
		   number++;
		   if(a&&b&&c&&d&&i&&j)
		   {
			   if(lookhead!=0) return(0);
			   /*cout<<("S->if C then S else S");*/
			   w[number][0]=14;
			   w[number][1]=b;
			   w[number][2]=d;
			   w[number][3]=j;
			   w[number][4]=0;
			   /*cout<<("	number=%d,  style=%d,   next1=%d,next2=%d,next3=%d\n",number,14,b,d,j);*/
			   return(number);
		   }
		   else
			   return(0);
	   }

   case 102:
	   a=match(102);
	   b=c1();
	   c=match(103);
	   d=s1();
	   number++;
	   if(a&&b&&c&&d)
	   {
		   /*cout<<("S->while C do S");*/
		   w[number][0]=15;
		   w[number][1]=b;
		   w[number][2]=d;
		   w[number][3]=0;
		   /*cout<<("    number=%d,	style=%d,	next1=%d,	next2=%d\n",number,15,b,d);*/
		   return(number);
	   }
	   else
		   return(0);
   }
   return(0);
}
int c1()
{
   int e1();
   //int match();
   int a=0,c=0,d=0,i1=0,i2=0,i3=0;

   a=e1();
   if((lookhead==23)||(lookhead==24)||(lookhead==25))
     {
       d=lookhead;
       if(lookhead==23) i1=match(23);
       if(lookhead==24) i2=match(24);
       if(lookhead==25) i3=match(25);
       c=e1();
       if((i1==0)&&(i2==0)&&(i3==0)||(c==0))
	    return(0);
       if(d==23)
	   {
	     number++;
	     /*cout<<("C->E>E");*/
	     w[number][0]=10;
	     w[number][1]=a;
	     w[number][2]=c;
	     w[number][3]=0;
	   }
       if(d==24)
	   {
	     number++;
	     /*cout<<("C->E<E");*/
	     w[number][0]=11;
	     w[number][1]=a;
	     w[number][2]=c;
	     w[number][3]=0;
	   }
       if(d==25)
	   {
	     number++;
	     /*cout<<("C->E=E");*/
	     w[number][0]=13;
	     w[number][1]=a;
	     w[number][2]=c;
	     w[number][3]=0;
	   }
       return(number);
     }
}
int e1 ()
{
  int t1();
  //int match();
  int a,b=0,c,d,g=0,k=1,h=0;

  if(lookhead!=4)
  {
	  a=t1();
	  if(a==0)
		  return (0);
  }
  else
    a=0;
  while((lookhead==3)||(lookhead==4))
  {
	  d=lookhead;
	  if(lookhead==3) g=match(3);
	  if(lookhead==4) b=match(4);
	  c=t1();
	  if(((g==0)&&(b==0))||(c==0))
		  return(0);
	  if(d==3)
	  {
		  number++;
		  /*cout<<("E->E+E");*/
		  w[number][0]=2;
		  if(k==1)
		  {
			  w[number][1]=a;
			  k++;
		  }
		  else
			  w[number][1]=h;
		  w[number][2]=c;
		  w[number][3]=0;
		  h=number;
		  /*cout<<("	number=%d,	style=%d,	next1=%d,	
		           next2=%d\n",number,2,w[number][1],c);*/
	  }
	  if(d==4)
	  {
		  number++;
		  if(a!=0)
		  {
			  /*cout<<("E->E-E");*/
			  w[number][0]=3;
			  if(k==1)
			  {
				  w[number][1]=a;
				  k++;
			  }
			  else
				  w[number][1]=h;
			  w[number][2]=c;
			  w[number][3]=0;
			  h=number;
			  /*cout<<("	number=%d,	style=%d,	next1=%d,	
			            next2=%d\n",number,3,w[number][1],c);*/
		  }
		  else
		  {
			  /*cout<<("E->-E");*/
			  w[number][0]=6;
			  w[number][1]=c;
			  w[number][2]=0;
			  h=number;
			  k++;
			  a=1;
			  /*cout<<("	number=%d,	style=%d,	
			           next1=%d\n",number,6,w[number][1]);*/
		  }
	  }
  }
  return(number);
}
int t1()
{
	int f1();
	//int match();
	int a,b=0,c,d,g=0,k=1,h=0;

	a=f1();
	if(a==0)
		return(0);
	while((lookhead==5)||(lookhead==6))
	{
		d=lookhead;
		if(lookhead==5) g=match(5);
		if(lookhead==6) b=match(6);
		c=f1();
		if(((g==0)&&(b==0))||(c==0))
			return(0);
		if(d==5)
		{
			number++;
			/*cout<<("E->E*E");*/
			w[number][0]=4;
			if(k==1)
			{
				w[number][1]=a;
				k++;
			}
			else
				w[number][1]=h;
			w[number][2]=c;
			w[number][3]=0;
			h=number;
			/*cout<<("	number=%d,	style=%d,	next1=%d,	next2=%d\n",number,4,w[number][1],c);*/
		}
		if(d==6)
		{
			number++;
			/*cout<<("E->E/E");*/
			w[number][0]=5;
			if(k==1)
			{
				w[number][1]=a;
				k++;
			}
			else
				w[number][1]=h;
			w[number][2]=c;
			w[number][3]=0;
			h=number;
			/*cout<<("	number=%d,	style=%d,	next1=%d,
			         next2=%d\n",number,5,w[number][1],c);*/
		}
	}
	return(number);
}
int f1()

{
	int e1();
	//int match();
	int a,b,c,a1;

	switch(lookhead)
	{
	case 1:
		a1=code;
		a=match(1);
		number++;
		if(a)
		{
			/*cout<<("E->id");*/
			w[number][0]=8;
			w[number][1]=a1;
			w[number][2]=0;
			/*cout<<("	number=%d,	style=%d,	id=%s\n",number,8,chart[a1]);*/
			return(number);
		}
		else
			return(0);
	case 21:
		a=match(21);
		b=e1();
		c=match(22);
		number++;
		if(a&&b&&c)
		{
			/*cout<<("E->(E)");*/
			w[number][0]=7;
			w[number][1]=b;
			w[number][2]=0;
			/*cout<<("	number=%d,	style=%d,	next1=%d\n",number,7,b);*/
			return(number);
		}
		else
			return(0);
	case 10:
		a1=code;
		a=match(10);
		number++;
		if(a)
		{
			/*cout<<("E->num");*/
			w[number][0]=9;
			w[number][1]=a1;
			w[number][2]=0;
			/*cout<<("	number=%d,	style=%d,	num=%s\n",number,9,chart[a1]);*/
			return(number);
		}
		else
			return(0);
	}
	return(0);
}
/*====================语义分析=====================*/
/*语义分析递归子程序之一
参数:第一个参数为该产生式的编号
      第二个参数为该产生式父产生式的编号
返值:临时变量的符号表入口序号*/
int s2(int m,int m1)
{
	int e2(int,int);
	int a;
	int newlabel();

	switch(w[m][0])
	{
	case 1:
		a=e2(w[m][1],0);
		cout<<chart[w[m][2]]<<":="<<chart[a]<<"\n";
		return(1);
	case 12:
		label[m][2]=newlabel();
		label[m][3]=label[m][1];
		label[w[m][2]][1]=label[m][1];
		e2(w[m][1],m);
		cout<<chart[label[m][2]]<<":\n";//
		s2(w[m][2],m);
		return(1);
	case 14:
		label[m][2]=newlabel();
		label[m][3]=newlabel();
		label[w[m][2]][1]=label[m][1];
		label[w[m][3]][1]=label[m][1];
		e2(w[m][1],m);
		cout<<chart[label[m][2]]<<":\n";//
		s2(w[m][2],m);
		cout<<"    goto "<<chart[label[m][1]]<<":\n";
		cout<<chart[label[m][3]]<<":\n";//
		s2(w[m][3],m);
		return(1);
	case 15:
		switch(w[m1][0])
		{
		case 12: 
			label[m][0]=label[m1][2];
			break;
		case 15: 
			label[m][0]=label[m1][2];
			break;
		case 14:
			if (m==w[m1][2])
				label[m][0]=label[m1][2];
			else
				label[m][0]=label[m1][3];
			break;
		default: 
			label[m][0]=newlabel();
			cout<<chart[label[m][0]]<<":\n";
		}
		label[m][2]=newlabel();
		label[m][3]=label[m][1];
		label[w[m][2]][1]=label[m][0];
		e2(w[m][1],m);
		cout<<chart[label[m][2]]<<":\n";//
		s2(w[m][2],m);
		cout<<"    goto  "<<chart[label[m][0]]<<":\n";
		return(1);
	}
}
int  e2(int m,int m1)
{
	int a,b,t;
	int newtemp();

	switch(w[m][0])
	{
	case 2:
		t=newtemp();
		a=e2(w[m][1],m);
		b=e2(w[m][2],m);
		cout<<chart[t]<<":="<<chart[a]<<"+"<<chart[b]<<endl;
		return(t);
	case 3:
		t=newtemp();
		a=e2(w[m][1],m);
		b=e2(w[m][2],m);
		cout<<chart[t]<<":="<<chart[a]<<"-"<<chart[b]<<endl;
		return(t);
	case 4:
		t=newtemp();
		a=e2(w[m][1],m);
		b=e2(w[m][2],m);
		cout<<chart[t]<<":="<<chart[a]<<"*"<<chart[b]<<endl;
		return(t);
	case 5:
		t=newtemp();
		a=e2(w[m][1],m);
		b=e2(w[m][2],m);
		cout<<chart[t]<<":="<<chart[a]<<"/"<<chart[b]<<endl;
		return(t);
	case 6:
		t=newtemp();
		a=e2(w[m][1],m);
		cout<<chart[t]<<":=0-"<<chart[a]<<endl;
		return(t);
	case 7:
		a=e2(w[m][1],m);
		return(a);
	case 8:
		return(w[m][1]);
	case 9:
		return(w[m][1]);
	case 10:
		a=e2(w[m][1],m);
		b=e2(w[m][2],m);
		cout<<"if "<<chart[a]<<">"<<chart[b]<<" goto "<<chart[label[m1][2]]<<endl;
		cout<<"    goto "<<chart[label[m1][3]]<<endl;
		return(-1);
	case 11:
		a=e2(w[m][1],m);
		b=e2(w[m][2],m);
		cout<<"if "<<chart[a]<<"<"<<chart[b]<<" goto "<<chart[label[m1][2]]<<endl;
		cout<<"    goto "<<chart[label[m1][3]]<<endl;
		return(-1);
	case 13:
		a=e2(w[m][1],m);
		b=e2(w[m][2],m);
		cout<<"if "<<chart[a]<<"="<<chart[b]<<" goto "<<chart[label[m1][2]]<<endl;
		cout<<"    goto "<<chart[label[m1][3]]<<endl;
		return(-1);
	}
}
//产生新的临时变量名
//返值:临时变量的符号表入口序号
int newtemp()
{
	temp++;
	chart[temp][0]='t';
	chart[temp][1]=temp1;
	chart[temp][2]=0;
	temp1++;
	return(temp);
}
//产生新的标号
//返值:标号的符号表入口序号
int newlabel()
{
	stemp++;
	chart[stemp][0]='L';
	chart[stemp][1]=stemp1;
	chart[stemp][2]=0;
	stemp1++;
	return(stemp);
}
/*========================主函数========================*/
void main()
{
	int cifa();
	int j;
//	int s1();
//	int match();
//	int s2(int,int);
//	int newlabel();

	lookhead=cifa();
	j=s1();
	if(j!=0)
		cout<<"\n 语法正确!";
	else
		cout<<"\n 语法有错误?";
	cout<<"\n\n 3 address:\n";
	label[j][1]=newlabel();
	s2(j,0);
	cout<<chart[label[j][1]]<<":";
	cout<<"\nend\n";
}


⌨️ 快捷键说明

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