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