📄 unit1.~cpp
字号:
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 + -