📄 pl.cpp
字号:
{
TYPES type;
int ref,size,helper;
if(CurSymbol->type==IDENT)
{
ENTER(TYPEL); //被声明的类型标识符
helper=TX;
getASymbol();
if(CurSymbol->type==EQL)
getASymbol();
else
{
error(6);//应该是'='
if(CurSymbol->type==SEMICOLON)
getASymbol();
}
//////////////////////////////////////////////////////////////
SYMLIST * tempList=new SYMLIST;
COPYLIST(tempList,listAddSym(listAddSym(listAddSym(list,SEMICOLON),COMMA),IDENT));
TYP(tempList,type,ref,size); //获取类型信息
delete tempList;
//////////////////////////////////////////////////////////////
NAMETAB[TX].type=type; //填表
NAMETAB[TX].ref=ref;
NAMETAB[TX].unite.size=size;
if(CurSymbol->type==SEMICOLON)
getASymbol();
else
error(1);//应该是';'
}
else
error(14);//应该是标识符
}
void VARDECLARATION(SYMLIST * list) //变量声明
{
TYPES type;
int ref,size,helper1,helper2;
if(CurSymbol->type==IDENT)
{
helper1=TX;
ENTER(VARIABLE); //被声明的变量
getASymbol();
while(CurSymbol->type==COMMA) //如果是逗号,则面临的是同类型的一串变量列表
{
getASymbol();
if(CurSymbol->type==IDENT)
{
ENTER(VARIABLE); //被声明的变量
getASymbol();
}
else
error(14);//应该是标识符
}
if(CurSymbol->type==COLON)
getASymbol();
else
error(0);//应该是':'
helper2=TX;
//////////////////////////////////////////////////////////
SYMLIST * tempList=new SYMLIST;
COPYLIST(tempList,listAddSym(listAddSym(listAddSym(list,SEMICOLON),COMMA),IDENT));
TYP(tempList,type,ref,size); //获取变量的类型信息
delete tempList;
//////////////////////////////////////////////////////////
while(helper1<helper2) //将一串变量的信息填表
{
helper1++;
NAMETAB[helper1].type=type;
NAMETAB[helper1].ref=ref;
NAMETAB[helper1].level=displayLevel;
NAMETAB[helper1].unite.address=DX;
NAMETAB[helper1].normal=1;
DX+=size;
}
if(CurSymbol->type==SEMICOLON)
getASymbol();
else
error(1);//应该是';'
}
else
error(14);//应该是标识符
}
void PROCDECLARATION(SYMLIST * list) //过程声明
{
getASymbol();
if(CurSymbol->type!=IDENT)
{
error(14); //应该是标识符
strcpy(CurSymbol->value.lpValue,"");
}
ENTER(PROCEDURE); //被声明的过程名
NAMETAB[TX].normal=1;
getASymbol();
///////////////////////////////////////////////////////////
SYMLIST * tempList1=new SYMLIST;
COPYLIST(tempList1,listAddSym(list,SEMICOLON));
BLOCK(tempList1,displayLevel); //编译过程体
delete tempList1;
///////////////////////////////////////////////////////////
if(CurSymbol->type==SEMICOLON)
getASymbol();
else
error(1);//应该是';'
}
void error(int errCode) //负责显示出错信息的函数
{
char errorScript[][100]=
{
"应该是\':\'",//0
"应该是\';\'",//1
"应该是\')\'",//2
"应该是\'(\'",//3
"应该是\'[\'",//4
"应该是\']\'",//5
"应该是\'=\'",//6
"应该是\':=\'",//7
"应该是\'.\'",//8
"应该是\'do\'",//9
"应该是\'of\'",//10
"应该是\'then\'",//11
"应该是\'end\'",//12
"应该是\'program\'",//13
"应该是标识符",//14
"应该是类型标识符",//15
"应该是变量",//16
"应该是常量或常量标识符",//17
"应该是过程名",//18
"数组上下界大小关系错误",//19
"数组定义时,下标元素类型错误",//20
"数组定义时,上下界类型不一致",//21
"引用时,数组元素下标元素类型出错",//22
"下标个数不正确",//23
"数组表溢出",//24
"名字表溢出",//25
"程序体表溢出",//26
"系统为本编译程序分配的堆不够用",//27
"实参与形参个数不等",//28
"实参与形参类型不一致",//29
"实参个数不够",//30
"程序体内符号重定义",//31
"if或while后面表达式必须为布尔类型",//32
"标识符没有定义",//33
"过程名或类型名不能出现在表达式中",//34
"操作数类型错误",//35
"类型定义出错",//36
"类型不一致",//37
"不认识的字符出现在源程序",//38
"不能打开.lst文件",//39
"不能打开.pld文件",//40
"不能打开.lab文件",//41
"应该是\'..\'",//42
"分析时缺少标识符",//43
//*************************************** @@@@@@
"应该是\'until\'",//44 添加
"until后面表达式必须为布尔类型",//45添加
"应该是\'to\'",//46添加
"应该是整数",//47添加
};
if(CurSymbol && CurSymbol->lineNumber>0)
printf("\n<<<<<< Line number %d ",CurSymbol->lineNumber);
printf("found error %d : %s ! >>>>>>\n\n",errCode,errorScript[errCode]);
nError++;
}
void FACTOR(SYMLIST * list,TYPEITEM & typeItem) //获取下一个“因子”的信息,传引用参数typeItem用来保存信息
{
int i;
typeItem.typ=NOTYP;
typeItem.ref=0;
////////////////////////////////////////////////////////
SYMLIST * tempList2=new SYMLIST;
COPYLIST(tempList2,listAddSym(list,RPAREN));
////////////////////////////////////////////////////////
while(SYMINLIST(CurSymbol->type,&FACBEGSYS))
{
switch(CurSymbol->type)
{
case IDENT:
i=GETPOSITION(CurSymbol->value.lpValue); //如果是标识符,则查表
Temporary_i=i; //修改
getASymbol();
if(i!=0)
{
switch(NAMETAB[i].kind)
{
case KONSTANT:
typeItem.typ=NAMETAB[i].type;
typeItem.ref=0;
GEN(LIT,0,NAMETAB[i].unite.value);
break;
case VARIABLE:
typeItem.typ=NAMETAB[i].type;
typeItem.ref=NAMETAB[i].ref;
if(NAMETAB[i].type==INTS || NAMETAB[i].type==BOOLS || NAMETAB[i].type==CHARS)
{
if(NAMETAB[i].normal)
GEN(LOD,NAMETAB[i].level,NAMETAB[i].unite.address);
else
GEN(ILOD,NAMETAB[i].level,NAMETAB[i].unite.address);
}
else
{
if(NAMETAB[i].type==ARRAYS)
{
if(NAMETAB[i].normal)
GEN(LODA,NAMETAB[i].level,NAMETAB[i].unite.address);
else
GEN(LOD,NAMETAB[i].level,NAMETAB[i].unite.address);
if(CurSymbol->type==LBRACK)
ARRAYELEMENT(list,typeItem);
if(typeItem.typ!=ARRAYS)
GEN(LODT,0,0);
}
}
break;
case PROCEDURE:
case TYPEL:
error(34); //过程名或类型名不能出现在表达始中
break;
}
}
break;
case INTCON:
case CHARCON:
if(CurSymbol->type==INTCON)
typeItem.typ=INTS;
else
typeItem.typ=CHARS;
typeItem.ref=0;
GEN(LIT,0,CurSymbol->value.iValue);
Temporary_i=CurSymbol->value.iValue; //修改
getASymbol();
break;
case LPAREN: //如果是左括号
getASymbol();
EXPRESSION(tempList2,typeItem); //获取一个“表达式”的信息
if(CurSymbol->type==RPAREN)
getASymbol();
else
error(2); //应该是')'
break;
case NOTSYM: //如果是“非”
getASymbol();
FACTOR(list,typeItem); //获取一个“因子”的信息
if(typeItem.typ==BOOLS)
GEN(NOTS,0,0);
else
error(35); //操作数类型错误
break;
}
}
delete tempList2;
}
void TERM(SYMLIST * list,TYPEITEM & typeItem) //获取一个“项”的信息
{
SYMBOL mulop;
TYPEITEM helpTypeItem;
///////////////////////////////////////////////////////////
SYMLIST * tempList=new SYMLIST;
SYMLIST * tempList1=new SYMLIST;
tempList1->AddHead(TIMES); tempList1->AddHead(DIVSYM); tempList1->AddHead(MODSYM); tempList1->AddHead(ANDSYM);
COPYLIST(tempList,listsAdd(tempList1,list));
FACTOR(tempList,typeItem); //获取一个“因子”的信息
///////////////////////////////////////////////////////////
while(SYMINLIST(CurSymbol->type,tempList1))
{
mulop=CurSymbol->type;
getASymbol();
FACTOR(tempList,helpTypeItem); //获取一个“因子”的信息
if(typeItem.typ!=helpTypeItem.typ)
{
error(37);//类型不一致
typeItem.typ=NOTYP;
typeItem.ref=0;
}
else
{
switch(mulop)
{
case TIMES:
if(typeItem.typ==INTS)
GEN(MULT,0,0);
else
error(35);//操作数类型错误
break;
case DIVSYM:
if(typeItem.typ==INTS)
GEN(IDIV,0,0);
else
error(35);//操作数类型错误
break;
case MODSYM:
if(typeItem.typ==INTS)
GEN(IMOD,0,0);
else
error(35);//操作数类型错误
break;
case ANDSYM:
if(typeItem.typ==INTS)
GEN(ANDS,0,0);
else
error(35);//操作数类型错误
break;
}
}
}
delete tempList;delete tempList1;
}
void SIMPLEEXPRESSION(SYMLIST * list,TYPEITEM & typeItem) //获取一个“简单表达式”的信息
{
SYMBOL addop;
TYPEITEM helpTypeItem;
/////////////////////////////////////////////////
SYMLIST * tempList=new SYMLIST;
SYMLIST * tempList1=new SYMLIST;
tempList->AddHead(PLUS); tempList->AddHead(MINUS); tempList->AddHead(ORSYM);
COPYLIST(tempList1,listsAdd(tempList,list));
/////////////////////////////////////////////////
if(CurSymbol->type==PLUS || CurSymbol->type==MINUS)
{
addop=CurSymbol->type;
getASymbol();
TERM(tempList1,typeItem); //获取一个“项”的信息
if(addop==MINUS)
GEN(MUS,0,0);
}
else
TERM(tempList1,typeItem); //获取一个“项”的信息
while(SYMINLIST(CurSymbol->type,tempList))
{
addop=CurSymbol->type;
getASymbol();
TERM(tempList1,helpTypeItem); //获取一个“项”的信息
if(typeItem.typ!=helpTypeItem.typ) //如果两个项的信息发生冲突
{
error(37);//类型不一致
typeItem.typ=NOTYP;
typeItem.ref=0;
}
else
{
switch(addop)
{
case PLUS:
if(typeItem.typ==INTS)
GEN(ADD,0,0);
else
error(35);//操作数类型错误
break;
case MINUS:
if(typeItem.typ==INTS)
GEN(SUB,0,0);
else
error(35);//操作数类型错误
break;
case ORSYM:
if(typeItem.typ==BOOLS)
GEN(ORS,0,0);
else
error(35);//操作数类型错误
break;
}
}
}
delete tempList;delete tempList1;
}
void EXPRESSION(SYMLIST * list,TYPEITEM & typeItem) //获取一个“表达式”的信息
{
SYMBOL relationop;
TYPEITEM helpTypeItem;
/////////////////////////////////////////////////////////////////
SYMLIST * tempList=new SYMLIST;
SYMLIST * tempList1=new SYMLIST;
tempList->AddHead(EQL); tempList->AddHead(NEQ); tempList->AddHead(LSS);
tempList->AddHead(GTR); tempList->AddHead(LEQ); tempList->AddHead(GEQ);
COPYLIST(tempList1,listsAdd(tempList,list));
SIMPLEEXPRESSION(tempList1,typeItem); //获取一个“简单表达式”的信息
/////////////////////////////////////////////////////////////////
while(SYMINLIST(CurSymbol->type,tempList))
{
relationop=CurSymbol->type;
getASymbol();
SIMPLEEXPRESSION(list,helpTypeItem); ///获取一个“简单表达式”的信息
if(typeItem.typ!=helpTypeItem.typ)
error(37);//类型不一致
else
{
switch(relationop)
{
case EQL: GEN(EQ,0,0);break;
case NEQ: GEN(NE,0,0);break;
case LSS: GEN(LS,0,0);break;
case GEQ: GEN(GE,0,0);break;
case GTR: GEN(GT,0,0);break;
case LEQ: GEN(LE,0,0);break;
}
}
typeItem.typ=BOOLS;
}
delete tempList;delete tempList1;
}
void ARRAYELEMENT(SYMLIST * list,TYPEITEM & typeItem) //获取一个数组元素的信息
{
int p;
TYPEITEM helpTypeItem;
p=typeItem.ref;
if(CurSymbol->type==LBRACK)
{
SYMLIST * tempList=new SYMLIST;
COPYLIST(tempList,listAddSym(list,COMMA));
do
{
getASymbol();
EXPRESSION(tempList,helpTypeItem); //引用数组元素时所使用的数组下标的信息
if(typeItem.typ!=ARRAYS)
error(23); //下标个数不正确
else
{
if(helpTypeItem.typ!=ATAB[p].intType)
error(22); //数组元素引用时,下标元素类型出错
GEN(LIT,0,ATAB[p].low); //下面是产生的计算数组元素地址的代码
GEN(SUB,0,0);
GEN(LIT1,0,ATAB[p].elSize);
GEN(MULT,0,0);
GEN(ADD1,0,0);
typeItem.typ=ATAB[p].eleType;
typeItem.ref=ATAB[p].elRef;
p=ATAB[p].elRef;
}
}
while(CurSymbol->type==COMMA); //多维数组
if(CurSymbol->type==RBRACK)
getASymbol();
else
error(5);//应该是']'
}
else
error(4);//应该是'['
}
void INITIAL() //编译程序初始化所作的一些工作
{
nError=0;
displayLevel=0;
DISPLAY[0]=0;
DX=0;
CX=0;
BX=1;
TX=-1;
JX=0;
// FIVE SYMLISTS' INITIALIZATION
DECLBEGSYS.AddHead(CONSTSYM); DECLBEGSYS.AddHead(VARSYM);
DECLBEGSYS.AddHead(TYPESYM); DECLBEGSYS.AddHead(PROCSYM);
STATBEGSYS.AddHead(BEGINSYM); STATBEGSYS.AddHead(CALLSYM);
STATBEGSYS.AddHead(IFSYM); STATBEGSYS.AddHead(WHILESYM);
//********************************************************** @@@@@@
//修改
STATBEGSYS.AddHead(REPEATSYM); STATBEGSYS.AddHead(FORSYM);
STATBEGSYS.AddHead(CASESYM);
//**********************************************************
FACBEGSYS.AddHead(IDENT); FACBEGSYS.AddHead(INTCON); FACBEGSYS.AddHead(LPAREN);
FACBEGSYS.AddHead(NOTSYM); FACBEGSYS.AddHead(CHARCON);
TYPEBEGSYS.AddHead(IDENT); TYPEBEGSYS.AddHead(ARRAYSYM);
CONSTBEGSYS.AddHead(PLUS); CONSTBEGSYS.AddHead(MINUS); CONSTBEGSYS.AddHead(INTCON);
CONSTBEGSYS.AddHead(CHARCON); CONSTBEGSYS.AddHead(IDENT);
}
void ENTERID(char * name,OBJECT kind,TYPES type,int value) //向符号表中填入信息要用的函数
{
TX++;
strcpy(NAMETAB[TX].name,name);
NAMETAB[TX].link=TX-1;
NAMETAB[TX].kind=kind;
NAMETAB[TX].type=type;
NAMETAB[TX].ref=0;
NAMETAB[TX].normal=1;
NAMETAB[TX].level=0;
switch(kind)
{
case VARIABLE:
case PROCEDURE:
NAMETAB[TX].unite.address=value;break;
case KONSTANT:
NAMETAB[TX].unite.value=value;break;
case TYPEL:
NAMETAB[TX].unite.size=value;break;
}
return;
}
void ENTERPREID() //预先填入符号表的信息,将这些信息作为“过程零”里面的数据
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -