编译原理实验4递归下降分析法
编译原理-第4章 语法分析--习题答案

第4章语法分析习题答案1.判断(1)由于递归下降分析法比较简单,因此它要求文法不必是LL(1)文法。
(× )LL(1)文法。
(× )(3)任何LL(1)文法都是无二义性的。
(√)(4)存在一种算法,能判定任何上下文无关文法是否是LL(1) 文法。
(√)(× )(6)每一个SLR(1)文法都是LR(1)文法。
(√)(7)任何一个LR(1)文法,反之亦然。
(× )(8)由于LALR是在LR(1)基础上的改进方法,所以LALR(× )(9)所有LR分析器的总控程序都是一样的,只是分析表各有不同。
(√)(10)算符优先分析法很难完全避免将错误的句子得到正确的归约。
(√)2.文法G[E]:E→E+T|TT→T*F|FF→(E)|i试给出句型(E+F)*i的短语、简单短语、句柄和最左素短语。
答案:画出语法树,得到:短语: (E+F)*i ,(E+F) ,E+F ,F ,i简单短语: F ,i句柄: F最左素短语: E+F3.文法G[S]:S→SdT | TT→T<G | GG→(S) | a试给出句型(SdG)<a的短语、简单短语、句柄和最左素短语。
答案:画出语法树,得到:短语:(SdG)<a 、(SdG) 、SdG 、G 、a简单(直接)短语:G 、a句柄:G最左素短语:SdG4.对文法G[S]提取公共左因子进行改写,判断改写后的文法是否为LL(1)文法。
S→if E then S else SS→if E then SS→otherE→b答案:提取公共左因子;文法改写为:S→if E then S S'|otherS'→else S|E→bLL(1)文法判定:① 文法无左递归② First(S)={if,other}, First(S')={else, }First(E)={b}Follow(S)= Follow(S')={else,#}Follow(E)={then}First(if E then S S')∩First(other)=First(else S)∩First( )=③First(S')∩Follow(S')={else}不为空集故此文法不是LL(1)文法。
编译原理 递归下降词法分析

编译原理实验报告—递归下降分析法程序实验2.1 递归下降分析法一、实验目的1. 根据某一文法编制递归下降分析程序,以便对任意输入的符号串进行分析。
2. 本次实验的目的是加深对递归下降分析法的理解。
二、实验平台Windows + VC++6.0范例程序: “递归下降分析法.cpp ”三、实验内容对下列文法,用递归下降分析法对任意输入的符号串进行分析:(1)E→TG(2)G→+TG|-TG(3)G→ε(4)T→FS(5)S→*FS|/FS(6)S→ε(7)F→(E)(8)F→i1.程序功能:输入: 一个以# 结束的符号串(包括+ - * / ()i # ):例如:i+i*i-i/i#输出:(1) 详细的分析步骤,每一步使用的产生式、已分析过的串、当前分析字符、剩余串,第一步, 产生式E->TG的第一个为非终结字符,所以不输出分析串,此时分析字符为i,剩余字符i+i*i-i/i#;第二步,由第一步的E->TG的第一个为非终结字符T,可进行对产生式T->FS 分析,此时第一个仍为非终结字符F,所以不输出分析串,分析字符仍为i, 剩余字符i+i*i-i/i#;第三步,使用产生式F->i,此时的分析串为i,,分析字符为i,匹配成功,剩余字符串+i*i-i/i#;第四步,因为使用了产生式T->FS,F->i,第一个字符i匹配成功,接着分析字符+,使用产生式S->ε,进行下步;第五步,使用产生式G->+TG,此时的分析串包含i+,分析字符为+,剩余字符串+i*i-i/i#;第六步,重复对产生式T->FS,F->i的使用,对第二个i进行匹配,此时分析串i+i,分析字符为i,剩余串*i-i/i#;第七步,分析字符*,使用产生式S->*FS, 分析串i+i*,剩余串i-i/i#;第八步,字符*匹配成功后,使用产生式F->i,匹配第三个字符i,,此时剩余串-i/i#;第九步,分析字符-,只有产生式G->-TG可以产生字符-。
编译原理-递归下降分析法

编译原理-递归下降分析法题:对下列⽂法,⽤递归下降分析法对任意输⼊的符号串进⾏分析:(1)E->TG(2)G->+TG|—TG(3)G->ε,(4)T->FS(5)S->*FS|/FS(6)S->ε(7)F->(E)(8)F->i答:⽂法太多,可先合并。
(1)E->FSG(2)G->+TG|—TG|ε(3)S->*FS|/FS|ε(4)F->(E)|i结合1,4(1)E->ESG|iSG(2)G->+TG|—TG|ε(3)S->*FS|/FS|ε(4)F->(E)|i消除左递归(1)E->iSGE1(2)E1->SGE1|ε(3)G->+TG|—TG|ε(4)S->*FS|/FS|ε(5)F->(E)|i好吧,其实上⾯的化简有些地⽅并⽆必要,不过我的代码是按照最后的⽂法写的。
package compile;public class com {public static String str="i+i*i"; //待测试语句static int seri=0; //记录当前读到的序号public static void main(String[] args) {int t=E(); //⽂法if(t==1) {System.out.println(str+" compiled successfully");}else {System.out.println(str+" compiled failed");}}static char getchar() {if(seri<str.length()) {System.out.println(seri+" "+str.charAt(seri));return str.charAt(seri++);}return ' ';};static int E() {char ch=getchar();if(ch!='i') {return 0;}return S()*G()*E1();}static int S() {char ch=getchar();if(ch=='+'|ch=='-') {seri--;return 1;}else if(ch=='*'|ch=='/') {return F()*S();}else if(ch=='i') {return 0;}return 1;}static int F() {char ch=getchar();if(ch=='i') return 1;return E();}static int G() {char ch=getchar();if(ch=='*'|ch=='/') {seri--;return 1;}else if(ch=='+'|ch=='-') {return F()*S()*G();}else if(ch=='i') {return 0;}return 1;}static int E1() {char ch=getchar();if(ch=='i') return 0;if(ch==' ') return 1;return S()*G()*E1(); }}。
编译原理递归下降预测分析

《编译原理》课程实验报告课程实验题目:作者所在系部:计算机科学与工程系作者所在专业:计算机科学与技术作者所在班级:作者学号:作者姓名:指导教师姓名:一、实验目的通过本实验,了解递归下降预测分析的原理和过程以及可能存在的回溯问题,探讨解决方法,为预测分析表方法的学习奠定基础。
分析递归下降子程序的优缺点。
二、实验内容及要求1.给定文法:S→(T)|a+S|aT→T,S|S改写文法,使其可以使用递归下降子程序方法进行分析,编写递归下降子程序,判断句子:(((a+a+a),a+a),a)是否符合该文法。
输入:(((a+a+a),a+a),a)输出:结构正确或结构错误2.编写程序调试运行;考虑如果将你的程序改为识别其他的文法,你的递归下降子程序可否通用,考虑递归下降子程序方法的优缺点。
三、实验程序设计说明1.实验方案设计1.match;函数:从文件中依次读字符2.S函数:判断表达式是否满足S→(T)|aS1。
3.S1函数:判断表达式是否满足S1→(a+)S1|e4.T函数:判断表达式是否满足T→ST15.T1函数:判断表达式是否满足T1→,ST1|e6.error函数:输出错误信息到屏幕2.程序源代码#include<iostream.h>#include<stdlib.h>void match(char t);void S();void S1();void T();void T1();void error();char lookahead;char a[100];int i=0;int j=0;int x=0;void match(char t){if(lookahead==t)lookahead=a[++j];else error();}void S(){if(lookahead=='('){match('(');T();if(lookahead==')')match(')');else error();}else if(lookahead=='a'){match('a');S1();}else error();}void S1(){if(lookahead=='+'){match('+');S();}}void T(){S();T1();}void T1(){if(lookahead==','){match(',');S();T1();}}void error()x=-1;}void main(){cout<<"请输入一个表达式(((a+a+a),a+a),a)(以@结束):";char c;cin>>c;char s;cin>>s;while(s!='@'){a[i]=s;i++;cin>>s;}lookahead=*a;S();if(x==-1)cout<<"不匹配"<<endl;if(x==0)cout<<"匹配"<<endl;}3.程序的执行结果4.实验程序的优点和特色1.输入是以读文件的方式进行,避免了输入时的繁琐;2.递归下降子程序的健壮性较好,能准确分析出表达式错误的位置等;3.采用C语言极其部分函数编写,易懂。
编译原理用递归下降法进行表达式分析实验报告

《编译原理》课程实验报告题目用递归下降法进行表达式分析专业班级学号姓名一.实验题目用递归下降法进行语法分析的方法二.实验日期三.实验环境(操作系统,开发语言)操作系统是Windows开发语言是C语言四.实验内容(实验要求)词法分析程序和语法分析程序已经提供。
此语法分析程序能够实现:正确的输入可以给出结果。
例:输入表达式串为:(13+4)*3则应给出结果为51。
要求:(1)读懂源代码,理解内容写入实验报告(语法分析及语法分析程序和词法分析程序的接口)(2)把语法分析中使用的yyval,用yytext实现。
(3)在语法分析程序用加入出错处理(尽量完整,包括出错的位置,出错的原因,错误的重定位)五.实验步骤1.生成lex.yy.c文件:将已给的mylexer.l文件打开,先理解,然后再在DOS环境下用flex运行此文件,这时会生成一个lex.yy.c文件。
2.创建工程:打开C-Free 5.0(注:用C-Free 4.0会出错),在菜单栏中的“工程(project)”菜单下选择“新建”;在新建工程中选择“控制台程序”,添加工程名字为“myleb”和保存位置后点“确定”;第1步选择“空的程序”点“下一步”;第2步再点“下一步”;最后点击“完成”。
3.在创建的工程中添加文件:在Source files文件夹中添加之前生成的lex.yy.c文件和syn.c文件,然后找到parser.h文件,将其添加到新建工程中的Header files文件夹中,这时就能将三个文件组成一个类似于.exe文件类型的文件,最后运行。
如图:4.理解并修改syn.c文件:首先,将num = yyval.intval修改成num = atoi(yytext);将num = yyval.fval修改成num = atof(yytext)。
可以这样修改的原因:在.l文件中所写的规则中,有{DIGIT}+ { yyval.intval = atoi(yytext);return INTEGER; }和{DIGIT}+"."{DIGIT}* {yyval.fval = atof(yytext); return DOUBLE; } 这两句代码,其中yyval.intval = atoi(yytext)和yyval.fval = atof(yytext)就说明两者可以相互替代。
编译原理递归下降分析法C语言

编译原理递归下降分析法C语言编译原理是计算机科学中的一个重要领域,主要研究如何将高级语言程序转化为机器可执行的目标代码。
在编译原理中,递归下降分析法是一种常用的语法分析方法,它通过递归地从上至下对程序进行分析,最终确定程序的语法结构。
递归下降分析法是一种自顶向下的语法分析方法,基于产生式和预测分析表来实现对程序的语法分析。
该方法的基本思想是,每个非终结符对应一个处理过程,通过递归调用这些处理过程来分析整个程序。
在C语言的递归下降分析法中,需要定义对应C语言语法结构的处理过程,这些处理过程通常对应于C语言中的各种语句、表达式、声明等。
递归下降分析法的实现主要包括两个步骤:构造预测分析表和编写递归下降分析程序。
预测分析表是一个二维表格,行对应于非终结符,列对应于终结符,表格中的每个元素记录了该产生式的编号。
通过预测分析表,可以预测下一个分析符号,并选择相应的产生式进行语法分析。
编写递归下降分析程序时,首先需要确定递归下降分析程序的数据结构和接口。
一般来说,分析程序的数据结构包括符号栈、语法树等,接口包括初始化、语法分析、错误处理等。
接下来,根据语法规则编写对应的递归下降分析函数,每个函数对应一个非终结符的处理过程。
在实际编写过程中,通常使用递归调用来实现对程序的逐步分析,直到达到终结符。
递归下降分析法在C语言编译器中的应用非常广泛。
通过该方法,可以对C语言程序进行语法分析,检测代码中的语法错误,并生成相应的语法树。
在生成语法树之后,可以继续进行语义分析、中间代码生成、代码优化等编译过程。
总的来说,递归下降分析法是一种重要的语法分析方法,可以用于对C语言程序进行语法分析。
它通过自顶向下的递归调用,从上至下地解析语法规则,最终确定程序的语法结构。
递归下降分析法在实际编译器设计中有广泛应用,是理解和学习编译原理的重要内容。
编译原理递归下降

《编译原理》课程实验实验二:自顶向下的语法分析:递归下降法1、实验目的:编制一个递归下降分析程序,实现对词法分析程序所提供的单词序列的语法检查和结构分析。
2、实验要求:文法(教材199页)(1)把词法分析作为语法分析的子程序实现(5分)(2)独立的语法分析程序(4分)(3)输入串以‘#’结束,输出成功(success)或出错(error)、指出出错位置(行、列以及错误类型)#include<iostream>#include<ctype.h>#include<fstream>#include<string.h>#include<malloc.h>using namespace std;ifstream fp("in.txt",ios::in);char cbuffer;char *key[13]={"if","else","for","while","do","return","break","continue","int","void" ,"main","begin","end"}; //关键字char *border[8]={ "," , ";" , "{" , "}" , "(" , ")" ,"//","\""}; //分界符char *arithmetic[6]={"+" , "-" , "*" , "/" , "++" , "--"}; //运算符char *relation[7]={"<" , "<=" , "=" , ">" , ">=" , "==" ,"!="}; //关系运算符char *lableconst[80]; //标识符int constnum=40;int lableconstnum=0;int colnum = 1, linenum=1; //统计常数和标识符数量int type1, type2;int search(char searchchar[],int wordtype){int i=0,t=0;switch (wordtype){case 1:{ for (i=0;i<=12;i++) //关键字{if (strcmp(key[i],searchchar)==0)return(i+1);}return(0);}case 2:{for (i=0;i<=6;i++) //分界符{if (strcmp(border[i],searchchar)==0)return(i+1);}return(0);}case 3:{for (i=0;i<=5;i++) //运算符{if (strcmp(arithmetic[i],searchchar)==0)return(i+1);}return(0);}case 4:{for (i=0;i<=6;i++) //关系运算符{if (strcmp(relation[i],searchchar)==0)return(i+1);}return(0);}case 5:{for (t=40;t<=constnum;t++) //常数{if (strcmp(searchchar,lableconst[t])==0)//判断该常数是否已出现过return(t+1);}lableconst[t-1]=(char *)malloc(sizeof(searchchar));//为新的元素分配内存空间strcpy(lableconst[t-1],searchchar);//为数组赋值lableconst指针数组名constnum++; //常数个数自加return(t);}case 6:{for (i=0;i<=lableconstnum;i++){if (strcmp(searchchar,lableconst[i])==0) //判断标识符是否已出现过return(i+1);}lableconst[i-1]=(char *)malloc(sizeof(searchchar));strcpy(lableconst[i-1],searchchar);lableconstnum++; //标识符个数自加return(i);}default:cout<<"错误!";return 0;}}char alphaprocess(char buffer) //字符处理过程{int atype;int i=-1;char alphatp[20];while (((isalpha(buffer))||(isdigit(buffer))) && !fp.eof()){alphatp[++i]=buffer;fp.get(buffer);}alphatp[i+1]='\0';//在末尾添加字符串结束标志if (atype=search(alphatp,1)){cout<<alphatp<<"\t\t\t"<<"关键字"<<endl;type1 = 0;}else{atype=search(alphatp,6); //标识符cout<<alphatp<<"\t\t\t"<<"标识符"<<endl;type1 = 1;}type2 = atype;return(buffer);}char digitprocess(char buffer) //数字处理过程{int i=-1;char digittp[20];int dtype;while((isdigit(buffer)||buffer=='.'||buffer=='e'||buffer=='+'||buffer=='-')&& !fp.eof()) {digittp[++i]=buffer;fp.get(buffer);}digittp[i+1]='\0';dtype=search(digittp,5);cout<<digittp<<"\t\t\t"<<"数据"<<endl;type1 = 8;type2 = dtype;return(buffer);}char otherprocess(char buffer) //分界符、运算符、逻辑运算符、等{int i=-1;char othertp[20];int otype,otypetp;othertp[0]=buffer;othertp[1]='\0';if (otype=search(othertp,3)){fp.get(buffer);othertp[1]=buffer;othertp[2]='\0';if (otypetp=search(othertp,3)) //判断该运算符是否是//由连续的两个字符组成的{cout<<othertp<<"\t\t\t"<<"运算符"<<endl;fp.get(buffer);type1 = 2;goto out;}else//单字符逻辑运算符{othertp[1]='\0';cout<<othertp<<"\t\t\t"<<"逻辑运算符"<<endl;type1 = 3;goto out;}}if (otype=search(othertp,4)) //关系运算符{fp.get(buffer);othertp[1]=buffer;othertp[2]='\0';if (otypetp=search(othertp,4)) //判断该关系运算符是否是//由连续的两个字符组成的{cout<<othertp<<"\t\t\t"<<"关系运算符"<<endl;fp.get(buffer);type1 = 4;goto out;}else//单字符逻辑运算符{othertp[1]='\0';cout<<othertp<<"\t\t\t"<<"逻辑运算"<<endl;type1 = 5;goto out;}}if (buffer=='!') //"=="的判断{fp.get(buffer);if (buffer=='=')//cout<<"!= (2,2)\n";fp.get(buffer);type1 = 6;goto out;}else{if (otype=search(othertp,2)) //分界符{cout<<othertp<<"\t\t\t"<<"分界符"<<endl;fp.get(buffer);type1 = 7;goto out;}}if ((buffer!='\n')&&(buffer!=' '))cout<<"错误!,字符非法"<<"\t\t\t"<<buffer<<endl;fp.get(buffer);out:type2 = otypetp;return(buffer);}void getWord(){type1 = -1;while(type1 == -1){if (fp.eof()) break;colnum++;if(cbuffer=='\n'){linenum++;colnum = 1;fp.get(cbuffer);}else if (isalpha(cbuffer)){cbuffer=alphaprocess(cbuffer);}else if (isdigit(cbuffer)){cbuffer=digitprocess(cbuffer);}elsecbuffer=otherprocess(cbuffer);}}string eText;bool hasError;void setError(string text) {hasError = true;eText = text;}void checkExpression();void checkFactor() {cout << type1 << " " << type2 << endl;if (type1 == 1 || type1 == 8) getWord();else if (type1 == -1) setError("缺少值或变量。
编译原理-实验4递归下降分析法

实验4《递归下降分析法设计与实现》实验学时: 2 实验地点:实验日期:一、实验目的根据某一文法编制调试递归下降分析程序,以便对任意输入的符号串进行分析。
本次实验的目的主要是加深对递归下降分析法的理解。
二、实验内容程序输入/输出示例(以下仅供参考):对下列文法,用递归下降分析法对任意输入的符号串进行分析:(1)E-TG(2)G-+TG|—TG(3)G-ε(4)T-FS(5)S-*FS|/FS(6)S-ε(7)F-(E)(8)F-i输出的格式如下:(3)备注:输入一符号串如i+i*#,要求输出为“非法的符号串”。
注意:1.表达式中允许使用运算符(+-*/)、分割符(括号)、字符I,结束符#;2.如果遇到错误的表达式,应输出错误提示信息(该信息越详细越好)。
三、实验方法用C语言,根据递归下降分析法的规则编写代码,并测试。
四、实验步骤1.对语法规则有明确的定义;2.编写的分析程序能够对实验一的结果进行正确的语法分析;3.对于遇到的语法错误,能够做出简单的错误处理,给出简单的错误提示,保证顺利完成语法分析过程;五、实验结果六、实验结论#include<stdio.h>#include<dos.h>#include<stdlib.h>#include<string.h>char a[50],b[50],d[200],e[10];char ch;int numOfEq,i1=0,flag=1,n=6;int E();int E1();int T();int G();int S();int F();void input();void input1();void output();//================================================ void main()/*递归分析*/{ int foe1,i=0;char x;d[0]='E';d[1]='=';d[2]='>';d[3]='?';d[4]='T';d[5]='G';d[6]='#';printf("请输入字符串(以#号结束)\n");do{ scanf("%c",&ch);a[i]=ch;i++;}while(ch!='#');numOfEq=i;ch=b[0]=a[0];printf("文法\t分析串\t\t分析字符\t剩余串\n");if (foe1==0) return;if (ch=='#'){ printf("accept\n");i=0;x=d[i];while(x!='#'){ printf("%c",x);i=i+1;x=d[i];/*输出推导式*/}printf("\n");}else{ printf("error\n");printf("回车返回\n");getchar();getchar();return;}}//================================================ int E1(){ int fot,fog;printf("E->TG\t");flag=1;input();input1();fot=T();if (fot==0) return(0);fog=G();if (fog==0) return(0);else return(1); }//================================================ int E(){ int fot,fog;printf("E->TG\t");e[0]='E';e[1]='=';e[2]='>';e[3]='?';e[4]='T';e[6]='#';output();flag=1;input();input1();fot=T();if (fot==0) return(0);fog=G();if (fog==0) return(0);else return(1); }//================================================ int T(){ int fof,fos;printf("T->FS\t");e[0]='T';e[1]='=';e[2]='>';e[3]='?';e[4]='F';e[5]='S';e[6]='#';output();flag=1;input();input1();fof=F();if (fof==0) return(0);fos=S();if (fos==0) return(0);else return(1); }//================================================ int G(){ int fot;if(ch=='+'){ b[i1]=ch;printf("G->+TG\t");e[0]='G';e[2]='>';e[3]='?';e[4]='+';e[5]='T';e[6]='G';e[7]='#';output();flag=0;input();input1();ch=a[++i1];fot=T();if (fot==0) return(0); G();return(1);}else if(ch=='-'){ b[i1]=ch;printf("G->-TG\t"); e[0]='G';e[1]='=';e[2]='>';e[3]='?';e[4]='-';e[5]='T';e[6]='G';e[7]='#';output();flag=0;input();input1();ch=a[++i1];fot=T();if (fot==0) return(0); G();return(1); }printf("G->^\t");e[1]='=';e[2]='>';e[3]='?';e[4]='^';e[5]='#';output();flag=1;input();input1();return(1);}//================================================ int S(){ int fof,fos;if(ch=='*'){ b[i1]=ch;printf("S->*FS\t");e[0]='S';e[1]='=';e[2]='>';e[3]='?';e[4]='*';e[5]='F';e[6]='S';e[7]='#'; output();flag=0;input();input1();ch=a[++i1];fof=F();if (fof==0)return(0);fos=S();if (fos==0) return(0);else return(1); }else if(ch=='/'){ b[i1]=ch;printf("S->/FS\t");e[0]='S';e[1]='=';e[2]='>';e[3]='?';e[4]='/';e[5]='F';e[6]='S';e[7]='#'; output();flag=0;input();input1();ch=a[++i1];fof=F();if (fof==0) return(0);fos=S();if (fos==0) return(0);else return(1); }printf("S->^\t");e[0]='S';e[1]='=';e[2]='>';e[3]='?';e[4]='^';e[5]='#';output();flag=1;a[i1]=ch;input();input1();return(1); }//================================================ int F(){int f;if(ch=='('){ b[i1]=ch;printf("F->(E)\t");e[0]='F';e[1]='=';e[2]='>';e[3]='?';e[3]='(';e[4]='E';e[5]=')';e[7]='#'; output();flag=0;input();input1();ch=a[++i1];f=E();if (f==0) return(0); if(ch==')'){ b[i1]=ch;printf("F--(E)\t");flag=0;input();input1();ch=a[++i1]; }else{ printf("error\n");return(0);}}else if(ch=='i'){b[i1]=ch;printf("F->i\t");e[0]='F';e[1]='=';e[2]='>';e[3]='?';e[4]='i';e[5]='#';output();flag=0;input();input1();ch=a[++i1];}else{printf("error\n");return(0);}return(1);}//================================================ void input(){ int i=0;for (;i<=i1-flag;i++)printf("%c",b[i]);/*输出分析串*/printf("\t\t");printf("%c\t\t",ch);/*输出分析字符*/}//================================================ void input1(){ int i;for (i=i1+1-flag;i<numOfEq;i++)printf("%c",a[i]);/*输出剩余字符*/printf("\n");}//================================================ void output(){/*推导式计算*/int m,k,j,q;int i=0;m=0;k=0;q=0;i=n;d[n]='=';d[n+1]='>';d[n+2]='?';d[n+3]='#';n=n+3;i=n;i=i-2;while(d[i]!='?'&&i!=0)i--;i=i+1;while(d[i]!=e[0])i=i+1;q=i;m=q;k=q;while(d[m]!='?')m=m-1;m=m+1;while(m!=q){d[n]=d[m];m=m+1;n=n+1;}d[n]='#';for(j=3;e[j]!='#';j++){d[n]=e[j];n=n+1;}k=k+1;while(d[k]!='='){d[n]=d[k];n=n+1;k=k+1;}d[n]='#';}七、实验小结通过本次试验实践掌握了自上而下语法分析法的特点。
编译原理语法分析递归下降子程序实验报告

编译原理语法分析递归下降子程序实验报告编译课程设计-递归下降语法分析课程名称编译原理设计题目递归下降语法分析一、设计目的通过设计、编制、调试一个具体的语法分析程序,加深对语法分析原理的理解,加深对语法及语义分析原理的理解,并实现对文法的判断,是算符优先文法的对其进行FirstVT集及LastVT集的分析,并对输入的字符串进行规约输出规约结果成功或失败。
二、设计内容及步骤内容:在C++ 6.0中编写程序代码实现语法分析功能,调试得到相应文法的判断结果:是算符优先或不是。
若是,则输出各非终结符的FirstVT与LastVT集的结果,还可进行字符串的规约,输出详细的规约步骤,程序自动判别规约成功与失败。
步骤:1.看书,找资料,了解语法分析器的工作过程与原理2.分析题目,列出基本的设计思路1定义栈,进栈,出栈函数○2栈为空时的处理○3构造函数判断文法是否是算符文法,算符优先文法○4构造FirstVT和LastVT函数对文法的非终结符进行分析○5是算符优先文法时,构造函数对其可以进行输入待规约○串,输出规约结果○6构造主函数,对过程进行分析3.上机实践编码,将设计的思路转换成C++语言编码,编译运行4.测试,输入不同的文法,观察运行结果详细的算法描述详细设计伪代码如下:首先要声明变量,然后定义各个函数1.void Initstack(charstack &s){//定义栈s.base=new charLode[20];s.top=-1; }2. void push(charstack&s,charLode w){//字符进栈s.top++;s.base[s.top].E=w.E;s.base[s.top].e=w.e;}3. void pop(charstack&s,charLode &w){//字符出栈w.E=s.base[s.top].E; 三、w.e=s.base[s.top].e;s.top--;}4. int IsEmpty(charstack s){//判断栈是否为空if(s.top==-1)return 1;else return 0;}5.int IsLetter(char ch){//判断是否为非终结符if(ch='A'&&ch= 'Z')return 1;else return 0;}6.int judge1(int n){ //judge1是判断是否是算符文法:若产生式中含有两个相继的非终结符则不是算符文法}7. void judge2(int n){//judge2是判断文法G是否为算符优先文法:若不是算符文法或若文法中含空字或终结符的优先级不唯一则不是算符优先文法8.int search1(char r[],int kk,char a){ //search1是查看存放终结符的数组r中是否含有重复的终结符}9.void createF(int n){ //createF函数是用F数组存放每个终结符与非终结符和组合,并且值每队的标志位为0;F数组是一个结构体}10.void search(charLode w){ //search函数是将在F数组中寻找到的终结符与非终结符对的标志位值为1 }分情况讨论://产生式的后选式的第一个字符就是终结符的情况//产生式的后选式的第一个字符是非终结符的情况11.void LastVT(int n){//求LastVT}12.void FirstVT(int n){//求FirstVT}13.void createYXB(int n){//构造优先表分情况讨论://优先级等于的情况,用1值表示等于}//优先级小于的情况,用2值表示小于//优先级大于的情况,用3值表示大于}14.int judge3(char s,char a){//judge3是用来返回在归约过程中两个非终结符相比较的值}15.void print(char s[],charSTR[][20],int q,int u,int ii,int k){//打印归约的过程}16. void process(char STR[][20],int ii){//对输入的字符串进行归约的过程}四、设计结果分两大类,四种不同的情况第一类情况:产生式的候选式以终结符开始候选式以终结符开始经过存在递归式的非终结符后再以终结符结束篇二:编译原理递归下降子程序北华航天工业学院《编译原理》课程实验报告课程实验题目:递归下降子程序实验作者所在系部:计算机科学与工程系作者所在专业:计算机科学与技术作者所在班级:xxxx作者学号:xxxxx_作者姓名:xxxx指导教师姓名:xxxxx完成时间:2011年3月28日一、实验目的通过本实验,了解递归下降预测分析的原理和过程以及可能存在的回溯问题,探讨解决方法,为预测分析表方法的学习奠定基础。
编译原理-编写递归下降语法分析器

学号107 成绩编译原理上机报告名称:编写递归下降语法分析器学院:信息与控制工程学院专业:计算机科学与技术班级:计算机1401班姓名:叶达成2016年10月31日一、上机目的通过设计、编制、调试一个递归下降语法分析程序,实现对词法分析程序所提供的单词序列进行语法检查和结构分析,掌握常用的语法分析方法。
通过本实验,应达到以下目标:1、掌握从源程序文件中读取有效字符的方法和产生源程序的内部表示文件的方法。
2、掌握词法分析的实现方法。
3、上机调试编出的词法分析程序。
二、基本原理和上机步骤递归下降分析程序实现思想简单易懂。
程序结构和语法产生式有直接的对应关系。
因为每个过程表示一个非终结符号的处理,添加语义加工工作比较方便。
递归下降分析程序的实现思想是:识别程序由一组子程序组成。
每个子程序对应于一个非终结符号。
每一个子程序的功能是:选择正确的右部,扫描完相应的字。
在右部中有非终结符号时,调用该非终结符号对应的子程序来完成。
自上向下分析过程中,如果带回溯,则分析过程是穷举所有可能的推导,看是否能推导出待检查的符号串。
分析速度慢。
而无回溯的自上向下分析技术,当选择某非终结符的产生时,可根据输入串的当前符号以及各产生式右部首符号而进行,效率高,且不易出错。
无回溯的自上向下分析技术可用的先决条件是:无左递归和无回溯。
无左递归:既没有直接左递归,也没有间接左递归。
无回溯:对于任一非终结符号U的产生式右部x1|x2|…|x n,其对应的字的首终结符号两两不相交。
如果一个文法不含回路(形如P⇒+ P的推导),也不含以ε为右部的产生式,那么可以通过执行消除文法左递归的算法消除文法的一切左递归(改写后的文法可能含有以ε为右部的产生式)。
三、上机结果测试数据:(1)输入一以#结束的符号串(包括+—*/()i#):在此位置输入符号串例如:i+i*i#(2)输出结果:i+i*i#为合法符号串(3)输入一符号串如i+i*#,要求输出为“非法的符号串”。
《递归下降分析法》实验报告

《编译原理》课程实验报告姓名:LZ学号:110地点:机房教师:老师院系:计通专业:计算机char scaner(char*input,int* p);void S(char*input,int* p);void T(char*input,int* p);void T1(char*input,int* p);void error();int sym=0;int main(){int p=0;char input[200]={0};printf("提示:单词只能由( ) a ^ , 组成,且单词必须以$#结尾\n"); printf("请输入你要识别的单词\n");return 0;}char scaner(char*input,int *p){char temp=input[*p];(*p)++;return temp;}void S(char*input,int* p) {if(sym=='a'||sym=='^')sym=scaner(input,p);{S(input,p);T1(input,p);return ;}void T1(char*input,int* p){if(sym==','){sym=scaner(input,p);S(input,p);T1(input,p);}else if(sym!=')')error();}void error(){printf("error!");return ;}三.实验步骤四.总结与回顾通过该实验的操作,我了解了语法分析器的内部工作原理,并掌握自上而下语法分析的要求与特点。
了解了每个函数的功能是识别由该终结符所表示的语法成分,通过在实验中运用一定的编程技巧,掌握对表达式进行处理的一种方法;在实验最后的调试中让我对该实验有了更全面的知识掌握,从中进步了不少。
编译原理之递归下降语法分析程序(实验)

编译原理之递归下降语法分析程序(实验)⼀、实验⽬的利⽤C语⾔编制递归下降分析程序,并对简单语⾔进⾏语法分析。
编制⼀个递归下降分析程序,实现对词法分析程序所提供的单词序列的语法检查和结构分析。
⼆、实验原理每个⾮终结符都对应⼀个⼦程序。
该⼦程序根据下⼀个输⼊符号(SELECT集)来确定按照哪⼀个产⽣式进⾏处理,再根据该产⽣式的右端:每遇到⼀个终结符,则判断当前读⼊的单词是否与该终结符相匹配,若匹配,再读取下⼀个单词继续分析;不匹配,则进⾏出错处理每遇到⼀个⾮终结符,则调⽤相应的⼦程序三、实验要求说明输⼊单词串,以“#”结束,如果是⽂法正确的句⼦,则输出成功信息,打印“success”,否则输出“error”,并指出语法错误的类型及位置。
例如:输⼊begin a:=9;b:=2;c:=a+b;b:=a+c end #输出success输⼊a:=9;b:=2;c:=a+b;b:=a+c end #输出‘end' error四、实验步骤1.待分析的语⾔的语法(参考P90)2.将其改为⽂法表⽰,⾄少包含–语句–条件–表达式E -> E+T | TT -> T*F | FF -> (E) | i3. 消除其左递归E -> TE'E' -> +TE' | εT -> FT'T' -> *FT' | εF -> (E) | i4. 提取公共左因⼦5. SELECT集计算SELECT(E->TE) =FIRST(TE')=FIRSI(T)-FIRST(F)U{*}={(, i, *}SELECT(E'->+TE')=FIRST(+TE')={+}SELECT(E'->ε)=follow(E')=follow(E)={#, )}SELECT(T -> FT')=FRIST(FT')=FIRST(F)={(, i}SELECT(T'->*FT')=FRIST(*FT')={*}SELECT(T'->ε)=follow(T')=follow(T)={#, ), +}SELECT(F->(E))=FRIST((E)) ={(}SELECT(F->i)=FRIST(i) ={i}6. LL(1)⽂法判断 其中SELECT(E'->+TE')与SELECT(E'->ε)互不相交,SELECT(T'->*FT')与SELECT(T'->ε)互不相交,SELECT(F->(E))与SELECT(F->i)互不相交,故原⽂法为LL(1)⽂法。
编译原理---递归下降分析法

编译原理---递归下降分析法所谓递归下降法 (recursive descent method),是指对⽂法的每⼀⾮终结符号,都根据相应产⽣式各候选式的结构,为其编写⼀个⼦程序 (或函数),⽤来识别该⾮终结符号所表⽰的语法范畴。
例如,对于产⽣式E′→+TE′,可写出相应的⼦程序如下:exprprime( ){if (match (PLUS)){advance( );term( );exprprime( );}}其中:函数match()的功能是,以其实参与当前正扫视的符号 (单词)进⾏匹配,若成功则回送true,否则回送false;函数advance()是⼀个读单词⼦程序,其功能是从输⼊单词串中读取下⼀个单词,并将它赋给变量Lookahead;term则是与⾮终结符号T相对应的⼦程序。
诸如上述这类⼦程序的全体,便组成了所需的⾃顶向下的语法分析程序。
应当指出,由于⼀个语⾔的各个语法范畴 (⾮终结符号)常常是按某种递归⽅式来定义的,此种特点也就决定了这组⼦程序必然以相互递归的⽅式进⾏调⽤,因此,在实现递归下降分析法时,应使⽤⽀持递归调⽤的语⾔来编写程序。
所以,通常也将上述⽅法称为递归⼦程序法。
例4 2对于如下的⽂法G[statements]:statements→expression; statements |εexpression→term expression′expression′→+term expression′ |εterm→factor term′term′→*factor term′ |εfactor→numorid | (expression)通过对其中各⾮终结符号求出相应的FIRST集和FOLLOW集 (计算FIRST集和FOLLOW集的⽅法后⾯再做介绍),可以验证,此⽂法为⼀LL(1)⽂法,故可写出递归下降语法分析程序如程序41所⽰(其中,在⽂件lex.h⾥,将分号、加号、乘号、左括号、右括号、输⼊结束符及运算对象分别命名为SEMI,PLUS,TIMES,LP,RP,EOI及NUMORID,并指定了它们的内部码;此外,还对外部变量yytext,yyleng及yylineno进⾏了说明)。
递归下降程序实验报告

一、实验目的1. 理解递归下降分析法的原理和实现方法。
2. 掌握递归下降分析程序的设计和调试。
3. 加深对编译原理中语法分析部分的理解。
二、实验环境1. 操作系统:Windows 102. 编程语言:C++3. 开发环境:Visual Studio 2019三、实验内容1. 递归下降分析法原理介绍2. 递归下降分析程序的设计与实现3. 递归下降分析程序的调试与测试四、实验步骤1. 递归下降分析法原理介绍递归下降分析法是一种自顶向下的语法分析方法,它将文法中的非终结符对应为分析过程中的递归子程序。
当遇到一个非终结符时,程序将调用对应的递归子程序,直到处理完整个输入串。
2. 递归下降分析程序的设计与实现(1)定义文法以一个简单的算术表达式文法为例,文法如下:E -> E + T| TT -> T F| FF -> ( E )| id(2)消除左递归由于文法中存在左递归,我们需要对其进行消除,消除后的文法如下:E -> T + E'E' -> + T E' | εT -> F T'T' -> F T' | εF -> ( E ) | id(3)设计递归下降分析程序根据消除左递归后的文法,设计递归下降分析程序如下:```cpp#include <iostream>#include <string>using namespace std;// 定义终结符const char PLUS = '+';const char MUL = '';const char LPAREN = '(';const char RPAREN = ')';const char ID = 'i'; // 假设id为'i'// 分析器状态int index = 0;string input;// 非终结符E的分析程序void E() {T();while (input[index] == PLUS) {index++;T();}}// 非终结符T的分析程序void T() {F();while (input[index] == MUL) {index++;F();}}// 非终结符F的分析程序void F() {if (input[index] == LPAREN) {index++; // 跳过左括号E();if (input[index] != RPAREN) {cout << "Error: Missing right parenthesis" << endl; return;}index++; // 跳过右括号} else if (input[index] == ID) {index++; // 跳过标识符} else {cout << "Error: Invalid character" << endl;return;}}// 主函数int main() {cout << "Enter an arithmetic expression: ";cin >> input;index = 0; // 初始化分析器状态E();if (index == input.size()) {cout << "The expression is valid." << endl;} else {cout << "The expression is invalid." << endl;}return 0;}```3. 递归下降分析程序的调试与测试将以上代码编译并运行,输入以下表达式进行测试:```2 +3 (4 - 5) / 6```程序输出结果为:```The expression is valid.```五、实验总结通过本次实验,我们了解了递归下降分析法的原理和实现方法,掌握了递归下降分析程序的设计与调试。
递归下降分析实验报告

一、实验目的通过本次实验,加深对递归下降分析法的理解,掌握递归下降分析法的原理和应用,并能够根据给定的文法编写相应的递归下降分析程序。
二、实验原理递归下降分析法是一种自顶向下的语法分析方法,它将文法中的每个非终结符对应一个递归过程(函数),分析过程就是从文法开始符触发执行一组递归过程(函数),向下推到直到推出句子。
递归下降分析法的前提是文法应满足以下条件:1. 消除二义性:确保文法中每个产生式都只有一个确定的意义。
2. 消除左递归:避免产生式出现如A -> A...A的形式。
3. 提取左因子:将产生式中的左因子提取出来,避免出现左递归。
4. 判断是否为LL(1)文法:LL(1)文法是指文法满足左递归和右递归的文法。
三、实验内容1. 根据给定的文法编写递归下降分析程序。
2. 对输入的符号串进行分析,判断其是否属于该文法。
3. 输出分析过程和结果。
四、实验步骤1. 阅读相关资料,了解递归下降分析法的原理和应用。
2. 根据给定的文法,设计递归下降分析程序的结构。
3. 编写递归下降分析程序,实现分析过程。
4. 编写测试用例,验证递归下降分析程序的正确性。
5. 分析实验结果,总结实验经验。
五、实验结果与分析1. 实验结果根据给定的文法,编写了递归下降分析程序,并进行了测试。
以下为部分测试用例及结果:(1)输入:eBaA输出:分析成功,属于该文法。
(2)输入:abAcB输出:分析成功,属于该文法。
(3)输入:dEdaC输出:分析成功,属于该文法。
(4)输入:edc输出:分析成功,属于该文法。
2. 实验分析通过本次实验,我们深入了解了递归下降分析法的原理和应用。
在编写递归下降分析程序的过程中,我们学会了如何根据文法设计程序结构,以及如何实现分析过程。
同时,我们还掌握了如何对输入的符号串进行分析,并输出分析结果。
实验过程中,我们遇到了一些问题,如消除二义性、消除左递归、提取左因子等。
通过查阅资料和不断尝试,我们成功解决了这些问题。
编译原理实验(递归向下语法分析法实验)

//定义一个数组大小常量
char string[N];
//定义一个用于存储算式字符串的数组
char *p;
//定义一个全局字符指针变量
函数说明:
1) 非终结符函数 E()
函数功能描述:根据以上文法要求 E->TG,所以从主函数开始调入第一个非终结符函数
执行,显示调用产生式,依次嵌套调用非终结符函数 T()和 G(),进行递归向下分析。
void E(){printf("E--->TG..............%c\n",ch);
T();
G();}
2) 非终结符函数 T()
函数功能描述:根据以上文法要求 T->FS,首先显示算式匹配所用的显示调用的产生式,
依次嵌套调用非终结符函数 F()和 S(),进行递归向下分析。
void T(){
(3)G->ε
(4)T->FS
(5)S->*FS| / FS
(6)S->ε
(7)F->(E)
(8)F->i
输入出的格式如下:
(1)E 盘建立一个文本文档" 222.txt"存储一个以#结束的符号串(包括+—*/()i#),在此
位置输入符号串例如:i+i*i#
(2)输出结果:i+i*i#为合法符号串
备注:输入一符号串如 i+i*#,要求输出为“非法的符号串”
此法分析,通过实验我对本章的语法分析也有了深刻的认识。同时通过本次编程,让我深刻
认识编程应该注重细节,编程之前首先要做好分析准备。
五、程序源代码
#include<stdio.h>
#include<stdlib.h>
编译原理实验递归下降分析器的设计(含源代码和运行结果)

《编译原理》实验报告实验3 递归下降分析器的设计姓名学号班级计科1001班时间: 2012/4/15 地点:文波同组人:无指导教师:朱少林实验目的使用递归子程序法设计一个语法分析程序,理解自顶向下分析方法的原理,掌握手工编写递归下降语法分析程序的方法。
实验内容a.运用所学知识,编程实现递归下降语法分析程序。
使用递归下降分析算法分析表达式是否符合下文法:exp → exp addop term | termAddop →+ | -term→ term mulop factor | factormulop → * | /factor → (exp) | id | number其中number可以是多位的十进制数字串(整数即可),因此这里还需要一个小的词法分析器来得到id 和number的值。
b.从数据文件中读出符号串,输出表达式并给出其正误评判。
实验数据文件中应该有多个表达式,可能有正确的也应该有错误的表达式;表达式有形式简单的也应该有复杂的。
每个表达式写在一行,以回车结束。
实验环境软件:VC++6.0实验前准备1、方案设计:①准备模拟数据:本实验中使用“work..cpp”②程序思想:为了使用递归向下的分析,为每个非终结符根据其产生式写一个分析程序,由于写入读出的操作频繁。
所以程序中还有一个match(char t)函数,该函数是将字符写入文件打印输出同时从文件中读取下一个字符,而由于id和number可能是多个字符构成,故写了number()和id()来分析数字和标识符,它们的功能仅仅是把整个number或id完整的读取出来并写入文件,打印输出。
由于分析的文件中可能出现非法字符,而一旦发现非法字符就无需再接着分析,所以在每次读取一个字符时调用islegal函数判断是否是合法字符,并返回0或1.在main()函数中,while((lookahead=='\n'||lookahead==' ')&&lookahead!=EOF) fscanf(resource,"%c",&lookahead);是为了忽略分析文件中的换行或空格,之后进入分析阶段,根据返回值判断是否是合法的表达式。
编译原理递归下降分析器 C语言

数学与软件科学学院实验报告学期:2015至2016第2学期2016年3月21日课程名称:编译原理专业:信息与计算科学2013级5班实验编号:2实验名称:递归下降分析器指导教师:王开端姓名:李丹学号:2013060510实验成绩:实验二递归下降分析器实验目的:通过设计、编制、调试递归下降语法分析程序,对输入的符号串进行分析匹配,观察输入符号串是否为给定文法的句子。
实验内容:根据文法G[E]设计递归下降分析器并分析输入串)(*321i i i +是否为文法的句子。
G[E]:E→E+T|TT→T*F|F F→(E)|i实验步骤:在进行递归下降分析法之前,必须对文法进行左递归和回溯的消除。
1消除左递归直接消除见诸于产生式中的左递归比较容易,其方法是引入一个新的非终结符,把含有左递归的产生式改为右递归。
文法G[E]经过消去直接左递归后得到文法G’[E]为:G’[E]:iE F FT T FT T TE E TE E |)(|'*''|'''→→→+→→εε2消除回溯回溯发生的原因在于候选式存在公共的左因子。
一般情况下,设文法中关于A 的产生式为ji i A ββδβδβδβ|...|||...||121+→,那么,可以把这些产生式改写为⎩⎨⎧→→+ij i A A A ββββδ|...|'|...||'11经过反复提取左因子,就能把每个非终结符(包括新引进者)的所有候选首字符集变为两两不相交(既不含有公共左因子)。
3什么是递归下降分析法递归下降分析法是一种自顶向下的分析方法,文法的每个非终结符对应一个递归过程(函数)。
分析过程就是从文法开始符出发执行一组递归过程(函数),这样向下推导直到推出句子;或者说从根节点出发,自顶向下为输入串寻找一个最左匹配序列,建立一棵语法树。
在不含左递归和每个非终结符的所有候选终结首字符集都两两不相交条件下,我们就可能构造出一个不带回溯的自顶向下的分析程序,这个分析程序是由一组递归过程(或函数)组成的,每个过程(或函数)对应文法的而一个非终结符。
递归下降分析器程序(c语言版,编译原理实验)

递归下降分析器设计1、实验目的:(1)掌握自上而下语法分析的要求与特点。
(2)掌握递归下降语法分析的基本原理和方法。
(3)掌握相应数据结构的设计方法。
2、实验内容:编程实现给定算术表达式的递归下降分析器。
算术表达式文法如下:E-->E+T|TT-->T*F|FF-->(E)|i3、设计说明:首先改写文法为LL(1)文法;然后为每一个非终结符,构造相应的递归过程,过程的名字表示规则左部的非终结符;过程体按规则右部符号串的顺序编写。
4、设计分析这个题目属于比较典型的递归下降语法分析。
需要先将原算术表达式方法改写为LL(1)文法为:E-->TE'E'-->+TE'|εT-->FT'T'-->*FT'|εF-->(E)|i然后再为每个非终结符设计一个对应的函数,通过各函数之间的递归调用从而实现递归下降语法分析的功能。
具体方法为:(1)当遇到终结符a时,则编写语句If(当前读到的输入符号==a)读入下一个输入符号(2)当遇到非终结符A时,则编写语句调用A()。
(3)当遇到A-->ε规则时,则编写语句If(当前读到的输入符号不属于Follow(A))error()(4)当某个非终结符的规则有多个候选式时,按LL(1)文法的条件能唯一地选择一个候选式进行推导.#include<stdio.h>void E();void T();void E1();void T1();void F();char s[100];int i, SIGN;int main(){printf("请输入一个语句,以#号结束语句(直接输入#号推出)\n");while( 1 ){SIGN = 0;i=0;scanf("%s",&s);if( s[0] == '#')return 0;E();if(s[i]=='#')printf("正确语句!\n");printf("请输入一个语句,以#号结束语句\n");}return 1;}void E(){if(SIGN==0){T();E1();}}void E1(){if(SIGN==0){if(s[i]=='+'){++i;T();E1();}else if(s[i]!='#'&&s[i]!=')'){printf("语句有误!\n");SIGN=1;}}}void T(){if(SIGN==0){F();T1();}}void T1(){if(SIGN==0){if(s[i]=='*'){++i;F();T1();}else if(s[i]!='#'&&s[i]!=')'&&s[i]!='+'){printf("语句有误!\n");SIGN=1;}}}void F(){if(SIGN==0){if(s[i]=='('){++i;E();if(s[i]==')')++i;else if(s[i]== '#'){printf("语句有误!\n");SIGN=1;++i;}}else if(s[i]=='i')++i;else{printf("语句有误!\n");SIGN=1;}}}测试用例(1)输入i,预期显示语句正确!(2)输入iii,预期显示语句有误!(3)输入a,预期显示语句有误!(4)输入(i),预期显示语句正确!(5)输入(a),预期显示语句有误!(6)输入(i+i),预期显示语句正确!(7)输入(i+i,预期显示语句有误!(8)输入((i*i)+i)*i,预期显示语句正确!(9)输入((((i+i*i)))),预期显示语句正确!(10)输入(i+ia,预期显示语句有误!(11)输入i+i*i+i*a,预期显示语句有误!。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验4《递归下降分析法设计与实现》实验学时: 2 实验地点:实验日期:一、实验目的根据某一文法编制调试递归下降分析程序,以便对任意输入的符号串进行分析。
本次实验的目的主要是加深对递归下降分析法的理解。
二、实验内容程序输入/输出示例(以下仅供参考):对下列文法,用递归下降分析法对任意输入的符号串进行分析:(1)E-TG(2)G-+TG|—TG(3)G-ε(4)T-FS(5)S-*FS|/FS(6)S-ε(7)F-(E)(8)F-i输出的格式如下:(3)备注:输入一符号串如i+i*#,要求输出为“非法的符号串”。
注意:1.表达式中允许使用运算符(+-*/)、分割符(括号)、字符I,结束符#;2.如果遇到错误的表达式,应输出错误提示信息(该信息越详细越好)。
三、实验方法用C语言,根据递归下降分析法的规则编写代码,并测试。
四、实验步骤1.对语法规则有明确的定义;2.编写的分析程序能够对实验一的结果进行正确的语法分析;3.对于遇到的语法错误,能够做出简单的错误处理,给出简单的错误提示,保证顺利完成语法分析过程;五、实验结果六、实验结论#include<stdio.h>#include<dos.h>#include<stdlib.h>#include<string.h>char a[50],b[50],d[200],e[10];char ch;int numOfEq,i1=0,flag=1,n=6;int E();int E1();int T();int G();int S();int F();void input();void input1();void output();//================================================ void main()/*递归分析*/{ int foe1,i=0;char x;d[0]='E';d[1]='=';d[2]='>';d[3]='?';d[4]='T';d[5]='G';d[6]='#';printf("请输入字符串(以#号结束)\n");do{ scanf("%c",&ch);a[i]=ch;i++;}while(ch!='#');numOfEq=i;ch=b[0]=a[0];printf("文法\t分析串\t\t分析字符\t剩余串\n");if (foe1==0) return;if (ch=='#'){ printf("accept\n");i=0;x=d[i];while(x!='#'){ printf("%c",x);i=i+1;x=d[i];/*输出推导式*/}printf("\n");}else{ printf("error\n");printf("回车返回\n");getchar();getchar();return;}}//================================================ int E1(){ int fot,fog;printf("E->TG\t");flag=1;input();input1();fot=T();if (fot==0) return(0);fog=G();if (fog==0) return(0);else return(1); }//================================================ int E(){ int fot,fog;printf("E->TG\t");e[0]='E';e[1]='=';e[2]='>';e[3]='?';e[4]='T';e[6]='#';output();flag=1;input();input1();fot=T();if (fot==0) return(0);fog=G();if (fog==0) return(0);else return(1); }//================================================ int T(){ int fof,fos;printf("T->FS\t");e[0]='T';e[1]='=';e[2]='>';e[3]='?';e[4]='F';e[5]='S';e[6]='#';output();flag=1;input();input1();fof=F();if (fof==0) return(0);fos=S();if (fos==0) return(0);else return(1); }//================================================ int G(){ int fot;if(ch=='+'){ b[i1]=ch;printf("G->+TG\t");e[0]='G';e[2]='>';e[3]='?';e[4]='+';e[5]='T';e[6]='G';e[7]='#';output();flag=0;input();input1();ch=a[++i1];fot=T();if (fot==0) return(0); G();return(1);}else if(ch=='-'){ b[i1]=ch;printf("G->-TG\t"); e[0]='G';e[1]='=';e[2]='>';e[3]='?';e[4]='-';e[5]='T';e[6]='G';e[7]='#';output();flag=0;input();input1();ch=a[++i1];fot=T();if (fot==0) return(0); G();return(1); }printf("G->^\t");e[1]='=';e[2]='>';e[3]='?';e[4]='^';e[5]='#';output();flag=1;input();input1();return(1);}//================================================ int S(){ int fof,fos;if(ch=='*'){ b[i1]=ch;printf("S->*FS\t");e[0]='S';e[1]='=';e[2]='>';e[3]='?';e[4]='*';e[5]='F';e[6]='S';e[7]='#'; output();flag=0;input();input1();ch=a[++i1];fof=F();if (fof==0)return(0);fos=S();if (fos==0) return(0);else return(1); }else if(ch=='/'){ b[i1]=ch;printf("S->/FS\t");e[0]='S';e[1]='=';e[2]='>';e[3]='?';e[4]='/';e[5]='F';e[6]='S';e[7]='#'; output();flag=0;input();input1();ch=a[++i1];fof=F();if (fof==0) return(0);fos=S();if (fos==0) return(0);else return(1); }printf("S->^\t");e[0]='S';e[1]='=';e[2]='>';e[3]='?';e[4]='^';e[5]='#';output();flag=1;a[i1]=ch;input();input1();return(1); }//================================================ int F(){int f;if(ch=='('){ b[i1]=ch;printf("F->(E)\t");e[0]='F';e[1]='=';e[2]='>';e[3]='?';e[3]='(';e[4]='E';e[5]=')';e[7]='#'; output();flag=0;input();input1();ch=a[++i1];f=E();if (f==0) return(0); if(ch==')'){ b[i1]=ch;printf("F--(E)\t");flag=0;input();input1();ch=a[++i1]; }else{ printf("error\n");return(0);}}else if(ch=='i'){b[i1]=ch;printf("F->i\t");e[0]='F';e[1]='=';e[2]='>';e[3]='?';e[4]='i';e[5]='#';output();flag=0;input();input1();ch=a[++i1];}else{printf("error\n");return(0);}return(1);}//================================================ void input(){ int i=0;for (;i<=i1-flag;i++)printf("%c",b[i]);/*输出分析串*/printf("\t\t");printf("%c\t\t",ch);/*输出分析字符*/}//================================================ void input1(){ int i;for (i=i1+1-flag;i<numOfEq;i++)printf("%c",a[i]);/*输出剩余字符*/printf("\n");}//================================================ void output(){/*推导式计算*/int m,k,j,q;int i=0;m=0;k=0;q=0;i=n;d[n]='=';d[n+1]='>';d[n+2]='?';d[n+3]='#';n=n+3;i=n;i=i-2;while(d[i]!='?'&&i!=0)i--;i=i+1;while(d[i]!=e[0])i=i+1;q=i;m=q;k=q;while(d[m]!='?')m=m-1;m=m+1;while(m!=q){d[n]=d[m];m=m+1;n=n+1;}d[n]='#';for(j=3;e[j]!='#';j++){d[n]=e[j];n=n+1;}k=k+1;while(d[k]!='='){d[n]=d[k];n=n+1;k=k+1;}d[n]='#';}七、实验小结通过本次试验实践掌握了自上而下语法分析法的特点。