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

📄 unit1.cpp

📁 1. PL/0 语言介绍 ●PL/0 程序设计语言是一个较简单的语言
💻 CPP
📖 第 1 页 / 共 5 页
字号:
                              GetCh();
                            }
                            else if(CH=='-')
                                  {
                                    SYM=MM;
                                    GetCh();
                                  }else
                                     SYM=MINUS;
                        }
////++++++++++++++++++++++++++++++++++++++++++++++++++++++++++添加结束
		  else { SYM=SSYM[CH]; GetCh(); }
} /*GetSym()*/
//---------------------------------------------------------------------------
void GEN(FCT X, int Y, float Z) {
  if (CX>CXMAX) {
    Form1->printfs("PROGRAM TOO LONG");
	fprintf(FOUT,"PROGRAM TOO LONG\n");
	fclose(FOUT);
    exit(0);
  }
  CODE[CX].F=X; CODE[CX].L=Y; CODE[CX].A=Z;
  CX++;
} /*GEN*/
//---------------------------------------------------------------------------
void TEST(SYMSET S1, SYMSET S2, int N) {
  if (!SymIn(SYM,S1)) {
    Error(N);
	while (!SymIn(SYM,SymSetUnion(S1,S2))) GetSym();
  }
} /*TEST*/
//---------------------------------------------------------------------------
void ENTER(OBJECTS K,TYPES TYP, int LEV, int &TX, int &DX,ALFA IDS,bool IsVAR)
{ /*ENTER OBJECT INTO TABLE*/               //这里入表函数的处理过程,参量分别是  K OBJECTS
                                            //ALFA NUMKIND 是该标识符的类型,
                                            //ALFA IDS 标识符的名   //bool IsVAR是否变量参数还是值参数
  TX++;
  strcpy(TABLE[TX].NAME,IDS); TABLE[TX].KIND=K;
  TABLE[TX].TYPE=TYP;
  TABLE[TX].IsVAR=IsVAR;
  switch (K) {
	case CONSTANT:
	       if (NUM>AMAX && SYM==INTEGERSYM) { Error(31); NUM=0; }
               if (NUM>RMAX && SYM==REALSYM) { Error(31); NUM=0;}
	       TABLE[TX].VAL=NUM;
               break;
	case PROCEDUR:
               TABLE[TX].vp.LEVEL=LEV;
	       break;
//++++++++++++++++++++++++++++++++++++++++++++++++数组输入到符号表
        case ARR:
               TABLE[TX].vp.LEVEL=LEV;            //数组的层
               TABLE[TX].vp.ADR=DX;               //数组的首地址
               TX++;
               TABLE[TX].VAL=UPARR;               //开多一个符号表,存地址的上界
               TX++;
               TABLE[TX].VAL=DOWNARR;             //再开多个符号表,存地址的下界
               DX=DX+DOWNARR-UPARR+1;
               break;
//+++++++++++++++++++++++++++++++++++++++++++++++++end arr enter
//------------------------------------------------函数标识符输入到符号表
	case FUNCTION:
		TABLE[TX].vp.LEVEL=LEV;
                if(strcmp(TABLE[TX].NAME,"")!=0)
                {
                   TABLE[TX].vp.ADR=DX;
                   DX++;
                   TX++;
                   TABLE[TX].VAL=PARACOUNT;        //存入定义参数的个数
                }
		break;
//-------------------------------------------------end  fun enter

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

  }



} /*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) {

  if (SYM==IDENT)
  {

      GetSym();
      if (SYM==EQL||SYM==BECOMES)
	  {
	     if (SYM==BECOMES) Error(1);
	     GetSym();
             switch(SYM)
             {
               case INTS: ENTER(CONSTANT,INTCON,LEV,TX,DX,ID,FALSE); GetSym(); break;
               case REALS : ENTER(CONSTANT,REALCON,LEV,TX,DX,ID,FALSE); GetSym(); break;
               case CHARS : ENTER(CONSTANT,CHARCON,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[] 存有同一类型变量临时数组
{


        //if(IsVAR) LEV--;
        TYPES tm;
	if(SYM==ARRAYSYM)                //数组的参数的处理
	{
		GetSym();
		if(SYM==OFSYM)
		{
			UPARR=0;
			DOWNARR=0;
                        GetSym();
		        if(SYM==INTEGERSYM || SYM==REALSYM || SYM==CHARSYM)
			{
                                 switch(SYM)
                                 {
                                   case INTEGERSYM: tm=INTCON;  break;
                                   case REALSYM   : tm=REALCON; break;
                                   case CHARSYM   : tm=CHARCON; break;
                                 }
                                for(int i=0; i<count; i++)
                                {
         			    ENTER(PARR,tm,LEV,TX,DX,VARS[i],IsVAR);    //定义数组
                                    DISPLAY[LEV].bp++;
                                }
			}
			else Error(4);
		}else Error(92);  //不正确的数组定义
	}else
              if(SYM==INTEGERSYM || SYM==REALSYM || SYM==CHARSYM)
	        {
                                 switch(SYM)
                                 {
                                   case INTEGERSYM: tm=INTCON;  break;
                                   case REALSYM   : tm=REALCON; break;
                                   case CHARSYM   : tm=CHARCON; break;
                                 }

			for(int i=0;i<count;i++)
			{
                            ENTER(VARIABLE,tm,LEV,TX,DX,VARS[i],IsVAR);    //定义变量
                            DISPLAY[LEV].bp++;
			}

		}
		else Error(4);

}

//+++++++++++++++++++++++++++++++++++++++++++++++++++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)                    //匹配的如果是变量参数,即运算时是对实在参数的运算
                         {
                            i=POSITION(ID,TX);                   //i为形参所在的符号表下标
                            if(i==0) Error(11);
                            else
                            {
                               if(TABLE[Pos].TYPE==TABLE[i].TYPE) //类型匹配
                               {
                                 GEN(LIT,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR);  //开始实现传递地址
                                 GEN(STOPAR,0,/*DISPLAY[LEV].tp+*/TABLE[Pos].vp.ADR);          //直接存入
                               }
                               else Error(32);
                               count--;
                               GetSym();
                                     if(count)
                                     {
                                       if(SYM==COMMA)                           //参数之间用逗号格开
                                          GetSym();
                                        else Error(48);
                                     }
                            }
                         }
                         else                                                   //不是变量参数,就为值参数
                         {
                                   if(TABLE[Pos].KIND==ARR)                      //如果类型配为数组 ,需要在此函数的数据活动开始区域,
                                                                                //新开空间存放数组变量
                                   {
                                     i=POSITION(ID,TX);                         //i为形参所在的符号表下标
                                     if(TABLE[i].KIND!=PARR) Error(32);
                                     else
                                     {
                                         int UP,DOWN;
                                         TABLE[Pos].vp.ADR=DISPLAY[LEV].bp;          //新开空间的首地址,为display中存的地址
                                         DOWN=TABLE[Pos-1].VAL=TABLE[i].VAL;        //新开的数组空间调试时有致命错误导致整个程序被关,

                                         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(STOPAR,0,TABLE[Pos].vp.ADR+j);
                                           DISPLAY[LEV+1].tp++;
                                         }
                                         count--;
                                         GetSym();
                                         if(count)
                                         {
                                           if(SYM==COMMA)
                                           GetSym();
                                           else Error(48);
                                         }
                                         else Error (32);
                                     }
                                   }
                                   else if(TABLE[Pos].KIND==VARIABLE)                //值参数匹配为其它变量时,
                                   {
                                       if(TABLE[Pos].TYPE==CHARCON )     //匹配为字符
                                       {
                                         if(SYM!=CHARS)  Error(32);
                                         else
                                         {
                                            GEN(LIT,0,(int)CH);                      //直接存入
                                            GEN(STOPAR,0,TABLE[Pos].vp.ADR);
                                         }
                                       }
                                       else
                                       {                                                  //匹配为数字型
                                            if(TABLE[Pos].TYPE==INTCON)                  //如果是整型
                                            WNUMK=1;                                      //在进行运算表达式时就只能进行1类运算
                                            EXPRESSION(SymSetUnion(SymSetNew(RPAREN,COMMA),FSYS),LEV,TX); //值参数传递的如果是表达式
                                                                                                          //例如 A(s+1+2*3);
                                            WNUMK=0;
                                            GEN(STOPAR,0,/*DISPLAY[LEV].tp+*/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;
        TYPES tm;
    if(SYM==ARRAYSYM)           //如果是数组,按照PASCAL数组定义的语法处理
                                // <标识符> : ARRAY[整数..整数] OF <类型>
    {
           GetSym();
	   if(SYM==SQLPAREN) //SQLPAREN 代表 '[' 符号
       	   {
	     GetSym();
	     if(SYM==REALS)                                       //上界为数字,实际上读入的是一个整型和一个点,
                                                                  // 词法分析的时候就认为是实数了,不过不带小数。

             {
                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 && TABLE[i].TYPE==INTCON)
                                                               //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==INTS )    //下界为数字
	    {
	    	DOWNARR=(int)NUM+1;
	    }else
	    if(SYM==IDENT)     //下界为常数
	    {
	    	int ii=POSITION(ID,TX);
	    	if (ii==0)
	        {
		   Error(11);
                   DOWNARR=0;
                }
		else

⌨️ 快捷键说明

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