📄 recuranalyser.c
字号:
/******************************************************************************
*所属模块名:递归下降分析器
*
*功能:判定源程序中程序结构语句是否符合语法规则
*
*开始时间: 2004.10.29
*
*修改时间:2004.11.18,11.25,11.27,11.28
*
*完成时间:2004.11.28
*
*作者: 邸晓峰
*
*
*******************************************************************************/
#include "WordAnalyser.c"
//全局变量
Duatype WORD; //读入单词符号
vtable VariableTable; //变量表
ptable ProcTable; //过程名表
my_stack ProcStack; //过程栈,用于查过程名表
int level; //当前分析所在过程深度
int counter; //变量相对个数
int errflag_prog;
char errtext[19][20]; //错误信息存储区
bool isTrue; //如果语法分析出现错误,则置为false,不再产生四元式。
int PC; //四元式表指针
void LRAnalyser();
void GEN(int strOperator,Operand op1,Operand op2,Operand op3);
//////////////////////////////////////////////////////////////////////////////////////////////
//此函数初始化全局变量
void init(){
FILE* perrfile;
char temp;
int bufpoint,textpoint;
isTrue=true;
perrfile=fopen("error.txt","r");
for(textpoint=0;textpoint<19;textpoint++){
bufpoint=0;
temp=fgetc(perrfile);
while(temp!='\n'){ //和文件存储有关
errtext[textpoint][bufpoint]=temp;
bufpoint++;
temp=fgetc(perrfile);
}
errtext[textpoint][bufpoint]='\0';
}
fclose(perrfile);
level=0;
counter=1;
linenum=1;
VariableTable.first=0;
VariableTable.last=49;
ProcTable.pointer=-1; //便于后续处理
errflag_prog=false;
ProcStack.base=ProcStack.top=(stack_item*)malloc(sizeof(stack_item)); //初始化栈
ProcStack.base->index=0;
ProcStack.base->next=NULL;
}
//////////////////////////////////////////////////////////////////////////////////////////////
//此函数从二元式链表中读出一个单词符号,放入WORD中
void getWord(){
Duatype* temp;
if(Dualist.head->next==NULL){ //二元式链表读完,WORD.index=0作为标志
WORD.index=0;
Dualist.tail=Dualist.head;
}
else{
temp=Dualist.head->next;
Dualist.head->next=temp->next; //从链表中删除已读二元式
while(temp->index==35){
linenum++;
free(temp);
temp=Dualist.head->next;
if(temp==NULL)
break;
Dualist.head->next=temp->next;
}
if(temp==NULL){ //二元式链表读完,WORD.index=0作为标志
WORD.index=0;
Dualist.tail=Dualist.head;
}
else{
WORD.value=(char*)malloc((strlen(temp->value)+1)*sizeof(char));
strcpy(WORD.value,temp->value); //读入单词所在二元式
WORD.index=temp->index;
free(temp); //释放已读二元式空间
}
}
}
//////////////////////////////////////////////////////////////////////////////////////////////
//入栈函数
void push(){
ProcStack.top->next=(stack_item*)malloc(sizeof(stack_item));
ProcStack.top=ProcStack.top->next;
ProcStack.top->index=ProcTable.pointer;
ProcStack.top->next=NULL;
}
//////////////////////////////////////////////////////////////////////////////////////////////
//出栈函数
void pop(){
stack_item* p=ProcStack.base;
if(p!=ProcStack.top){
while(p->next!=ProcStack.top)
p=p->next;
p->next=NULL;
free(ProcStack.top);
ProcStack.top=p;
}
}
//////////////////////////////////////////////////////////////////////////////////////////////
//此函数跳过一些单词,直到读入指定的单词
//参数为索引值,按索引值跳到相应的单词
void skip(int index){
switch(index){
case 1: //jump to begin
while(WORD.index!=4){
getWord();
if(WORD.index==0)
break;
}
break;
case 2: //jump to procedure or begin
while(WORD.index!=3 && WORD.index!=4){
getWord();
if(WORD.index==0)
break;
}
break;
case 3: //jump to var or procedure or begin
while(WORD.index!=2 && WORD.index!=3 && WORD.index!=4){
getWord();
if(WORD.index==0)
break;
}
break;
}
}
//////////////////////////////////////////////////////////////////////////////////////////////
//此函数错误处理函数
//参数为索引值,表示正常执行第几条错误处理
void error_handle(int index){
printf("Error:第%d行,%s\n",linenum,errtext[index]);
isTrue=false;
}
//////////////////////////////////////////////////////////////////////////////////////////////
//此函数填写变量名表
//参数为0表示正常填入,为1标识倒填
void enterVTable(int flag){
int tempointer;
int i;
tempointer=VariableTable.first;
switch(flag){
case 0: //正常顺序填入
if(VariableTable.first>VariableTable.last){
error_handle(17); //越界处理
return;
}
else{
if(counter==1) //若是本过程第一个变量则填过程名表第一个变量所在位置first值
ProcTable.table[ProcTable.pointer].firstinvtable=VariableTable.first;
else{ //若不是本过程第一个变量则查本过程内是否有同名变量
for(i=ProcTable.table[ProcTable.pointer].firstinvtable;i<tempointer;i++)
if(strcmp(VariableTable.table[i].vname,WORD.value)==0){
error_handle(13);
return;
}
}
VariableTable.table[tempointer].vname=(char*)malloc((strlen(WORD.value)+1)*sizeof(char));
strcpy(VariableTable.table[tempointer].vname,WORD.value); //填变量名
free(WORD.value);
VariableTable.table[tempointer].plevel=level; //填嵌套深度
VariableTable.table[tempointer].relposition=counter; //填相对个数
counter++;
VariableTable.first++;
break;
}
case 1: //倒填
if(VariableTable.last<VariableTable.first){
error_handle(17); //越界处理
break;
}
else{
VariableTable.table[VariableTable.last].vname=(char*)malloc((strlen(WORD.value)+1)*sizeof(char));
strcpy(VariableTable.table[tempointer].vname,WORD.value); //填变量名
free(WORD.value);
VariableTable.last--;
break;
}
}
}
//////////////////////////////////////////////////////////////////////////////////////////////
//此函数在执行语句中遇到变量去查变量名表看是否已定义
//参数变量名,返回置为-1表示没查到,查到则返回在变量名表中的下标
int searchVTable(char *v){
int currentproc;
int firstvar;
int sumvar;
int i;
currentproc=ProcStack.top->index;
while(currentproc!=-1){
firstvar=ProcTable.table[currentproc].firstinvtable;
sumvar=ProcTable.table[currentproc].variablenum;
for(i=firstvar;i<firstvar+sumvar;i++)
if(strcmp(VariableTable.table[i].vname,v)==0)
return i;
currentproc=ProcTable.table[currentproc].outposition;
}
for(i=49;i>VariableTable.last;i--)
if(strcmp(VariableTable.table[i].vname,v)==0)
return i;
error_handle(15);
return -1;
}
//////////////////////////////////////////////////////////////////////////////////////////////
//此函数在填过程名表前去查过程名表看是否已定义
//参数变量名,返回置为-1表示没查到,查到则返回在过程名表中的下标
int searchPTable(char* name){
int i;
for(i=ProcTable.pointer;i>=0;i--){
if(strcmp(ProcTable.table[i].pname,name)==0){
error_handle(14);
return i;
}
}
return -1;
}
//////////////////////////////////////////////////////////////////////////////////////////////
//此函数填写过程名表
void enterPTable(){
int templevel;
int tempindex;
if(searchPTable(WORD.value)==-1){ //过程名不重名
ProcTable.pointer=ProcTable.pointer+1;
ProcTable.table[ProcTable.pointer].pname=(char*)malloc((strlen(WORD.value)+1)*sizeof(char));
strcpy(ProcTable.table[ProcTable.pointer].pname,WORD.value); //填过程名
free(WORD.value);
ProcTable.table[ProcTable.pointer].plevel=level; //填嵌套深度
ProcTable.table[ProcTable.pointer].paranum=0; //参数个数初始为0,后续可能修改
ProcTable.table[ProcTable.pointer].variablenum=0; //变量总数初始为0,后续可能修改
if(ProcTable.pointer==0) //填外过程位置
ProcTable.table[ProcTable.pointer].outposition=-1; //主程序外过程规定为-1
else{
if(level==ProcTable.table[ProcTable.pointer-1].plevel)
ProcTable.table[ProcTable.pointer].outposition=ProcTable.table[ProcTable.pointer-1].outposition;
else if(level>ProcTable.table[ProcTable.pointer-1].plevel)
ProcTable.table[ProcTable.pointer].outposition=ProcTable.pointer-1;
else{
templevel=ProcTable.table[ProcTable.pointer-1].plevel;
tempindex=ProcTable.pointer-1;
while(level!=templevel){
tempindex=ProcTable.table[tempindex].outposition;
templevel=ProcTable.table[tempindex].plevel;
}
ProcTable.table[ProcTable.pointer].outposition=ProcTable.table[tempindex].outposition;
}
}
}
}
void recurPRP();
//////////////////////////////////////////////////////////////////////////////////////////////
//PARL(参数说明)的递归下降分析子程序
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -