编译原理递归下降分析器 C语言

合集下载

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

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

编译原理实验报告—递归下降分析法程序实验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可以产生字符-。

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

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

递归下降分析器设计一、实验/实习过程内容:利用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基本的使用。

编译原理用递归下降法进行表达式分析实验报告

编译原理用递归下降法进行表达式分析实验报告

《编译原理》课程实验报告题目用递归下降法进行表达式分析专业班级学号姓名一.实验题目用递归下降法进行语法分析的方法二.实验日期三.实验环境(操作系统,开发语言)操作系统是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语言程序进行语法分析,检测代码中的语法错误,并生成相应的语法树。

在生成语法树之后,可以继续进行语义分析、中间代码生成、代码优化等编译过程。

总的来说,递归下降分析法是一种重要的语法分析方法,可以用于对C语言程序进行语法分析。

它通过自顶向下的递归调用,从上至下地解析语法规则,最终确定程序的语法结构。

递归下降分析法在实际编译器设计中有广泛应用,是理解和学习编译原理的重要内容。

编译原理语法分析递归下降子程序实验报告

编译原理语法分析递归下降子程序实验报告

编译原理语法分析递归下降子程序实验报告编译课程设计-递归下降语法分析课程名称编译原理设计题目递归下降语法分析一、设计目的通过设计、编制、调试一个具体的语法分析程序,加深对语法分析原理的理解,加深对语法及语义分析原理的理解,并实现对文法的判断,是算符优先文法的对其进行FirstVT集及LastVT集的分析,并对输入的字符串进行规约输出规约结果成功或失败。

二、设计内容及步骤内容:在C++ 6.0中编写程序代码实现语法分析功能,调试得到相应文法的判断结果:是算符优先或不是。

若是,则输出各非终结符的FirstVT与LastVT集的结果,还可进行字符串的规约,输出详细的规约步骤,程序自动判别规约成功与失败。

步骤:1.看书,找资料,了解语法分析器的工作过程与原理2.分析题目,列出基本的设计思路1定义栈,进栈,出栈函数○2栈为空时的处理○3构造函数判断文法是否是算符文法,算符优先文法○4构造FirstVT和LastVT函数对文法的非终结符进行分析○5是算符优先文法时,构造函数对其可以进行输入待规约○串,输出规约结果○6构造主函数,对过程进行分析3.上机实践编码,将设计的思路转换成C++语言编码,编译运行4.测试,输入不同的文法,观察运行结果详细的算法描述详细设计伪代码如下:首先要声明变量,然后定义各个函数1.void Initstack(charstack &amp;s){//定义栈s.base=new charLode[20];s.top=-1; }2. void push(charstack&amp;s,charLode w){//字符进栈s.top++;s.base[s.top].E=w.E;s.base[s.top].e=w.e;}3. void pop(charstack&amp;s,charLode &amp;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=&#39;A&#39;&amp;&amp;ch= &#39;Z&#39;)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日一、实验目的通过本实验,了解递归下降预测分析的原理和过程以及可能存在的回溯问题,探讨解决方法,为预测分析表方法的学习奠定基础。

编译原理实验递归下降分析器的设计含源代码和运行结果

编译原理实验递归下降分析器的设计含源代码和运行结果
2求出每个非终结符的FIRST集合和FOLLOW集合:
FIRST(exp)= FIRST(term)= FIRST(factor)={id, number, ( }
FIRST(texp)={ ε,+, - }
FIRST(Addop)={+, - }
FIRST(tterm)={ ε,*, / }
FIRST(mulop)={*, / }
由于分析的文件中可能出现非法字符,而一旦发现非法字符就无需再接着分析,所以在每次读取一个字符时调用islegal函数判断是否是合法字符,并返回0或1.
在main()函数中,while((lookahead=='\n'||lookahead==' ')&&lookahead!=EOF)ﻩfscanf(resource,"%c",&lookahead);
void match(chart)//写入result文件,打印输出,并读取下一个

fprintf(result,"%c",lookahead);//向result写入
printf("%c",lookahead);
fscanf(resource,"%c",&lookahead);//读数据

number()//识别数字,如果遇到数字就一直接着读直到不是数字
{
while('0'<=lookahead&&lookahead<='9')
ﻩ{
ﻩfprintf(result,"%c",lookahead);//写入
printf("%c",lookahead);

编译原理之递归下降语法分析程序(实验)

编译原理之递归下降语法分析程序(实验)

编译原理之递归下降语法分析程序(实验)⼀、实验⽬的利⽤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)

编译原理实验报告二递归下降语法分析程序 (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");}}六、实验者自评这个实验比第一个有难度,是在第一个完成的基础上进行的。

编译原理实验_递归下降语法分析

编译原理实验_递归下降语法分析

递归下降语法分析姓名:郝梦朔学号:日期:2010-1-17一、实验目的构造文法的语法分析程序,要求采用递归下降语法分析方法对输入的字符串进行语法分析,实现对词法分析程序所提供的单词序列的语法检查和结构分析,进一步掌握递归下降的语法分析方法。

二、实验内容编写为一上下文无关文法构造其递归下降语法分析程序,并对任给的一个输入串进行语法分析检查。

程序要求能对输入串进行递归下降语法分析,能判别程序是否符合已知的语法规则,如果不符合(编译出错),则输出错误信息。

三、实验要求利用C语言编制递归下降分析程序,并对语言进行语法分析。

(1)待分析的语言的语法。

用扩充额BNF表示如下。

①<程序>::=function<语言串>endfunc②<语言串>::=<语句>{;<语句>}③<语句>::=<赋值语句>④<赋值语句>::=ID=<表达式>⑤<表达式>::=<项>{+<项>|-<项>}⑥<项>::=<因子>{*<因子>|/<因子>}⑦<因子>::=ID|NUM|(<表达式>)(2)实验要求说明输入单词串以“#”结束,如果是文法正确的句子,则输出成功信息,打印“success”,否则输出“error”,具体例子如下。

输入functiona=9;x=2*3;b=a+x;endfunc#输出success又如,输入:x=a+b*cendfunc#输出error(3)语法分析程序的算法思想为翟玉庆老师上课所讲。

四、实验源程序#include<stdio.h>#include<string.h>char prog[80],token[8];char ch;int syn,p,m=0,n,sum,kk=0;char *rwtab[6]={"function","if","then","while","do","endfunc"};void scaner();void lrparser();void yucu();void statement();void expression();void term();void factor();void main(){p = 0;printf("please input the string:\n");do{ch = getchar();prog[p++] = ch;}while(ch != '#');p = 0;ch = prog[p++];scaner();lrparser();return;}void scaner(){for(n=0;n<8;n++)token[n]=NULL;//printf("\n%c in scaner()",ch);while(ch == ' ' || ch == '\n' )ch = prog[p++];//printf("\n%c in scaner()",ch);m = 0;if((ch<='z' && ch>='a') ||(ch<='Z' && ch>='A')){while((ch<='z' && ch>='a') ||(ch<='Z' && ch>='A')||(ch<='9' && ch>='0')){token[m++] = ch;ch = prog[p++];}syn=10;for(n=0;n<6;n++)if(strcmp(token,rwtab[n]) == 0){syn = n+1;//printf("\n%d in keyword",syn);break;}token[m++] = '\0';}else if(ch<='9' && ch>='0'){sum=0;while(ch<='9' && ch>='0'){sum = sum*10 + ch - '0';ch = prog[p++];}syn = 11;}else{switch(ch){case '<':m = 0;token[m++] = ch;ch = prog[++p];if(ch == '='){syn = 22;token[m++] = ch;}else{syn = 20;ch = prog[--p];}break;case '>':m = 0;token[m++] = ch;ch = prog[++p];if(ch == '='){syn = 24;token[m++] = ch;}else{syn = 23;ch = prog[--p];}break;case '=':m = 0;token[m++] = ch;ch = prog[++p];if(ch == '='){syn = 25;token[m++] = ch;}else{syn = 18;ch = prog[--p];}break;case '!':m = 0;token[m++] = ch;ch = prog[++p];if(ch == '='){syn = 22;token[m++] = ch;}elsesyn = -1;break;case '+':syn = 13;token[0] = ch;break;case '-':syn = 14;token[0] = ch;break;case '*':syn = 15;token[0] = ch;break;case '/':syn = 16;token[0] = ch;break;case ';':syn = 26;token[0] = ch;break;case '(':syn = 27;token[0] = ch;break;case ')':syn = 28;token[0] = ch;break;case '#':syn = 0;token[0] = ch;break;default:syn = -1;}ch = prog[p++];}}void lrparser(){if(syn ==1){//printf("\n%d",syn);scaner();//printf("\n%d",syn);yucu();/**/// printf("\n%d after yucu()",syn);if(syn == 6){scaner();//printf("\n%d in lrparser() after scaner()",syn);if(syn == 0 && kk == 0)printf("\nsuccess!\n");else{if(kk != 1){printf("error!need 'endfunc'");kk = 1;}}}else{printf("error!need 'function'");kk =1;}return;}void yucu(){//printf("\n%d in yucu() first",syn);statement();//printf("\n%d after statement() in yucu()",syn);while(syn == 26){scaner();//syn = 6;//printf("\n%d after scaner() in yucu()",syn);statement();}return;}void statement(){//printf("\n%d in statement() at first",syn);if(syn == 10){scaner();//printf("\n%d after scaner() in statement()",syn);if(syn == 18){scaner();// printf("\n%d after scaner when syn=18",syn);expression();// printf("\n%d after expression()",syn);else{printf("error! evaluate tag error");kk = 1;}}else if(syn == 6)return;else{printf("error! the statement error!");kk = 1;}return;}void expression(){// printf("\n%d in expression at first",syn);term();while(syn == 13 || syn == 14){scaner();term();}return;}void term(){// printf("\n%d in term() at first",syn);factor();while(syn == 15 || syn == 16){scaner();factor();}return;}void factor(){// printf("\n%d in factor() at first",syn);if(syn == 10 || syn == 11){scaner();}else{if(syn == 27){scaner();expression();if(syn == 28){scaner();}else{printf("error! need another ')'");kk = 1;}}else{printf("error! expression error!");}}}五、程序运行效果截图六、心得体会这个实验其实是上个实验的扩展,有个上个实验的基础做这个实验就比较轻松了。

编译原理递归下降分析器 C语言

编译原理递归下降分析器 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什么是递归下降分析法递归下降分析法是一种自顶向下的分析方法,文法的每个非终结符对应一个递归过程(函数)。

分析过程就是从文法开始符出发执行一组递归过程(函数),这样向下推导直到推出句子;或者说从根节点出发,自顶向下为输入串寻找一个最左匹配序列,建立一棵语法树。

在不含左递归和每个非终结符的所有候选终结首字符集都两两不相交条件下,我们就可能构造出一个不带回溯的自顶向下的分析程序,这个分析程序是由一组递归过程(或函数)组成的,每个过程(或函数)对应文法的而一个非终结符。

编译原理编写递归下降语法分析器

编译原理编写递归下降语法分析器

降语法分析器学院:信息与控制工程学院专业:计算机科学与技术班级:计算机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*#,要求输出为“非法的符号串”。

程序清单:#include<stdio.h>#include<string>char str[50];int index=0;void E(); //E->TX;void X(); //X->+TX | evoid T(); //T->FYvoid Y(); //Y->*FY | evoid F(); //F->(E) | iint main() /*递归分析*/int len;int m;printf("请输入要测试的次数:");scanf("%d",&m);while(m--)printf("请输入字符串(长度<50>):\n");scanf("%s",str);len=strlen(str);//str[len]='#';str[len+1]='\0';E();printf("%s为合法符号串!\n",str);strcpy(str,"");index=0;} return 0;void E(){ T(); X();}void X()if(str[index]=='+'){ index++;T();X();void T(){ F(); Y(); }void Y(){ i f(str[index]=='*') {index++;F();Y();void F()if(str[index]=='i'){ index++; }else if (str[index]=='(')index++;E();if(str[index]==')'){ index++; }elseprintf("\n非法的符号串!\n");exit (0);elseprintf("非法的符号串!\n");exit(0);屏幕截图:四、讨论与分析通过本次实验对递归下降词法分析器的结构,过程有了更进一步的了解,通过学习书本与试验原理书上的内容,对它的工作原理,具体实行步骤有了进一步的掌握,由于本次试验是测试性试验,所以要求输出的结果是成功与否,输入一个句型,进过分析,判断它是否合法,主要内容在于其判断过程中。

实验三递归下降分析器设计与实现编译原理实验报告

实验三递归下降分析器设计与实现编译原理实验报告

实验三递归下降分析器设计与实现编译原理实验报告一、引言递归下降分析器是编译原理中常用的一种语法分析方法。

它根据文法规则和输入的源代码,递归地进行语法分析,判断源代码是否符合给定的文法规则。

本实验旨在通过设计与实现一个简单的递归下降分析器,加深对编译原理中语法分析的理解。

二、实验目的1.学习递归下降分析器的原理和设计方法;2.掌握使用递归下降分析器进行简单语法分析的过程;3.加深对编译原理中文法规则和语法分析的理解。

三、实验过程1.设计文法规则:根据实验要求,设计一个简单的算术表达式文法规则。

例如,我们可以采用以下文法规则:```E->E+T,E-T,TT->T*F,T/F,FF -> ( E ) , num```2.设计分析器:根据设计的文法规则,设计递归下降分析器的结构和算法。

我们可以使用编程语言实现一个类,其中包含递归下降分析器所需要的方法和数据结构。

3. 实现分析器:根据设计的分析器结构和算法,使用编程语言实现递归下降分析器的代码。

可以选择常用的编程语言,如C++、Java、Python等。

4.进行语法分析:编写测试代码,使用实现的递归下降分析器对输入的算术表达式进行语法分析。

根据分析结果,判断输入的算术表达式是否符合给定的文法规则。

五、实验结果实验结果根据设计的分析器的实现和测试代码的编写而定。

例如,对于以下输入的算术表达式:(3+4)*5-2,经过递归下降分析器的分析,应该能正确判断其是否符合给定的文法规则。

六、实验总结递归下降分析器是编译原理中常用的一种语法分析方法。

通过实验三,我深入理解了递归下降分析器的原理和设计方法,并通过实现一个简单的递归下降分析器,加深了我对编译原理中文法规则和语法分析的理解。

在实验过程中,我学会了如何根据设计的文法规则来设计递归下降分析器的结构和算法。

我使用了编程语言实现了递归下降分析器的代码,并编写了相应的测试代码进行语法分析。

通过测试,我验证了递归下降分析器的正确性。

最新编译原理实验(递归向下语法分析法实验)附C语言源码-成功测试

最新编译原理实验(递归向下语法分析法实验)附C语言源码-成功测试

实验二递归向下分析法一、实验目和要求根据某一文法编制调试递归下降分析程序,以便对任意输入的符号串进行分析。

本次实验的目的主要是加深对递归下降分析法的理解。

二、实验内容(1)功能描述1、递归下降分析法的功能词法分析器的功能是利用函数之间的递归调用模拟语法树自上而下的构造过程。

2、递归下降分析法的前提改造文法:消除二义性、消除左递归、提取左因子,判断是否为LL(1)文法,3、递归下降分析法实验设计思想及算法为G 的每个非终结符号U 构造一个递归过程,不妨命名为U。

U 的产生式的右边指出这个过程的代码结构:1)若是终结符号,则和向前看符号对照,若匹配则向前进一个符号;否则出错。

2)若是非终结符号,则调用与此非终结符对应的过程。

当 A 的右部有多个产生式时,可用选择结构实现。

具体为:(1)对于每个非终结符号U->u1|u2|…|un处理的方法如下:U( ) { ch=当前符号;if(ch可能是u1字的开头) 处理u1的程序部分;else if(ch可能是u2字的开头)处理u2的程序部分;…else error()}(2)对于每个右部u1->x1x2…xn的处理架构如下:处理x1的程序;处理x2的程序;…处理xn的程序;(3)如果右部为空,则不处理。

(4)对于右部中的每个符号xi①如果xi为终结符号:if(xi= = 当前的符号){NextChar();return;}else出错处理②如果xi为非终结符号,直接调用相应的过程xi()说明:NextChar为前进一个字符函数。

(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)E 盘建立一个文本文档" 222.txt"存储一个以#结束的符号串(包括+—*/()i#),在此位置输入符号串例如:i+i*i#(2)输出结果:i+i*i#为合法符号串备注:输入一符号串如i+i*#,要求输出为“非法的符号串” 函数调用格式、参数含义、返回值描述、函数功能;函数之间的调用关系图。

编译原理——递归下降语法分析

编译原理——递归下降语法分析

《编译原理》课程实验陈述之南宫帮珍创作实验名称:递归下降分析法姓名:彭国保学号:540907010130院系:计算机与通信工程学院专业:计算机科学与技术班级:09-1班教师:韩丽2012年4月22日一.实验目的根据某一文法编制调试递归下降分析程序,以便对任意输入的符号串进行分析。

本次实验的目的主要是加深对递归下降分析法的理解。

程序开始变得复杂起来,需要利用到程序设计语言的知识和大量编程技巧,递归下降分析法是一种较实用的分析法,通过这个练习可大大提高软件开发能力。

通过练习,掌握函数间相互调用的方法。

二.实验内容递归下降分析法是确定的自上而下分析法,它要求文法是LL(1)文法。

它的基本思想是:对文法中的每个非终结符编写一个函数或子程序,每个函数或子程序的功能是识别由该非终结符所暗示的语法成分。

程序算法描述词法分析器的功能是利用函数之间的递归调用模拟语法树自上而下的构造过程。

改造文法:消除二义性、消除左递归、提取左因子,判断是否为LL(1)文法,为G的每个非终结符号U构造一个递归过程。

U的发生式的右边指出这个过程的代码结构:(1)若是终结符号,则和向前看符号对照,若匹配则向前进一个符号;否则出错。

(2)若是非终结符号,则调用与此非终结符对应的过程。

当A的右部有多个发生式时,可用选择结构实现。

最后编写程序以实现上述功能。

三.实验步调根据上述算法描述,编写程序以实现相应的功能,该程序由C语言编写,然后在VC运行环境下进行调试,其实不竭完善,直到能正确的实现递归下降分析功能,判断输入的字符串是否是一个文法的句子。

源程序代码如下:#include<stdio.h>void S();void T();void error();void scaner();char sym;int main(){scaner();S();if(sym=='$') printf("是该文法的句子");else printf("不是该文法的句子");return 0;}void S(){if(sym=='a'||sym=='^') scaner();else if(sym=='('){scaner(); T();if(sym==')') scaner();else error();}else error();}void T(){T1();}void T1(){if(sym==','){scaner();S();T1();}else if(sym !=')')error();}void scaner(){scanf("%c",&sym);}void error(){printf("不是该文法的句子");}调试程序的结果:四.总结与回顾通过本次实验,我掌握了递归下降分析程序的构造过程,将一个文法编写为对应的子程序,如有左递归先消除左递归,再改写为相应的程序。

递归下降分析器程序(c语言版,编译原理实验)

递归下降分析器程序(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. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
int E()/*E() procedure*/ {
print(); printf("E->TE'\n"); n=3; l=l+n-1; ch[l]='T'; ch[l-1]=39; ch[l-2]='E'; step++; T(); E1(); }
int E1()/*E1() procedure*/ {
lookahead++; } else {
printf("No ')'match!\n"); exit(0); } } else { printf("No '(' match!\n"); exit(0); } }
int print() {
int i; printf("%d\t",step); for(i=0;i<=l;i++)
int T1()/*T1() procedure*/ {
if(a[lookahead]=='*') {
print(); printf("T'->*FT'\n"); n=3; l=l+n-2; ch[l]='F'; ch[l-1]=39; ch[l-2]='T'; step++; lookahead++; F(); T1(); } else print(); printf("T'->e\n"); l=l-2; step++; }
if(a[lookahead]=='+')/*if the next char is ‘+’*/ {
print(); printf("E'->+TE'\n"); n=3; l=l+n-2; ch[l]='T'; ch[l-1]=39; ch[l-2]='E'; step++; lookahead++;/*turn to next char*/ T(); E1();
E TE' E' TE'| T FT ' T ' *FT '| F (E) | i 2 消除回溯
回溯发生的原因在于候选式存在公共的左因子。一般情况下,设文法中关于
A 的产生式为 A 1 | 2 | ... | i | i1 | ... | j ,那么,可以把这些产生式改写为
A A'| i1 | ... | j
T(),执行其中的嵌套函数 F()或 T’();对于函数 F(),如果有字符“i”匹配,则进
行匹配,否则若待分析串喊字符“(”,进行匹配,并进入嵌套函数 E()执行,再匹
配“)”;对于函数 T’(),若有字符“*”匹配,则进行匹配,否则进入嵌套函数 F()
或 T’()或为空。
5 文法分析流程图
函数间调用情况:
printf("%c",ch[i]); if(l<7) printf("\t\t");
else printf("\t"); for(i=0;i<lookahead;i++) {
a[i]=' '; printf("%c",a[i]); } for(i=lookahead;i<length;i++) printf("%c",a[i]); printf("\t"); }
E TE' E' TE'| T FT ' T ' *FT '| F (E) | i
ห้องสมุดไป่ตู้
文法分析过程类似于一个个函数嵌套,我们可以假定函数 E()、T()、E’()、
F()、T’(),文法开始符 E(看做函数 E())嵌套函数 T()、E’();而对于函数 E’(),
若有字符“+”匹配,则进行匹配,否则进入嵌套函数 T()或 E’()或为空;对于函数
A'
1
|
...
|
i
经过反复提取左因子,就能把每个非终结符(包括新引进者)的所有候选首字符
集变为两两不相交(既不含有公共左因子)。
3 什么是递归下降分析法
递归下降分析法是一种自顶向下的分析方法,文法的每个非终结符对应一个
递归过程(函数)。分析过程就是从文法开始符出发执行一组递归过程(函数),
这样向下推导直到推出句子;或者说从根节点出发,自顶向下为输入串寻找一个
} else
print(); printf("E'->e\n"); l=l-2; step++; }
int T()/*T() procedure*/ {
print(); printf("T->FT'\n"); n=3; l=l+n-1; ch[l]='F'; ch[l-1]=39; ch[l-2]='T'; step++; F(); T1(); }
int F()/*F() procedure*/ {
if(a[lookahead]=='i') {
print(); printf("F->i\n"); n=0; l=l+n-1; step++; lookahead++; } else if(a[lookahead]=='(') { print(); printf("F->(E)\n"); ch[l]='E'; step++; lookahead++; E(); if(a[lookahead]==')') {
实验目的:
通过设计、编制、调试递归下降语法分析程序,对输入的符号串进行分析匹 配,观察输入符号串是否为给定文法的句子。
实验内容:
根据文法 G[E]设计递归下降分析器并分析输入串 i1 *(i2 i3) 是否为文法的句
子。
G[E]:E→E+T|T T→T*F|F F→(E)|i
实验步骤:
在进行递归下降分析法之前,必须对文法进行左递归和回溯的消除。 1 消除左递归 直接消除见诸于产生式中的左递归比较容易,其方法是引入一个新的非终结 符,把含有左递归的产生式改为右递归。 文法 G[E]经过消去直接左递归后得到文法 G’[E]为: G’[E]:
)#
15
#E’T’
#
16
#E’
#
17
#
#
7 程序设计
本实验在程序设计方面做出了以下定义:
一维字符数组 a[]:用于存放分析字符串
一维字符数组 ch[]:用于存放符号栈内容
lookahead:用于处理正在分析字符串的哪一个字符
length:输入串的长度
l:符号栈大小减 1
n:产生式右部长度(’也算作一个字符)
#include<stdio.h> #include<string.h>
char a[10];/*define input string’s type & length*/ char ch[10]={'#','E'}; char cha; int lookahead=0;/*define array’s number*/ int length=0; int step=1; int l=1; int n;
do {
scanf("%c",&cha); a[length]=cha; length++; }while(cha!='#'); E(); if(a[lookahead]=='#')/*whether the last char is ‘#’ or not*/ printf("\nThe structure of the sentence is right!"); else printf("\nNo end sign!"); } return 0; }
实验结果:
注:实验结果第一列表示步骤,第二列表示符号栈,第三列表示待分析串,第四 列代表所用产生式。
实验心得:
这个实验相对于词法分析实验而言更加困难,本实验在设计代码的时候是以 不存在左递归和回溯的情况下进行的,在一定程度上降低了一定的难度。该实验 重点在于需要我们理解什么是递归下降分析器,是如何进行分析的,还需要画出 流程图,理清整体思路,再结合书上的代码,整理出相应的内容,然后将之编写 为代码,实现递归下降分析器。所编写的代码仍存在问题,欢迎老师指点。
最左匹配序列,建立一棵语法树。
在不含左递归和每个非终结符的所有候选终结首字符集都两两不相交条件
下,我们就可能构造出一个不带回溯的自顶向下的分析程序,这个分析程序是由
一组递归过程(或函数)组成的,每个过程(或函数)对应文法的而一个非终结
符。这样的一个分析程序称为递归下降分析器。
4 文法分析
以 G’[E]为例:G’[E]:
数学与软件科学学院 实验报告
学 期: 2015 至 2016 第 2 学期
2016 年 3 月 21 日
课程名称: 编译原理 专 业: 信息与计算科学
2013 级 5 班
实验编号: 2
实验名称: 递归下降分析器 指导教师: 王开端
相关文档
最新文档