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

#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#define READ(ch) ch=getc(fp)
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 T1();
void F ();
void main(int argc,char *argv[])
{
void E ();
void E1();
void T ();
void T1();
void 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]); /*成功打开文件*/
/*[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); /*正常退出本程序*/
}
/*[2]开始遍历文件*/
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;
}
}

转载于:https://www.cnblogs.com/88mei/p/5091911.html

第三次上机—语法分析1 目的:熟练掌握自上而下的语法分析方法,并能用C++程序实现。 要求: 1. 使用的文法如下: E ® TE ¢ E ¢ ® + TE ¢ | e T ® FT ¢ T ¢ ® * FT ¢ | e F ® (E) | id 2. 对于任意给定的输入串(词法记号流)进行语法分析递归下降方法和非递归预测分析方法可以任选其一来实现。 3. 要有一定的错误处理功能。即对错误能提示,并且能在一定程度上忽略尽量少的记号来进行接下来的分析。可以参考书上介绍的同步记号集合来处理。 可能的出错情况:idid*id, id**id, (id+id, +id*+id …… 4. 输入串以#结尾,输出推导过程中使用到的产生式。例如: 输入:id+id*id# 输出:E ® TE ¢ T ® FT ¢ F ® id E ¢ ® + TE ¢ T ® FT ¢ …… 如果输入串有错误,则在输出中要体现是跳过输入串的某些记号了,还是弹栈,弹出某个非终结符或者是终结符了,同时给出相应的出错提示信息。比如: idid*id对应的出错信息是:“输入串跳过记号id,用户多输入了一个id”; id**id对应的出错信息是:“弹栈,弹出非终结符F,用户少输入了一个id” (id+id对应的出错信息是:“弹栈,弹出终结符 ) ,用户少输入了一个右括号(或者说,括号不匹配)” 有余力的同学可进一步考虑如下扩展: 1. 将递归下降方法和非递归预测分析方法都实现 2. 在语法分析的过程中调用第二次上机的结果,即利用词法分析器来返回一个记号给语法分析器。 3. 编写First和Follow函数,实现其求解过程。 测试文法: A->BCDE B->aBA|ε C->F|ε D->b|c|ε E->e|ε F->d|ε
递归下降分析法 一、实验目的: 根据某一文法编制调试递归下降分析程序,以便对任意输入符号串进行分析。本次实验的目的主要是加深对递归下降分析法的理解。 二、实验说明 1、递归下降分析法的功能 词法分析器的功能是利用函数之间的递归调用模拟语法树自上而下的构造过程。 2、递归下降分析法的前提 改造文法:消除二义性、消除左递归、提取左因子,判断是否为LL(1)文法, 3、递归下降分析法实验设计思想及算法 为G的每个非终结符号U构造一个递归过程,不妨命名为U。 U的产生式的右边指出这个过程的代码结构: (1)若是终结符号,则和向前看符号对照, 若匹配则向前进一个符号;否则出错。 (2)若是非终结符号,则调用与此非终结符对应的过程。当A的右部有多个产生式时,可用选择结构实现。 三、实验要求 (一)准备: 1.阅读课本有关章节, 2.考虑好设计方案; 3.设计出模块结构、测试数据,初步编制好程序。 (二)上课上机: 将源代码拷贝到机上调试,发现错误,再修改完善。第二次上机调试通过。 (三)程序要求: 程序输入/输出示例: 对下列文法,用递归下降分析法任意输入符号串进行分析: (1)E->eBaA (2)A->a|bAcB (3)B->dEd|aC (4)C->e|dc 输出的格式如下: (1)递归下降分析程序,编制人:姓名,学号,班级 (2)输入一以#结束的符号串:在此位置输入符号串例如:eadeaa# (3)输出结果:eadeaa#为合法符号串 注意: 1.如果遇到错误的表达式,应输出错误提示信息(该信息越详细越好); 2.对学有余力的同学,可以详细的输出推导的过程,即详细列出每一步使用的产生式。 ()程序思路 0.定义部分:定义常量、变量、数据结构。 1.初始化:从文件将输入符号串输入到字符缓冲区中。 2.利用递归下降分析法分析,对每个非终结符编写函数,在主函数中调用文法开始符号的函数。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值