编译原理课程设计---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. 学生能理解递归下降分析法的概念和原理;2. 学生能掌握递归下降分析法在语法分析中的应用;3. 学生能了解递归下降分析法与其它语法分析方法的区别和联系。

技能目标:1. 学生能运用递归下降分析法对简单程序设计语言的语法进行分析;2. 学生能通过递归下降分析法编写简单的语法分析程序;3. 学生能通过案例分析和团队合作,解决递归下降分析过程中的问题。

情感态度价值观目标:1. 学生对程序设计语言的学习产生兴趣,增强学习积极性;2. 学生在递归下降分析法的实践过程中,培养解决问题的能力和团队协作精神;3. 学生通过递归下降分析法的学习,认识到程序设计语言在计算机科学中的重要性。

课程性质:本课程为计算机科学领域的一门专业课程,旨在让学生掌握递归下降分析法的基本原理和应用。

学生特点:学生具备一定的程序设计基础,对语法分析有一定了解,但可能对递归下降分析法较为陌生。

教学要求:结合学生的特点,采用案例教学、团队合作等方式,使学生能够将递归下降分析法应用于实际语法分析中,提高学生的实践能力和理论知识水平。

在教学过程中,注重引导学生积极思考,培养学生的问题解决能力和创新意识。

通过本课程的学习,使学生在知识、技能和情感态度价值观方面取得具体的学习成果。

二、教学内容1. 引言:介绍语法分析在程序设计语言中的作用,引出递归下降分析法的重要性。

2. 递归下降分析法基本原理:- 语法分析的基本概念;- 递归下降分析法的定义;- 递归下降分析法的工作流程。

3. 递归下降分析法的应用:- 简单程序设计语言的语法分析;- 递归下降分析法的具体实现步骤;- 递归下降分析法在实际案例中的应用。

4. 递归下降分析法与其它语法分析方法的比较:- LL分析法;- LR分析法;- 与递归下降分析法的区别和联系。

5. 实践环节:- 编写简单的递归下降分析程序;- 分析和讨论递归下降分析过程中的问题;- 团队合作完成复杂语法分析任务。

(完整)编译原理课程设计 LL(1)递归下降分析器

(完整)编译原理课程设计 LL(1)递归下降分析器

(完整)编译原理课程设计 LL(1)递归下降分析器编辑整理:尊敬的读者朋友们:这里是精品文档编辑中心,本文档内容是由我和我的同事精心编辑整理后发布的,发布之前我们对文中内容进行仔细校对,但是难免会有疏漏的地方,但是任然希望((完整)编译原理课程设计LL(1)递归下降分析器)的内容能够给您的工作和学习带来便利。

同时也真诚的希望收到您的建议和反馈,这将是我们进步的源泉,前进的动力。

本文可编辑可修改,如果觉得对您有帮助请收藏以便随时查阅,最后祝您生活愉快业绩进步,以下为(完整)编译原理课程设计 LL(1)递归下降分析器的全部内容。

仲恺农业技术学院编译原理课程设计课程设计题目:LL(1)递归下降分析器姓名:院(系):专业班级:学号 :指导教师:设计日期:目录1、需求分析 (1)2、概要设计 (2)3、详细设计 (3)4、测试分析 (8)5、用户手册 (9)6、课程总结 (9)7、参考文献 (10)题目:LL(1)递归下降分析器1、需求分析语法分析是编译过程的核心部分。

语法分析器的任务是识别和处理比单词更大的语法单位。

如:程序设计语言中的表达式,各种说明和语句乃至全部源程序,指我们知道,语言的语法结构是用上下文无关文法描述的.按照语法分析树的建立方法,我们可以粗略地把语法分析办法分成两类,一类是自上而下分析,另一类是自下而上分析法。

而自上而下这种方法是带“回溯”的,且存在许多困难和缺点.首先,是文法的左递归性问题。

一个文法是含有左递归的,如果存在非终结符P 且,含有左递归的文法使上述的自上而下的分析过程陷入无限循环。

即,当试图用P 去匹配输入串时,我们会发现,在没有识别任何输入符号的情况下,有得重新要求P 去进行新的匹配。

因此,使用自上而下分析法必须消除文法的左递归性.其次,由于回溯,就碰到一大堆麻烦问题。

如果我们走了一大段错路,最后必须回头,那么,就应把已经做的一大堆语义工作(指中间代码产生工作和各种表格的簿记工作)推倒重来.这些事情既麻烦又费时间,所以,最好应设法消除回溯.第三,在自上而下分析过程中,当一个非终结符用某一候选匹配成功时,这种成功可能仅是暂时的。

编译原理_实验二_语法分析_递归下降分析器设计_实验报告

编译原理_实验二_语法分析_递归下降分析器设计_实验报告

递归下降分析器设计一、实验/实习过程内容:利用JavaCC生成一个MiniC的语法分析器;要求:1. 用流的形式读入要分析的C语言程序,或者通过命令行输入源程序。

2. 具有错误检查的能力,如果有能力可以输出错误所在的行号,并简单提示3. 如果输入的源程序符合MiniC的语法规范,输出该程序的层次结构的语法树具体实施步骤如下:1.把MiniC转换为文法如下<程序〉→ main()〈语句块〉〈语句块〉→{〈语句串〉}〈语句串〉→〈语句〉〈语句串〉|〈语句〉〈语句〉→〈赋值语句〉|〈条件语句〉|〈循环语句〉〈赋值语句〉→ ID =〈表达式〉;〈条件语句〉→ if〈条件〉〈语句块〉〈循环语句〉→ while〈条件〉〈语句块〉〈条件〉→(〈表达式〉〈关系符〉〈表达式〉)〈表达式〉→〈表达式〉〈运算符〉〈表达式〉|(〈表达式〉)|ID|NUM〈运算符〉→+|-|*|/〈关系符〉→<|<=|>|>=|==|!=2.消除语句中的回溯与左递归3.在eclipse环境下完成JavaCC的插件安装后,写一个JavaCC文法规范文件(扩展名为jj)4.完成的功能包括词法分析,语法分析二、代码:options {JDK_VERSION = "1.5";}PARSER_BEGIN(eg1)public class eg1 {public static void main(String args[]) throws ParseException { eg1 parser = new eg1(System.in);parser.start();}}PARSER_END(eg1)SKIP :{" "| "\r"| "\t"| "\n"}TOKEN : /* OPERATORS */{< PLUS: "+" >| < MINUS: "-" >| < MULTIPLY: "*" >| < DIVIDE: "/" >}TOKEN :{<BIGGER:">"> |<SMALLER:"<"> |<NOTVOLUTION:"!="> |<SMALLEREQDD:"<="> |<BIGGEREE:">=" > |<DOUBLE:"==">TOKEN: //关键字{<MAIN:"main"> |<VOID:"void"> |<IF:"if"> |<INT:"int"> | <WHILE:"while"> |<CHAR:"char"> | <VOLUTION:"="> }TOKEN : //定义整型数{< INTEGER: ["0" - "9"]( <DIGIT> )+ >| < #DIGIT: ["0" - "9"] >}TOKEN : //数字{<NUMBER:(<DIGIT>)+ | (<DIGIT>)+"."| (<DIGIT>)+"."(<DIGIT>)+| "."(<DIGIT>)+>}TOKEN : //标记{<COMMA:","> | <SEMICOLON:";"> | <COLON:":"> | <LEFTPARENTHESES:"("> |<RIGHTPARENTHESES:")"> | <LEFTBRACE:"{"> | <RIGHTBRACE:"}"> }TOKEN : //标识符{<IDENTIFIER:<LETTER> |<LETTER>(<LETTER> | <DIGIT> )* >|<#LETTER:["a"-"z", "A"-"Z"]>}void start():{}{<MAIN> <LEFTPARENTHESES> <RIGHTPARENTHESES> block() }void block():{}{<LEFTBRACE> string() <RIGHTBRACE>}void string():{}{yuju() (string())?}void yuju():{}{fuzhiyuju() | tiaojianyuju() | xunhuanyuju()}void fuzhiyuju():{}{<IDENTIFIER> <VOLUTION> biaodashi() <SEMICOLON>}void tiaojianyuju():{}{<IF> tiaojian() block()}void xunhuanyuju():{}<WHILE> tiaojian() block()}void tiaojian():{}{<LEFTPARENTHESES> biaodashi() guanxifu() biaodashi()<RIGHTPARENTHESES>}void biaodashi():{}{( <LEFTPARENTHESES> biaodashi() <RIGHTPARENTHESES> biaodashi2()) |(<IDENTIFIER> biaodashi2() ) | ( <NUMBER> biaodashi2() )}void biaodashi2():{}{(yunsuanfu() biaodashi() biaodashi2() )?}void yunsuanfu():{}{< PLUS > | < MINUS > |< MULTIPLY> | < DIVIDE >}void guanxifu() :{}{<BIGGER> | <SMALLER> | <NOTVOLUTION><SMALLEREQDD> | <BIGGEREE> | <DOUBLE>}三、实验/实习总结本次实习,我使用javacc完成了包括词法分析,语法分析(输出语法树),能够读文件的功能,总的来说比较满意,通过本次实习掌握了javacc基本的使用。

编译原理-实验报告2-递归下降分析法

编译原理-实验报告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输出的格式如下:(1)递归下降分析程序,编制人:姓名,学号,班级(2)输入一以#结束的符号串(包括+—*/()i#):在此位置输入符号串例如:i+i*i#(3)输出结果:i+i*i#为合法符号串备注:输入一符号串如i+i*#,要求输出为“非法的符号串”。

注意:1.表达式中允许使用运算符(+-*/)、分割符(括号)、字符i,结束符#;2.如果遇到错误的表达式,应输出错误提示信息(该信息越详细越好);三、实验过程:程序设计:1.模块设计:将程序分成合理的多个模块(函数),每个模块做具体的同一事情。

2.写出(画出)设计方案:模块关系简图、流程图、全局变量、函数接口等。

程序编写:1.定义部分:定义常量、变量、数据结构。

2.初始化:从文件将输入符号串输入到字符缓冲区中。

3.利用递归下降分析法,对每个非终结符编写函数,在主函数中调用文法开始符号的函数。

四、实验结果(1)程序流程图(2)运行结果示例程序:#include <>#include<>#include<>#include<>char a[50] ,b[50],d[500],e[10];char ch;int n1,i1=0,flag=1,n=5;int E();int E1();int T();int G();int S();int F();void input();void input1();void output();void main() /*递归分析*/{int f,p,j=0;char x;d[0]='E';d[1]='=';d[2]='>';d[3]='T';d[4]='G';d[5]='#';printf("递归下降分析程序,编制人:武普泉,20号,1020562班\n");printf("输入一以#结束的符号串(包括+ - * / ( ) i #,且长度小于50):");do{scanf("%c",&ch);a[j]=ch;j++;}while(ch!='#');n1=j;ch=b[0]=a[0];printf("文法\t分析串\t\t\t分析字符\t\t剩余串\n");f=E1();if(f==0) return ;if (ch=='#'){ printf("accept\n");p=0;x=d[p];// {// printf("%c",x);p=p+1;x=d[p]; /*输出推导式*/ // }while(a[p]!='#')printf("%c",a[p++]);printf("为合法字符!\n");}else {// printf("error\n");j=0;while(a[j]!='#')printf("%c",a[j++]);printf("非法字符!\n");printf("回车返回\n");getchar();getchar();return;}printf("\n");printf("回车返回\n");getchar();getchar();}int E1(){ int f,t;printf("E-->TG\t");flag=1;input();input1();f=T();if (f==0) return(0);t=G();if (t==0) return(0);else return(1);}int E(){ int f,t;printf("E-->TG\t");e[0]='E';e[1]='=';e[2]='>';e[3]='T';e[4]='G';e[5]='#';output();flag=1;input();input1();f=T();if (f==0)return(0);t=G();if (t==0) return(0);else return(1);}int T(){ int f,t;printf("T-->FS\t");e[0]='T';e[1]='=';e[2]='>';e[3]='F';e[4]='S';e[5]='#';output();flag=1;input();input1();f=F();if (f==0)return(0);t=S();if (t==0) return(0);else return(1);}int G(){int f;if(ch=='+'){b[i1]=ch;printf("G-->+TG\t");e[0]='G';e[1]='=';e[2]='>';e[3]='+';e[4]='T';e[5]='G';e[6]='#';output();flag=0;input();input1();ch=a[++i1];f=T();if (f==0)return(0);f=G();if(f==0)return 0;else return 1;}else if(ch=='-'){b[i1]=ch;printf("G-->-TG\t");e[0]='G';e[1]='=';e[2]='>';e[3]='-';e[4]='T';e[5]='G';e[6]='#';output();flag=0;input();input1();ch=a[++i1];f=T();if (f==0){// printf("G=%d\n",f);return(0);}f=G();if(f==0)return 0;else return 1;}else{printf("G-->^\t");e[0]='G';e[1]='=';e[2]='>';e[3]='^';e[4]='#';output();flag=1;input();input1();return(1);}}int S(){int f,t;if(ch=='*'){b[i1]=ch;printf("S-->*FS\t");e[0]='S';e[1]='=';e[2]='>';e[3]='*';e[4]='F';e[5]='S';e[6]='#';output();flag=0;input();input1();ch=a[++i1];f=F();if (f==0)return(0);t=S();if (t==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]='F';e[5]='S';e[6]='#';output();flag=0;input();input1();ch=a[++i1];f=F();if (f==0)return(0);t=S();if (t==0)return(0);else return(1);}else{printf("S-->^\t");e[0]='S';e[1]='=';e[2]='>';e[3]='^';e[4]='#';output();flag=1;a[i1]=ch;input();input1();return(1);}}int F(){ int f;int j;if(ch=='('){b[i1]=ch;printf("F-->(E)\t");e[0]='F';e[1]='=';e[2]='>';e[3]='(';e[4]='E';e[5]=')';e[6]='#';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");j=0;while(a[j]!='#')printf("%c",a[j++]);printf("非法字符!\n");return(0);}}else if(ch=='i'){b[i1]=ch;printf("F-->i\t");e[0]='F';e[1]='=';e[2]='>';e[3]='i';e[4]='#';output();flag=0;input();input1();ch=a[++i1];}else {printf("error\n");j=0;while(a[j]!='#')printf("%c",a[j++]);printf("非法字符!\n");return(0);}return(1);}void input(){int j=0;for (;j<=i1-flag;j++)printf("%c",b[j]); /*输出分析串*/printf("\t\t\t");printf("%c\t\t\t",ch); /*输出分析字符*/ }void input1(){int j;for (j=i1+1-flag;j<n1;j++)printf("%c",a[j]); /*输出剩余字符*/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]='#';n=n+2;i=n;i=i-2;while(d[i]!='>'&&i!=0) i=i-1;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]='#';}。

递归下降分析器的设计

递归下降分析器的设计

河北大学工商学院编译原理实验报告年级09级学号姓名成绩专业计算机科学与技术实验地点B3-216 指导教师李凯实验项目递归下降分析器的设计实验日期2012/5/14实验报告要求:一、实验目的1. 实验目的使用递归子程序法设计一个语法分析程序,理解自顶向下分析方法的原理,掌握手工编写语法分析程序的方法。

2.了解什么是LL(1)文法的,以及如何把一个非ll(1)的文法转化为非ll(1)型文法,深入了解如何根据ll(1)文法编写递归子程序,实现语法的检查。

3.深入了解编译程序语法分析的过程。

二、实验原理1. 基本原理递归下降法是语法分析中最易懂的一种方法。

它的主要原理是,对每个非终极符按其产生式结构构造相应语法分析子程序,其中终极符产生匹配命令,而非终极符则产生过程调用命令。

因为文法递归相应子程序也递归,所以称这种方法为递归子程序下降法或递归下降法。

其中子程序的结构与产生式结构几乎是一致的。

2. 文法要求递归下降法要满足的条件:假设 A 的全部产生式为A α1|α2|……|αn ,则必须满足如下条件才能保证可以唯一的选择合适的产生式Select(A-> αi)∩select(A ->αj)=Φ,当i≠j,即要求文法必需满足ll(1)文法。

3.开发工具要求本程序使用C语言写的,要求掌握C语言的基本语法和语义,特别是关于程序递归调用的要求。

4.文法的BNF式:E->EaT|T;T->TbF|FF->(E)|da:=+|-b:=*|/消除左递归之后的文法E->TE’E’->aTE’|εT->bFT’|εT’->bFT’F->(E)|da:=+|-b:=*|/三、实验要求【目的】使用递归子程序法设计一个语法分析程序,理解自顶向下分析方法的原理,掌握手工编写语法分析程序的方法。

【要求】1、使用递归下降分析算法分析表达式文法:exp ::= exp addop term | termaddop ::= + | -term ::= term mulop factor | factormulop ::= * | /factor ::= (exp) | number其中number可以是多位的十进制数字串(整数即可),因此这里还需要一个小的词法分析器来得到number的值。

编译原理---递归下降分析法

编译原理---递归下降分析法

编译原理---递归下降分析法所谓递归下降法 (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)

编译原理实验报告二递归下降语法分析程序 (1)

编译原理实验报告实验名称:编写递归下降语法分析程序实验类型:验证型实验指导教师:专业班级:姓名:学号:电子邮件:实验地点:实验成绩:日期:201 年 5 月 25 日一、实验目的通过设计、调试递归下降语法分析程序,实现用词法分析从源程序中分出各种单词并对词法分析程序提供的单词序列进行语法检查和结构分析,熟悉并掌握常用的语法分析方法。

明确语法分析器的功能,在词法分析的基础上进一步分析程序;加深对课堂教学的理解;提高语法分析方法的实践能力;通过本实验,应达到以下目标:1、掌握递归下降的结构模型。

2、掌握语法分析的实现方法。

3、上机调试编出的语法分析程序。

二、实验过程有了第一次的经验,这次还是先画出流程图。

流程图如下:三、实验结果语法分析实验成功。

赋值时少写数字:缺少括号时:附(txt文档内容):程序运行后写入的:四、讨论与分析这个程序是在实验一的基础上写的,用的递归下降的方法。

不止能识别,还能判断一些语法的正误。

刚看书上附录的代码时,头都大了,觉得自己完成不了。

但是真正一步一步看下去,画出了流程图,就很清晰明白了。

一个函数嵌套一个函数,一步一步往细处走,刚开始是大体轮廓,然后就深入,直到最低层的判断。

书上的程序还是有一些漏洞,比如要写多个语句时,if,for,while在语句内不能加括号,不然只能分析至第一个,遇到“}”就结束了,所以在txt文件里写程序代码的时候要注意不能加{},这样才可以全部printf出来。

五、附录:关键代码(给出适当注释,可读性高)全部代码附vc++,这里粘贴主程序,以及各类函数。

int TESTparse();int TESTscan();int program();int compound_stat();int statement();int expression_stat();int expression();int bool_expr();int additive_expr();int term();int factor();int if_stat();int while_stat();int for_stat();int write_stat();int read_stat();int declaration_stat();int declaration_list();int statement_list();int compound_stat();#include<stdio.h>#include<ctype.h>int TESTscan();int TESTparse();FILE *fin,*fout;void main(){int es=0;es=TESTscan();if(es>0)printf("词法分析有错!编译停止!\n");else{printf("词法分析成功!\n");}if(es==0){es=TESTparse();if(es==0)printf("语法分析成功!\n");elseprintf("语法分析错误!\n");}}六、实验者自评这个实验比第一个有难度,是在第一个完成的基础上进行的。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

编译原理课程设计课程设计题目:LL(1)递归下降分析器姓名:院(系):专业班级:学号:指导教师:设计日期:目录1、需求分析 (1)2、概要设计 (2)3、详细设计 (3)4、测试分析 (8)5、用户手册 (9)6、课程总结 (9)7、参考文献 (10)题目:LL (1)递归下降分析器1、需求分析语法分析是编译过程的核心部分。

语法分析器的任务是识别和处理比单词更大的语法单位。

如:程序设计语言中的表达式,各种说明和语句乃至全部源程序,指出其中的语法错误;必要时,可生成内部形式,便于下一阶段处理。

我们知道,语言的语法结构是用上下文无关文法描述的。

按照语法分析树的建立方法,我们可以粗略地把语法分析办法分成两类,一类是自上而下分析,另一类是自下而上分析法。

而自上而下这种方法是带“回溯”的,且存在许多困难和缺点。

首先,是文法的左递归性问题。

一个文法是含有左递归的,如果存在非终结符P 且αP P +⇒,含有左递归的文法使上述的自上而下的分析过程陷入无限循环。

即,当试图用P 去匹配输入串时,我们会发现,在没有识别任何输入符号的情况下,有得重新要求P 去进行新的匹配。

因此,使用自上而下分析法必须消除文法的左递归性。

其次,由于回溯,就碰到一大堆麻烦问题。

如果我们走了一大段错路,最后必须回头,那么,就应把已经做的一大堆语义工作(指中间代码产生工作和各种表格的簿记工作)推倒重来。

这些事情既麻烦又费时间,所以,最好应设法消除回溯。

第三,在自上而下分析过程中,当一个非终结符用某一候选匹配成功时,这种成功可能仅是暂时的。

第四,当最终报告分析不成功时,我们难于知道输入串中出错的确切位置。

最后,由于带回溯的自上而下分析实际上采用了一种穷尽一切可能的试探法,因此,效率很低,代价极高。

严重的低效使得这种分析法只有理论意义,而在实践上价值不大。

由于上述原因,我们需要把原算术表达式改写为LL(1)文法,LL(1)文法的文法条件如下: 文法不含左递归。

对于文法中每一个非终结符A 的各个产生式的候选首集符两两不相交。

即,若n A ααα|||21 →,则()()φαα=⋂j i FIRST FIRST ()j i ≠对文法中的每个非终结符A ,若它存在某个候选首符集包含ε,则()()φ=⋂A F O L L O WA F I R S T LL(1)中的第一个L 表示从左到右扫描输入串,第二个L 表示最左推导,1表示分析时每一步只需向前查看一个符号。

当一个文法满足LL(1)条件时,我们就可以为它构造一个不带回溯的自上而下分析程序,这个分析程序是由一组递归过程组成的,每个过程对应文法的一个非终结符。

这样的一个分析程序称为递归下降分析器。

2、概要设计编程实现给定算术表达式的递归下降分析器。

算术表达式文法如下:E-->E+T|E-T|TT-->T*F|T/F|FF-->(E)| i首先改写文法为LL(1)文法;然后为每一个非终结符,构造相应的递归过程,过程的名字表示规则左部的非终结符;过程体按规则右部符号串的顺序编写。

上述算法表达式文法属于比较典型的递归下降语法分析。

需要先将原算术表达式方法改写为LL(1)文法为:E-->TE’E’-->+TE’|-TE’| εT-->FT’T’-->*FT’|/FT’| εF-->(E)| i然后再为每个非终结符设计一个对应的函数,通过各函数之间的递归调用从而实现递归下降语法分析的功能。

具体方法为:(1)当遇到终结符a时,则编写语句If(当前读到的输入符号==a)读入下一个输入符号(2)当遇到非终结符A时,则编写语句调用A()。

(3)当遇到A-->ε规则时,则编写语句If(当前读到的输入符号不属于Follow(A)) error()(4)当某个非终结符的规则有多个候选式时,按LL(1)文法的条件能唯一地选择一个候选式进行推导.递归下降子程序流程图:图1递归下降子程序流程图3、详细设计#include<iostream.h>char inputstream[50]; //存储输入句子int temp=0; //数组下标int right; //判断输出信息void e();void e1();void t();void t1();void f();void main(){right=1;cout<<"---------------------------------------------------"<<endl;cout<<"请输入您要分析的字符串以#结束(^为空字符):"<<endl;cin>>inputstream;cout<<"---------------------------------------------------"<<endl;cout<<endl;cout<<"开始进行语法分析"<<endl;e();if((inputstream[temp]=='#')&&right)cout<<"分析成功"<<endl;elsecout<<"分析失败"<<endl;}void e(){cout<<"E->TE'"<<endl;t();e1();}void e1(){if(inputstream[temp]=='+'){cout<<"E'->+TE'"<<endl;temp++;t();e1();}else if(inputstream[temp]=='-'){cout<<"E'->-TE'"<<endl;temp++;t();e1();}else if(inputstream[temp]!='#'||inputstream[temp]!=')') {cout<<"T'->^"<<endl;return;}elseright=0;}void t(){cout<<"T->FT'"<<endl;f();t1();}void t1(){if(inputstream[temp]=='*'){cout<<"T'->*FT'"<<endl;temp++;f();t1();}else if(inputstream[temp]=='/'){cout<<"T'->/FT'"<<endl;temp++;f();t1();}elseif(inputstream[temp]!='#'&&inputstream[temp]!=')'&&inputstream[temp]!='+'&&input stream[temp]!='-'){cout<<"T'->^"<<endl;right=0;}}void f(){if(inputstream[temp]=='i'){cout<<"F->i"<<endl;temp++;}elseif(inputstream[temp]=='('){cout<<"F->(E)"<<endl;temp++;e();if(inputstream[temp]==')'){cout<<"F->(E)"<<endl;temp++;}elseright=0;}else right=0;}4、测试分析图2 测试分析成功图3 测试分析失败5、用户手册开发工具:visual c++ 6.0开发环境:windows XP操作系统运行环境:windows 9x,windows NT,Windows 2000,windows XP注意:输入时,程序最多只能接受50个字符,输入完算术表达式后要以“#”号结束。

6、课程总结通过一个星期的努力,终于把编译原理课程设计给完成了。

我觉得编译原理这门课是一门非常难学的课程,它涉及文法、词法分析、语法分析属性文法和语义分析等等一系列内容,课本里的内容和定义也非常的抽象且枯燥。

如果上课没有好好的认真听课,自己独自学习就感到非常的吃力,而且效果也不好。

本人因为上课无法做到打醒十二分专心听课,经常会分神,所以学习的效果也不怎么好。

这也给做编译原理课程设计带来了困难。

本次课程设计,我选的课程设计题目是LL(1)递归下降分析器,这个题目涉及的内容有关课本第四章语法分析——自上而下分析里面的内容。

在开始动手对题目进行设计和编程之前,我重复的仔细认真的阅读和理解课本第四章里面的内容,弄懂自上而下分析面临的问题、何谓左递归,搞清楚如何消除左递归、如何消除回溯、提左因子,理解构造LL(1)文件需要什么条件。

虽然这花费了一定的时间和精力,但那点付出也是值得的,通过复习让我加深理解了有关自上而下语法分析的内容,而且也为用高级语言实现递归下降分析器带来便利。

在用C++编程时,基本上没有遇到什么困难,只需把所有递归过程都写出就行了。

但是要注意的是,在编写代码时,要根据LL(1)文法的工作原理去设计。

通过本次课程设计清楚地了解到递归下降分析法的优缺点,其优点是简单、直观,易于构造分析程序。

缺点是对文法要求高,必须是LL(1)文法,同时由于递归调用较多,影响分析器的效率。

课程设计虽然只有短短的一周,但让我认识到学习好编译原理,是对程序设计和编译的一个很好的进化桥梁和奠基石。

今后学习的日子还很长,希望通过这次编译原理的课程设计,不仅对编程语言的进一步复习,还是对更深层次的学习作一个简单的准备。

编程的能力不是一朝一夕能锻炼出来,坚持学习,坚持编程的学习,多看,多编是最好的学习和提高方法。

相关文档
最新文档