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

📄 结合.cpp

📁 从源代码到中间语言生成的针对一系列语言的实现过程
💻 CPP
字号:
#include <iostream.h>
#include <fstream.h>
#include <string.h>
#include <math.h>
#include <ctype.h>
#include <stdio.h>
int E_stack[10],T_stack[10],top_E_stack=-1,top_T_stack=-1;
char str[500];
char word[20];
char filename[50]; 
int num_stack[20]; int  num_top=0;//状态压进数字栈
char *id_stack[20];int  id_top=-1;//符号压入符号栈
char *X[37]={"(",")",";","id",":","int","=","else","if","then","{","}","while","do","+","*","and","<","num","$",
	             "P","D","A","S","L","Q","G","C","B","N","U","E","T","F","I","M","W"};
struct sym_table{
	char name[20];
	int bianma;
	char type[4];
	int addr;
}symtable[100];//符号表结构
int m=0;//符号表入口
int enterstack[50];//语义中用于顺序记住数字或标识符符号表入口的栈
int top_enterstack=-1;
struct mid_code{
	int one;
	int two;
	int three;
	int four;
}fourgroup[100];//伪四元式
int newtemp=99;
int nextquad=0;
int offset=0;
int A_width,S_nextlist,L_nextlist,U_nextlist,G_nextlist,C_nextlist,W_head,U_head,N_quad,M_quad,
    B_truelist,B_falselist,F_place,I_place,id_place,M_truelist,M_falselist;
void enter(int entry_addr,int offset)
{	strcpy(symtable[entry_addr].type,"int");
	symtable[entry_addr].addr=offset;
}
void emit(int a,int b,int c,int d)
{	++nextquad;
	fourgroup[nextquad].one=a;
	fourgroup[nextquad].two=b;
	fourgroup[nextquad].three=c;
	fourgroup[nextquad].four=d;
}
int merge(int p1,int p2)
{	int p;
	if(p2==0) return p1;
	else
	{	p=p2;
		while(fourgroup[p].four!=0)
			p=fourgroup[p].four;
		fourgroup[p].four=p1;
		return p2;
	}
}
void backpatch(int p,int t)
{	int q,Q;
	Q=p;
	while(Q!=0)
	{	q=fourgroup[Q].four;
		fourgroup[Q].four=t;
		Q=q;
	}	
}
void load()//用来把文件中的内容放到缓冲区中
{	int i=0;
	char c; 
	ifstream infile(filename);
	while (infile.get(c))
		str[i++]=c;
	str[i]='\0';
}
void cifa()//词法
{   int i,j,s,k,line=1;
    i=0;s=0;
	int sign=0;
	FILE *fp;
	ofstream OutFile1("token.txt");
	cout<<"输入要打开的文件(路径、名称):";//提示用户键入路径名
F:	cin.getline(filename,50);	
	fp=fopen(filename,"r");
	while (fp==NULL)//若文件不存在,则要求继续输入文件的路径与名称
	{   cout<<"文件不存在,请重新输入!"<<endl;
		goto F;
	}
	load();//把文件中的内容放入缓冲区
	fclose(fp);
A:  i=s;
    if(i<500 && str[i]!='\0')
	{  if(isalpha(str[i]))//---------------------字母
	   {  k=0;
		  word[k++]=str[i];
          while(isalpha(str[i+1]) || isdigit(str[i+1])) 
		  {  word[k++]=str[++i];
			 s=i+1;
		  }
		  if(k==1) s=i+1;
		  word[k]='\0';
		  if(strcmp(word,"id")!=0 && strcmp(word,"num")!=0)
			  for(j=0;j<19;j++)//用来判断取出的当前单词是不是关键词
				  if(strcmp(word,X[j])==0) 
				  {	  OutFile1<<j<<" "<<-1<<endl; goto A; }
		  for (j=0;j<19;j++) if(strcmp(X[j],"id")==0) break;
		  for(i=0;i<100 && strcmp(symtable[i].name,"")==1;i++)
			  if(strcmp(word,symtable[i].name)==0)
			  {  OutFile1<<j<<" "<<i<<endl;goto A;  }
		  OutFile1<<j<<" "<<i<<endl;
          strcpy(symtable[i].name,word);
		  symtable[i].bianma=j;
		  goto A;
	   }
	   if(isdigit(str[i]))//---------------------数字
	   {  int k=0;
		  word[k++]=str[i];
          while(isdigit(str[i+1])) {word[k++]=str[++i];s=i+1;}
		  if(k==1) s=i+1;
		  word[k]='\0';
          for (j=0;j<19;j++) if(strcmp(X[j],"num")==0) break;
		   for(i=0;i<100 &&strcmp(symtable[i].name,"")==1;i++)
			  if(strcmp(word,symtable[i].name)==0)
			  {  OutFile1<<j<<" "<<i<<endl;goto A;  }
		  OutFile1<<j<<" "<<i<<endl;
          strcpy(symtable[i].name,word);
		  symtable[i].bianma=j;
		  goto A;
	   }
	   if(str[i]!=' ' && str[i]!='\n')
	   {   s=i+1;
		   word[0]=str[i];word[1]='\0';
		   for(j=0;j<19;j++) 
			   if(strcmp(X[j],word)==0)
			   {   OutFile1<<j<<" "<<-1<<endl;
				   goto A;
			   }
			cout<<filename<<"("<<line<<"):Error:'"<<str[i]<<"':illegal character!"<<endl;
			goto A;
	   }
       else
	   {   while(str[i]==' ' || str[i]=='\n')
			{ if(str[i]=='\n') line++;i++;s=i;} //------除去空格和回车
	       goto A;	   
	   }
	}
	OutFile1<<19<<" "<<19<<endl;
}
void main()
{	int i=0,j=0,num1,num2,n=3,k=0,sk,slr[61][37];
	char comma;
	char *p[30]={"P'->P","P->D","D->id()D;S","D->D;D","D->id:A","A->int",
	             "S->id=QE","Q->ε","S->GS","S->CS","G->CSelse","C->if(B)then",
				 "S->{L}","L->L;NS","L->S","N->ε","S->US","U->W(B)do",
				 "E->E+T","E->T","T->T*F","T->F","F->(E)","F->I","B->BandMB",
				 "B->id<I","I->id","I->num","M->ε" ,"W->while"};
	char *A_type;
	char *math_operator[5]={"+","*","=","J","J<"};
	cifa();
	ifstream slrtable("slrtable.html");
	while(!slrtable.eof())
	{	slrtable>>slr[i][(j++)%37]>>comma;
	    if(j%37==0) i++;
	}	    
	num_stack[0]=0;
	ifstream infile1("token.txt");
	while(!infile1.eof())
		  {	  infile1>>num1>>num2;
A:            if(slr[num_stack[num_top]][num1]>0) 
			  {   if(num1==3 || num1==18)   
			          enterstack[++top_enterstack]=num2;
			      if(slr[num_stack[num_top]][num1]==100) { cout<<"----------------"<<endl; break; }
				  id_stack[++id_top]=X[num1];
				  num_stack[num_top+1]=slr[num_stack[num_top]][num1];
				  num_top++;
			  }
			  else if(slr[num_stack[num_top]][num1]<0)
			  {   sk=abs(slr[num_stack[num_top]][num1]);
			      switch(sk){
				  case 1:  break; //P->D
				  case 2:  break; //D->id()D;S
				  case 3:  break; //D->D;D
			      case 4:  enter(enterstack[top_enterstack--],offset); offset=offset+A_width; break; //D->id:A
				  case 5:  A_type="int"; A_width=4; break; //A->int
				  case 6:  emit(2,E_stack[top_E_stack--],0,enterstack[top_enterstack--]); S_nextlist=0; break; //S->id=QE
				  case 7:  break; //Q->ε
				  case 8:  S_nextlist=merge(G_nextlist,S_nextlist); break; //S->GS
				  case 9:  S_nextlist=merge(C_nextlist,S_nextlist); break; //S->CS
				  case 10: emit(3,0,0,0); G_nextlist=merge(S_nextlist,nextquad);
					       backpatch(C_nextlist,nextquad+1); break; //G->CSelse
			      case 11: backpatch(B_truelist,nextquad+1); C_nextlist=B_falselist; break; //C->if(B)then
				  case 12: S_nextlist=L_nextlist; break; //S->{L}
				  case 13: backpatch(L_nextlist,N_quad); L_nextlist=S_nextlist; break; //L->L;NS
				  case 14: L_nextlist=S_nextlist; break; //L->S
				  case 15: N_quad=nextquad+1; break; //N->ε
				  case 16: backpatch(S_nextlist,U_head); emit(3,0,0,U_head); S_nextlist=U_nextlist; break; //S->US
				  case 17: backpatch(B_truelist,nextquad+1); U_nextlist=B_falselist; U_head=W_head; break; //U->W(B)do
				  case 18: i=E_stack[top_E_stack--]; E_stack[++top_E_stack]=++newtemp; emit(0,i,T_stack[top_T_stack--],E_stack[top_E_stack]); break; //E->E+T
				  case 19: E_stack[++top_E_stack]=T_stack[top_T_stack--]; break; //E->T
				  case 20: i=T_stack[top_T_stack--]; T_stack[++top_T_stack]=++newtemp; emit(1,i,F_place,T_stack[top_T_stack]); break; //T->T*F
				  case 21: T_stack[++top_T_stack]=F_place; break; //T->F
				  case 22: F_place=E_stack[top_E_stack--]; break; //F->(E)
				  case 23: F_place=I_place; break; //F->I
				  case 24: backpatch(M_truelist,M_quad); B_truelist=B_truelist;
					       B_falselist=merge(M_falselist,B_falselist); break; //B->BandMB
				  case 25: B_truelist=nextquad+1; emit(4,enterstack[top_enterstack--],I_place, 0);
					       B_falselist=nextquad+1; emit(3,0,0,0); break; //B->id>I
				  case 26: I_place=enterstack[top_enterstack--]; break; //I->id
				  case 27: I_place=enterstack[top_enterstack--]; break; //I->num
				  case 28: M_quad=nextquad+1; M_truelist=B_truelist; M_falselist=B_falselist; break; //M->ε
				  case 29: W_head=nextquad+1; break; //W->while
				  }
				  cout<<p[sk]<<endl;
				  if(p[sk][0]=='Q' || p[sk][0]=='N' || p[sk][0]=='M') goto B;
				  while(p[sk][n]!='\0')
				  {	  k++;
					  if((p[sk][n]>='a' && p[sk][n]<='z') && 
						  (p[sk][n-1]>='a' && p[sk][n-1]<='z'))
						  k--;
					  n++;
				  }				  
				  id_top-=k;
				  num_top-=k;
B:				  for(i=20;i<37;i++)
					  if(X[i][0]==p[sk][0]) break;
				  id_stack[++id_top]=X[i];
                  num_stack[num_top+1]=slr[num_stack[num_top++]][i];
				  n=3;
				  k=0;
				  goto A;				  
			  }
			  else cout<<"_________________________ERROR!"<<endl;
		  }
		  for(i=1;i<=nextquad;i++)
		  {   cout<<i<<": "<<"("<<math_operator[fourgroup[i].one]<<",";		      
			  if(fourgroup[i].two==0) cout<<"  "<<",";
			  else if(fourgroup[i].two>=100) cout<<"t"<<fourgroup[i].two-100<<",";
			  else cout<<symtable[fourgroup[i].two].name<<",";             
			  if(fourgroup[i].three==0) cout<<"  "<<",";
			  else if(fourgroup[i].three>=100) cout<<"t"<<fourgroup[i].three-100<<",";
			  else cout<<symtable[fourgroup[i].three].name<<",";              
			  if(fourgroup[i].four>=100) cout<<"t"<<fourgroup[i].four-100<<")"<<endl;
              else if(fourgroup[i].four==0) cout<<"  "<<")"<<endl;
			  else if(fourgroup[i].one==3 || fourgroup[i].one==4) cout<<fourgroup[i].four<<")"<<endl;
			  else cout<<symtable[fourgroup[i].four].name<<")"<<endl;
		  }
		  ofstream OutFile2("symboltable.txt");
		  OutFile2<<"序号    "<<"符号    "<<"编码    "<<"类型    "<<"偏移地址    "<<endl;
		  OutFile2<<"----------------------------------------"<<endl;
		  for(i=0;i<100 && symtable[i].bianma!=0;i++) 
		  {	  OutFile2<<i+1<<"	"<<symtable[i].name<<"	"<<symtable[i].bianma<<"	"<<symtable[i].type<<"	";
		      if(strcmp(symtable[i].type,"int")!=0)  OutFile2<<endl;
			  else OutFile2<<symtable[i].addr<<endl;
		  }
}

⌨️ 快捷键说明

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