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

📄 parser.h

📁 完成一个完整的编译程序
💻 H
字号:
//---------------语法法分析parser.h-------------------------
#ifndef parser_comp
#define parser_comp
#include <iostream>
#include <fstream>
#include <string>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include "scanner.h"
using namespace std;
//------------------------ 语法分析程序-----------------------------
int kind;
int ent;
//四元式代码结构
struct code1
{
  int op;
  int ag1;
  int ag2;
  int result;
};
struct code1 code[TXMAX*10];
int codetab=0;
int gencode(int x,int y,int z,int r)
{
	if(codetab<TXMAX*10-1)
	{
     code[codetab].op=x;
     code[codetab].ag1=y;
     code[codetab].ag2=z;
     code[codetab].result=r;
     codetab++;
	}
 return 0;
}

//----------算符优先文法-----------
struct opg
{
  int opgnum[TXMAX];
  int opgtab;
};
struct opg num_stack;//操作数栈

struct opg op_stack;//操作符栈

int popnum(struct opg& a,int& b)
{
 if(a.opgtab>0)
 {
  a.opgtab-=1;
  b=a.opgnum[a.opgtab];
  return 0;
  }
 return -1;
}
int pushnum(struct opg& a,int b)
{

 a.opgnum[a.opgtab]=b;
 a.opgtab+=1;
 return 0;
}
//算符优先矩阵
int opg_array[6][6]={
	{2,2,1,1,1,2},
	{2,2,1,1,1,2},
	{2,2,2,2,1,2},
	{2,2,2,2,1,2},
	{1,1,1,1,1,0},
	{2,2,2,2,-1,2},
};
int tab2=300;//临时变量存贮始址
//读入数值
int Getnum(ifstream& src)
{
  int cRet;
  src>>cRet;
  return cRet;
}
//读入二元式
int getoken(ifstream& src)
{
  kind=Getnum(src);
  GetChar(src);
  ent=Getnum(src);
  return 0;
}
//-------判断运算符-------
int gequen(int i)
{
	int j;
  switch (i)
  {
  case 39:
	  j=4;
	  break;
  case 40:
	  j=5;
	  break;
   case 41:
	  j=2;
	  break;
	case 43:
	  j=0;
	  break;
	case 45:
	  j=1;
	  break;
	case 48:
	  j=3;
	  break;
	case 53:
	  j=9;
	  break;
	case 54:
	  j=13;
	  break;
	case 55:
	  j=8;
	  break;
	case 56:
	  j=14;
	  break;
	case 57:
	  j=7;
	  break;
	case 58:
	  j=12;
	  break;
	default:
         break;
  }
 return j;
}
//查找变量说明地址
int position(int x)
{
	
  if(x<300)
  {
   for(int i=0;i<x;i++)
   {
    if(strcmp(table[i].name,table[x].name)==0)

	  return i;
   }
  }
  else
	 return x;
}
//if-while出口堆栈
struct opg ifchain_stack;//if跳转链栈
struct opg iffalse_stack;//if假出口栈
struct opg while_stack;//while真出口
struct opg whfalse_stack;//while假出口
bool else_if=false;//表明最近处理过else
//-----过程有关结构--------
struct procedure1
{
  int name;
  int goin;
  int goinum;
  int code_begin;
};
struct procedure1 proce[10];
int procenum=0;
int procecode=300;
struct opg goin_stack;
struct opg in_stack;
int find_proce(int x)
{
 for(int i=0;i<procenum;i++)
   {
    if(proce[i].name==x)
        return i;
   }
}
//-----程序体处理----
void syntax(ifstream& src)
{
//程序头处理
	getoken(src);
  if(kind==22)
  {
	getoken(src);
    if(kind==34)
	{
		getoken(src);
	    if(kind==52)
          gencode( 5,-1,-1,-1);
	}
  }
//说明语句处理
   if(kind==31)
   {
     while (kind!=52)
	 {
		 getoken(src);
	    while(kind!=50)
		{
          getoken(src);
		if(kind==34)
			getoken(src);
		 while(kind==44)
		 {
			getoken(src);
		    if(kind==34)
		 	 getoken(src);
		 }
		}
		if(kind==50)
		{
	     	getoken(src);
			if(kind==4||kind==7||kind==16||kind==24)
                 getoken(src);
		}
	 }
   }
      // 算术运算处理
   if(kind==34)
   {
	   int i=ent;
	   getoken(src);
	if(kind==51)
	{
      int op1=-1;
      int op2=-1;
      int num1=0;
      int num2=0;
      op_stack.opgtab=0;
      getoken(src);
     while(kind!=52&&kind!=44)
	 {
      if(kind==35||kind==34)
	  {
       pushnum(num_stack,position(ent));
	   getoken(src);
	  }
      else if(kind==39||kind==40||kind==41||kind==43||kind==45||kind==48)
	  {
	    op2=gequen(kind);
	   while(op_stack.opgtab>0 && op1>=0 && op2>=0 && opg_array[op1][op2]==2)
	   {
		popnum(num_stack,num2);
        popnum(num_stack,num1);
	    gencode( op1,num1,num2,tab2);
	    pushnum(num_stack,tab2);
        popnum(op_stack,op1);
		tab2++;
	    if(op_stack.opgtab>0)
		{
	     popnum(op_stack,op1);
		 op1=gequen(op1);
		}
	   }
       if(op_stack.opgtab>0 && op1>=0 && op2>=0 && opg_array[op1][op2]==0)
	   {
	    popnum(op_stack,op1);
		popnum(op_stack,op1);
		op1=gequen(op1);
		op2=-1;
	    getoken(src);
	   }
	   else if(op_stack.opgtab==0 && op1>=0 && op2>=0 && opg_array[op1][op2]==2)
	   {
		   popnum(num_stack,num2);
           popnum(num_stack,num1);
           gencode( op1,num1,num2,tab2);
		   pushnum(num_stack,tab2);
		   tab2++;
           pushnum(op_stack,kind);
		   getoken(src);
	   }
	   else
	   {
	    op1=gequen(kind);
		op2=-1;
	    pushnum(op_stack,kind);
	    getoken(src);
	   }
	  }
	 }
     if(kind==44)
	 {
	  while(op_stack.opgtab>0)
	  {
		popnum(op_stack,op1);
		op1=gequen(op1);
		popnum(num_stack,num2);
        popnum(num_stack,num1);
	    gencode( op1,num1,num2,tab2);
	    pushnum(num_stack,tab2);
		tab2++;
	  }
	  if(num_stack.opgtab==1)
	  {
	    popnum(num_stack,num1);
		gencode( 4,num1,-1,position(i));
	  }
	 }
	 if(kind==52)
	 {
	  while(op_stack.opgtab>0)
	  {
		popnum(op_stack,op1);
		op1=gequen(op1);
		popnum(num_stack,num2);
        popnum(num_stack,num1);
	    gencode( op1,num1,num2,tab2);
	    pushnum(num_stack,tab2);
		tab2++;
	  }
	  if(num_stack.opgtab==1)
	  {
	    popnum(num_stack,num1);
		gencode( 4,num1,-1,position(i));
	  }
	    //-------对于if语句的有关处理
	   while(iffalse_stack.opgtab==0 && ifchain_stack.opgtab>0 && else_if==true)
		  {
		  int back_chain;
		  popnum(ifchain_stack,back_chain);
		  code[back_chain].result=codetab;
		  else_if=false;
		  }
		
	  if(iffalse_stack.opgtab>0)
	  {
          gencode( 6,-1,-1,-1);
		  pushnum(ifchain_stack,codetab-1);
          getoken(src);
		  if(kind==10)
		  {
		   else_if=true;
		   int back;
		   popnum(iffalse_stack,back);
		   code[back].result=codetab;
           }
		
	  }
	   //-------------对于while语句的处理
	  while(whfalse_stack.opgtab>0)
	  {
		  int head;
		 popnum(while_stack,head);
	     gencode( 6,-1,-1,head);
         popnum(whfalse_stack,head);
		 code[head].result=codetab;
	  }
	 }
	}
   }
//If-then部分处理
  if(kind==14)
  {
	  int num1 ,num2,op;
     getoken(src);
	 if(kind==34||kind==35)
	 {
		 num1=position(ent);
         getoken(src);
		 if(kind>=53&&kind<=58)
		 {
			 op=gequen(kind);
		     getoken(src);
			 if(kind==34||kind==35)
			 {
		         num2=position(ent);
                 getoken(src);
			 }
		 }
	 }
	 if(kind==27)
	 {
	    gencode( op,num1,num2,codetab+2);
        gencode( 6,-1,-1,-1);
		pushnum(iffalse_stack,codetab-1);
	 }
  }

//while-do处理部分
  if(kind==32)
  {
	  int num1 ,num2,op;
     getoken(src);
	 if(kind==34||kind==35)
	 {
		 num1=position(ent);
         getoken(src);
		 if(kind>=53&&kind<=58)
		 {
			 op=gequen(kind);
		     getoken(src);
			 if(kind==34||kind==35)
			 {
		         num2=position(ent);
                 getoken(src);
			 }
		 }
	 }
	 if(kind==9)
	 {
	    gencode( op,num1,num2,codetab+2);
        pushnum(while_stack,codetab-1);
        gencode( 6,-1,-1,-1);
		pushnum(whfalse_stack,codetab-1);
	 }
  }

  //过程procedure处理
   if(kind==21)
   {
      codetab=procecode;
      getoken(src);
	  if(kind==34)
	  {
		proce[procenum].name=ent;
        getoken(src);
	    if(kind==39)
		   getoken(src);
	    while(kind!=40)
		{
		  getoken(src);
	      if(kind==34)
		  {
             proce[procenum].goin=ent;
             proce[procenum].goinum++;
		  }
		}
		if(kind==40)
		{
			proce[procenum].code_begin=codetab;
            procenum++;
		    getoken(src);
		}
	  }
   }
 //end.处理与end;处理
  if(kind==11)
  {
	getoken(src);
   if(kind==46)
     gencode( 11,-1,-1,-1);
    else if(kind==52)
	{
		for(int i=0;i<=proce[procenum-1].goinum;i++)
		{
         gencode( 4,proce[procenum-1].goin-proce[procenum-1].goinum+i,-1,-1);
		 pushnum(goin_stack,codetab-1);
		}
        gencode( 6,-1,-1,-1);
		pushnum(goin_stack,codetab-1);
		procecode=codetab;
		codetab=0;	
	}
  }

    //call 处理
   if(kind==5)
   {
	 int callin;
	 int in;
	 int back;
	 popnum(goin_stack,back);
     getoken(src);
	 if(kind==34)
	 {
        callin=position(ent);
        callin=find_proce(callin);
		getoken(src);
		in=proce[callin].goin-proce[callin].goinum;
	 }
     if(kind==39)
	 {
		   getoken(src);
	    while(kind!=40)
		{
	      if(kind==34)
		  {
			  gencode( 4,position(ent),-1,in);
			  in++;
			  pushnum(in_stack,position(ent));
			  getoken(src);
		  }
		  else
           getoken(src);
		}
		if(kind==40)
		{
			for(int i=0;i<=proce[callin].goinum;i++)
			{
			 int p,k;
			 popnum(goin_stack,p);
			 popnum(in_stack,k);
			 code[p].result=k;
			}
          getoken(src);
		  if(kind==52)
		  {
		   gencode(6,-1,-1,proce[callin].code_begin);
           code[back].result=codetab;
		  }
		}
	 }
   }
  //write 语句处理
  if(kind==33)
  {

   while(kind!=52&&kind!=44)
   {
     getoken(src);
    if(kind==34)
	 gencode( 10,position(ent),-1,-1);

   }

   if(kind==52)
   {
	   //--对于if语句的有关处理--
	  while (iffalse_stack.opgtab==0 && ifchain_stack.opgtab>0 && else_if==true )
		
		   {
		   int back_chain=0;
		   popnum(ifchain_stack,back_chain);
		   code[back_chain].result=codetab;
		   else_if=false;
		  }
    if(iffalse_stack.opgtab>0)
	  {
          gencode( 6,-1,-1,-1);
		  pushnum(ifchain_stack,codetab-1);
          getoken(src);
		  if(kind==10)
		  {
		   else_if=true;
		   int back=0;
		   popnum(iffalse_stack,back);
		   code[back].result=codetab;
           }
	  }
           //对于while语句的处理
	  while(whfalse_stack.opgtab>0)
	  {
		  int head=0;
		 popnum(while_stack,head);
	     gencode( 6,-1,-1,head);
         popnum(whfalse_stack,head);
		 code[head].result=codetab;
	  }
   }
  }
}
//输出四元式
int putcode(ofstream& codst)
{
    int i;
 for( i=0;i<codetab;i++)
 {
	 codst<<i<<"("<<code[i].op<<" "<<arrow;
     codst<<code[i].ag1<<" "<<arrow;
     codst<<code[i].ag2<<" "<<arrow;
     codst<<code[i].result<<")"<< enter;

 }
  for( i=300;i<procecode;i++)
 {
	 codst<<i<<"("<<code[i].op<<" "<<arrow;
     codst<<code[i].ag1<<" "<<arrow;
     codst<<code[i].ag2<<" "<<arrow;
     codst<<code[i].result<<")"<< enter;

 }

 return 0;
}
//-------------语法分析主程序-------------
int parser()
{
 // 打开文件
  ifstream src("token.txt");
  if (src.fail())
  {
    cerr << "\aFailed openning \"" << endl;
    return 1;
  }
  ofstream codst("four_code.txt");
  // 开始解析并产生四元式
  while (!src.eof())
         syntax(src);
	 putcode(codst);
  // 收尾工作
  codst.close();
  src.close();
  cout << "The result of Syntax Analyzing is written into four_code.txt." << endl;
  return 0;

}
#endif

⌨️ 快捷键说明

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