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

📄 unit1.~cpp

📁 PLO模板程序设计
💻 ~CPP
📖 第 1 页 / 共 4 页
字号:
                   TABLE[TX].VAL=PARACOUNT;        //存入定义参数的个数
                }
		break;
//-------------------------------------------------end  fun enter

	    default:
	       TABLE[TX].vp.LEVEL=LEV; TABLE[TX].vp.ADR=DX; DX++;
	       break;

  }

 /*DS*/ DISPLAY[LEV+1].tp=DX;

} /*ENTER*/
//---------------------------------------------------------------------------
int POSITION(ALFA ID, int TX) { /*FIND IDENTIFIER IN TABLE*/
  int i=TX;
  strcpy(TABLE[0].NAME,ID);
  while (strcmp(TABLE[i].NAME,ID)!=0) i--;
  return i;
} /*POSITION*/


//---------------------------------------------------------------------------
void ConstDeclaration(int LEV,int &TX,int &DX) {
  ALFA NUMCONST0,NUMCONST1,NUMCONST2;
     strcpy(NUMCONST0,"INTEGER");    //下面参数说名的常数按类型入表
     strcpy(NUMCONST1,"REAL");
     strcpy(NUMCONST2,"CHAR");
  if (SYM==IDENT)
  {

      GetSym();
      if (SYM==EQL||SYM==BECOMES)
	  {
	     if (SYM==BECOMES) Error(1);
	     GetSym();
             switch(SYM)
             {
               case INTEGERSYM: ENTER(CONSTANT,NUMCONST0,LEV,TX,DX,ID,FALSE); GetSym(); break;
               case REALSYM : ENTER(CONSTANT,NUMCONST1,LEV,TX,DX,ID,FALSE); GetSym(); break;
               case CHARSYM : ENTER(CONSTANT,NUMCONST2,LEV,TX,DX,ID,FALSE); GetSym(); break;
                default : Error(2); break;
             }
    }
    else Error(3);
  }
  else Error(4);
} /*ConstDeclaration()*/
//---------------------------------------------------------------------------

//+++++++++++++++++++++++++++start para declaration
void ParaDeclaration(int LEV,int &TX,int &DX,int count,ALFA VARS[],bool IsVAR)
                                         //函数参数变量声明过程
                                         //int count   同一类型变量的个数
                                         //ALFA VARS[] 存有同一类型变量临时数组
{

        DISPLAY[LEV].bp=DISPLAY[LEV].tp;

	if(SYM==ARRAYSYM)                //数组的参数的处理
	{
		GetSym();
		if(SYM==OFSYM)
		{
			UPARR=0;
			DOWNARR=0;
                        GetSym();
		        if(SYM==INTEGERSYM || SYM==REALSYM || SYM==CHARSYM)
			{
                                for(int i=0; i<count; i++)
         			    ENTER(ARR,ID,LEV,TX,DX,VARS[i],IsVAR);    //定义数组
			}
			else Error(4);
		}else Error(92);  //不正确的数组定义
	}else
		if((SYM==INTEGERSYM && strcmp(ID,"INTEGER")==0)|| (SYM==REALSYM && strcmp(ID,"REAL")==0) 
			|| (SYM==CHARSYM && strcmp(ID,"CHAR")==0))
		{
			for(int i=0;i<count;i++)
			{
                            ENTER(VARIABLE,ID,LEV,TX,DX,VARS[i],IsVAR);    //定义变量
			}

		}
		else Error(4);
                GetSym();
}

//+++++++++++++++++++++++++++++++++++++++++++++++++++end par declaration

//----------------++++++++++++++--------ParaGetSub-------
void ParaGetSub(SYMSET FSYS,int LEV,int &TX,int Pos)
{
	int count=0;                         //调用函数之前的参数处理过程,pos为该函数在符号表的位置
        int i;
        GetSym();
        if(SYM==LPAREN)                      //函数参数的语法形式 标识符(参数1,参数2,参数3。。);
	{
		GetSym();
                count=TABLE[Pos+1].VAL;       //count 是由该函数原先存在数组表的个数
		Pos-=count;
                while(count)                  //这里是对原先存入的符号表的所有参数进行匹配处理,少了是不可以的
                {
                     if(TABLE[Pos].KIND==FUNCTION) Error(73);     //这里是在调用时的参数还未匹配完,就已经到尽头了,
                                                                  //所以出错,多了是不可以的
                     else
                     {
                         if(TABLE[Pos].IsVAR==VAR)                //匹配的如果是变量参数,即运算时是对实在参数的运算
                         {
                            i=POSITION(ID,TX);
                            if(i==0) Error(11);
                            else
                            {
                               if(strcmp(TABLE[Pos].NUMKIND,TABLE[i].NUMKIND)==0) //类型匹配
                               {
                                 GEN(LIT,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR);  
                                 GEN(STO,LEV-TABLE[Pos].vp.LEVEL,TABLE[Pos].vp.ADR);  
//开始传递地址,但实际上是无法实现的
//因为早在主函数生成调用被调用函数代码的时候,
                                                        //被调用函数在对参变量写入生成代码了,
                                                        //地址的改变也无法改变运算结果了
                               }
                               else Error(32);
                               count--;
                               GetSym();
                                     if(count)
                                     {
                                       if(SYM==COMMA)                       //参数之间用逗号格开
                                          GetSym();
                                        else Error(48);
                                     }
                            }
                         }
                         else                                //不是变量参数,就为值参数,实际上可行
                                                            //因为在被调用函数定义变量时,已经将参数变量地址正确的分配了
                         {
                                 i=POSITION(ID,TX);
                                 if(i==0) Error(11);
                                 else
                                 if(strcmp(TABLE[Pos].NUMKIND,TABLE[i].NUMKIND)!=0) Error(11); //类型不匹配
                                 else
                                 {
                                   if(TABLE[Pos].KIND==ARR)        //如果类型配为数组 ,需要在此函数的数据活动开始区域,
                                                                    //新开空间存放数组变量
                                   {
                                     int UP,DOWN;
                                     TABLE[Pos].vp.ADR=DISPLAY[LEV].bp;   //新开空间的首地址,为display中存的地址
                                     DOWN=TABLE[Pos-1].VAL=TABLE[i].VAL; 
//新开的数组空间调试时有致命错误导致整个程序被关,
                                                                    //头痛ing。。。
                                     UP=TABLE[Pos-2].VAL=TABLE[i].VAL;
                                     int LASTDX=DOWN-UP+1;
                                     for(int j=1;j<=LASTDX;j++)
                                     {
                                       GEN(LOD,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR+j);       
//一个一个的将原数组值对应复制到
                                                                             //新开的数据区中,以便以后调用
                                       GEN(STO,LEV-TABLE[Pos].vp.LEVEL,TABLE[Pos].vp.ADR+j);
                                       DISPLAY[LEV].tp++;
                                     }
                                     count--;
                                     GetSym();
                                     if(count)
                                     {
                                       if(SYM==COMMA)
                                          GetSym();
                                        else Error(48);
                                     }
                                     else Error (32);
                                   }
                                   else if(TABLE[Pos].KIND==VARIABLE)                //值参数匹配为其它变量时,
                                   {
                                       if(strcmp(TABLE[Pos].NUMKIND,"CHAR")==0 )     //匹配为字符
                                       {
                                         if(strcmp(ID,"CHAR")==0)  Error(32);
                                         else
                                         {
                                            GEN(LIT,0,(int)CH);                      //直接存入
                                            GEN(STO,LEV-TABLE[Pos].vp.LEVEL,TABLE[Pos].vp.ADR);
                                         }
                                       }
                                       else
                                       {                                                  //匹配为数字型
                                            if(strcmp(TABLE[Pos].NUMKIND,"INTEGER")==0)   //如果是整型
                                            WNUMK=1;                          //在进行运算表达式时就只能进行1类运算
                                            EXPRESSION(SymSetUnion(SymSetNew(RPAREN,COMMA),FSYS),LEV,TX);
 //值参数传递的如果是表达式
                                                                                  //例如 A(s+1+2*3);
                                            WNUMK=0;
                                            GEN(STO,LEV-TABLE[Pos].vp.LEVEL,TABLE[Pos].vp.ADR);          //直接存入
                                       }
                                       count--;
                                       if(count)
                                       {
                                            if(SYM==COMMA)
                                            GetSym();
                                            else Error(48);
                                       }
                                   }//end if(VARIABLE)
                                 }//end else(i=0)
                         }//end else VAR
                     }//else if(function)
                     Pos++;           //匹配下一个参数变量
                }//end while(count)
            if (SYM!=RPAREN) Error(33);
         }//end if(SYM==LPAREN)
}//end   ParaGetSub

//++++++++++++++++++++++++++start var &arr
void VarDeclaration(int LEV,int &TX,int &DX,int count,ALFA VARS[])  //变量类型声明处理
{
	int i=0;
    if(SYM==ARRAYSYM)           //如果是数组,按照PASCAL数组定义的语法处理
                                // <标识符> : ARRAY[整数..整数] OF <类型>
    {
           GetSym();
	   if(SYM==SQLPAREN) //SQLPAREN 代表 '[' 符号
       	   {
	     GetSym();
	     if(SYM==REALSYM && strcmp(ID,"REAL")!=0)              //上界为数字,实际上读入的是一个整型和一个点,
                                                           // 词法分析的时候就认为是实数了,不过不带小数。
                                                    //strcmp(ID,"REAL")!=0,这句是因为我在以后加入实型和整型的时候太懒了,
                                 //对整型数字的SYM直接用已有的INTEGERSYM 实型就为REALSYM 导致出现数字处理的时候,
                                //例如i:ARRAY[REAL.INTEGER]是可以接受的错误,这里就只好过滤了
             {
                if(NUM-(int)NUM!=0) Error(93); //类型错误     //判读是否带有小数,带小数就出错
                else
	        UPARR=(int)NUM;
	     }else
	     if(SYM==IDENT)     //上界为常数
	     {
	        int i=POSITION(ID,TX);
	        if (i==0)
	        {
	      	  Error(11);
	      	  UPARR=0;
	        }
	        else
	        if(TABLE[i].KIND==CONSTANT && strcmp(TABLE[i].NUMKIND,"INTEGER")==0)
                                                   //strcmp(TABLE[ii].NUMKIND,"INTEGER")==0  这里就不是过滤上面的错误
                                                   //是检测常数的数据类型是否为整型,字符和实型均不可接受
         	{
	        	UPARR=TABLE[i].VAL;
	     	}
	        else
		{
		  UPARR=0;
		  Error(91);  //存在于表中,但非常数
		}
	    }//if上界
	    GetSym();
	    if(SYM==PERIOD)
	    {
	    	GetSym();
            }else
	    Error(92);  //不正确的数组定义
            if(SYM==INTEGERSYM && strcmp(ID,"INTEGER")!=0)    //下界为数字,strcmp(ID,"INTEGER")!=0 是过滤上面的错误
	    {
	    	DOWNARR=(int)NUM+1;
	    }else
	    if(SYM==IDENT)     //下界为常数
	    {
	    	int ii=POSITION(ID,TX);
	    	if (ii==0)
	        {
		   Error(11);
                   DOWNARR=0;
                }
		else
		if(TABLE[ii].KIND==CONSTANT && strcmp(TABLE[ii].NUMKIND,"INTEGER")==0)
                                                              //是检测常数的数据类型是否为整型,字符和实型均不可接受
		{
		   DOWNARR=TABLE[ii].VAL;
		}
		else
		{
		   DOWNARR=0;
		   Error(91);  //存在于表中,但非常数
		}
            }//if下界
            GetSym();
	    if(SYM==SQRPAREN)        //SQRPAREN 代表 ']'符号
	    {
	      	GetSym();
	      	if(SYM==OFSYM)
	      	GetSym();
	      	else Error(93);
            }
	    else Error(93);  //数组定义不正确
	    if((SYM==INTEGERSYM  && strcmp(ID,"INTEGER")==0)|| (SYM==REALSYM && strcmp(ID,"REAL")==0)
                    || (SYM==CHARSYM && strcmp(ID,"CHAR")==0))    
//这里是过滤上面相反的可接受错误,  就是 I:121312; 是可接受错误
	    {
	    	for(i=0;i<count;i++)
	        ENTER(ARR,ID,LEV,TX,DX,VARS[i],FALSE);    //定义数组
	    }
	    else Error(92);
          }else Error(92);
    }
    else
    if((SYM==INTEGERSYM && strcmp(ID,"INTEGER")==0)|| (SYM==REALSYM && strcmp(ID,"REAL")==0)
                    || (SYM==CHARSYM && strcmp(ID,"CHAR")==0))     //同上的错误类型.
    {
          for(i=0;i<count;i++)
          ENTER(VARIABLE,ID,LEV,TX,DX,VARS[i],FALSE);    //定义变量
    }
    else Error(4);
     GetSym();

} /*VarDeclaration()*/

//++++++++++++++++++++++++++end


//---------------------------------------------------------------------------
void ListCode(int CX0) {  /*LIST CODE GENERATED FOR THIS Block*/
  if (Form1->ListSwitch->ItemIndex==0)
    for (int i=CX0; i<CX; i++) {
      String s=IntToStr(i);
      while(s.Length()<3)s=" "+s;
      if(CODE[i].A-(int)CODE[i].A!=0)
      s=s+""+MNEMONIC[CODE[i].F]+""+IntToStr(CODE[i].L)+" "+IntToStr((int)CODE[i].A)+"."+IntToStr((int)((CODE[i].A-(int)CODE[i].A)*10000));
      else s=s+" "+MNEMONIC[CODE[i].F]+" "+IntToStr(CODE[i].L)+" "+IntToStr((int)CODE[i].A);
	  Form1->printfs(s.c_str());
	  fprintf(FOUT,"%3d%5s%4d%4f\n",i,MNEMONIC[CODE[i].F],CODE[i].L,CODE[i].A);
    }
} /*ListCode()*/;

//-------------+++++++++++++++---------数组偏移地址处理过程
void ARRGetSub(SYMSET FSYS, int LEV,int &TX)
{

      GetSym();
      if(SYM==SQLPAREN)        //数组的语法为  <数组名> [ 运算表达式 ];
        {
          GetSym();

          WNUMK=1;                 //因为数组中只能进行,整型的运算,所以对下面的运算只能调用一类运算,WNUMK是全局变量
          EXPRESSION(SymSetUnion(SymSetNew(SQRPAREN),FSYS),LEV,TX);
          WNUMK=0;

          //GetSym();
          if(SYM!=SQRPAREN)
          Error(93);  //数组定义不正确

        }
        else Error(93);
        //if(arr)
}


//----------------++++++++++++++---------------



//---------------------------------------------------------------------------
void FACTOR(SYMSET FSYS, int LEV, int &TX) {
  int i,jk;
  jk=0;
  FCT STOMode[2]={STO,STOARR};   //这里是后面加入的对数组的运算实现代码 STOARR和LODARR
  FCT LODMode[2]={LOD,LODARR};
  TEST(FACBEGSYS,FSYS,24);
  while (SymIn(SYM,FACBEGSYS)) {
	if (SYM==IDENT) {
	  i=POSITION(ID,TX);
	  if (i==0) Error(11);
          else if((strcmp(TABLE[i].NUMKIND,"REAL")==0 && WNUMK==1)||strcmp(TABLE[i].NUMKIND,"CHAR")==0) Error(32);
//类型不匹配,字符型不可以参加运算
          else
		switch (TABLE[i].KIND) {
		  case CONSTANT: GEN(LIT,0,TABLE[i].VAL); break;
		  case VARIABLE: GEN(LOD,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR); break;
		  case PROCEDUR: Error(21); break;
                  //--------------------------------------------在表达式中的函数计算
                  case FUNCTION:
                        ParaGetSub(FSYS,LEV,TX,i);              //函数参数处理过程调用
                        GEN(CAL,LEV-TABLE[i].vp.LEVEL,TABLE[i].CS);       //生成调用函数的代码
                        GEN(LOD,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR);   
//读出函数的返回值,我是直接把函数的返回值放在函数名变量所在的地址位置.
                       break;
                  //-----------------------------------------------------------
                  case ARR:                                                //数组处理
                        jk=1;
                        ARRGetSub(FSYS,LEV,TX);                           //调用数组的偏移地址处理
                        GEN(LODMode[jk],LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR);//读出数组元素的值,放入栈顶
                        break;
		}
          GetSym();
          //++++++++++++++++++++ START ++ --       //变量自加运算
          if(SYM==PP)
          {
             GetSym();
             GEN(LIT,0,1);
             GEN(OPR,0,2);
             GEN(STOMode[jk],LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR);
             GEN(LODMode[jk],LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR);
          }
          else if(SYM==MM)                    //变量自减运算
          {
            GetSym();
            GEN(LIT,0,1);

⌨️ 快捷键说明

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