1231 实验四 递归下降语法分析程序设计

时间:2022-09-02 17:05:30

#include<stdio.h> 
#include<stdlib.h>
#include<malloc.h> 
#define READ(ch) ch=getc(fp) /*宏:READ(ch)*/ 
char ch; /*声明为全局变量*/ 
int right=0; 
FILE *fp;
struct struCH{ 
char ch; 
struct struCH *next; 
}struCH,*temp,*head,*shift; /*head指向字符线性链表的头结点*/ /*shift指向动态建成的结点(游标)*/ 
void E();
void E1(); 
void T(void); 
void T1(void); 
void F(void); 

void main(int argc,char *argv[])

void E (); /* P(E) */ 
void E1(); /* P(E')*/ 
void T (); /* P(T) */ 
void T1(); /* P(T')*/ 
void F (); /* P(F) */ 
int errnum=0,k=0,m=0,countchar=0,rownum; 
int charerr=0; /*开关控制量*/
if((fp=fopen(argv[1],"r"))==NULL) 

printf("\n\tCan not open file %s,or not exist it!\n",argv[1]); 
exit(0);
} /*文件不存在or打不开时,正常退出程序*/ 
else 
printf("\n\tSuccess open file: %s\n",argv[1]); /*成功打开文件*/
while(!feof(fp))

READ(ch); /*这里读取字符只是让文件指针往前移*/ 
countchar++; 
} /*统计文件中的字符数(包括换行符及文件结束符)*/ 
rewind(fp); /*将fp文件指针重新指向文件头处,以备后面对文件的操作*/ 
if(countchar==0)
{ /*空文件*/ 
printf("\t%s is a blank file!\n",argv[1]); 
exit(0); /*正常退出本程序*/ 
}
while(k<(countchar-1))
{ /*加换行符后countchar仍多了一个,不知为何*/ 
ch=getc(fp); 
if(!(ch=='('||ch==')'||ch=='i'||ch=='+'||ch=='-'||ch=='*'||ch=='/'||ch=='#'||ch=='\n'))

charerr=1;errnum++; /*charerror出错标记,errnum统计出错个数*/ 

k++; 

rewind(fp); /*将fp文件指针重新指向文件头处,以备后面的建链表操作*/ 
if(charerr==1)
{ /*文件中有非法字符*/ 
printf("\n\t%d Unindentify characters in file %s \n",errnum,argv[1]); 
exit(0); /*正常退出本程序*/ 
}
for(rownum=1;m<(countchar-1);rownum++)
{ /*识别所有行,rownum记录行号*/ /*初始变量及堆栈和*/ 
right=1; /*初始存放待识别的表达式的线性链表头*/ 
shift= malloc(sizeof(struCH));/**/ 
shift->next=NULL; 
head=shift; /*读取一行形成线性链表*/ 
READ(ch);
putchar(ch);
m++; 
while(ch!='\n'&&m<(countchar))
{ /*行末or到文件尾。最后会读取文件结束符*/ /*读取ch,读取存入结点,这样每行便形成一个线性链表*/ 
temp=malloc(sizeof(struCH)); 
temp->ch=ch; 
temp->next=NULL; 
shift->next=temp; 
shift=shift->next; 
READ(ch); 
if(m!=(countchar-1)) 
putchar(ch); /*不输出最后一次读取的文件结束符*/ 
m++; 

head=head->next; /*消去第一个空头结点,并使head指向非空线性链表*/
shift=head; /*shift指向头结点,以便后面识别操作*/ 
putchar('\n'); 
E(); /*开始识别一行*/ 
if(shift->ch=='#'&&right) /*正确提示:[文件名] Line [行号]:right expression!*/ 
printf("%s Line %d:\t right expression!\n",argv[1],rownum); 
else /*错误提示:[文件名] Line [行号]:error expression!*/ 
printf("%s Line %d:\t error expression!\n",argv[1],rownum); 
putchar('\n'); 
}/*end for*/ 
printf("Completed!\n"); 
fclose(fp); /*关闭文件*/ 
exit(0); /*正常结束程序*/ 
} /*以下函数分别对应于子模块程序*/ 
void E()

T(); 
E1(); 

void E1()

if(shift->ch=='+'||shift->ch=='-')

shift=shift->next; 
T(); 
E1(); 

else

if(shift->ch=='#'||shift->ch==')') 
return; 
else 
right=0; 


void T(void)

F(); 
T1(); 

void T1(void)

if(shift->ch=='*'||shift->ch=='/')

shift=shift->next; 
F(); 
T1(); 

else

if(shift->ch!='#'&&shift->ch!=')'&&shift->ch!='+'&&shift->ch!='-') 
right=0; /*如果不是'#'or')'or'+'or'+'or'-'则出错*/ 


void F(void)

if(shift->ch=='i') 
shift=shift->next; 
else{ 
if(shift->ch=='(')

shift=shift->next; 
E(); 
if(shift->ch==')') 
shift=shift->next; 
else 
right=0; 

else 
right=0; 

}