实验二自顶向下语法分析--递归下降法

合集下载

实验二 递归下降分析法的实现

实验二  递归下降分析法的实现

实验二递归下降分析法的实现一、实验目的实现一个递归下降语法分析程序,识别用户输入的算术表达式。

二、实验主要内容1、文法如下:E→TE`E’→+TE’|-TE’|εT→FT`T’→*FT’|/FT’|εF→(E)|i2、求取各非终结符的First及Follow集合3、编程实现下降递归分析法,识别从键盘输入的关于整数或浮点数的算术表达式(在此,上述文法中的i代表整数或浮点数)4、对于语法错误,要指出错误具体信息。

5、运行实例如下:三、提示1、纸质实验报告内容:实验内容、非终结符的First及Follow集合、正确表达式与错误表达式各举一例进行测试并给出结果、核心源代码。

2、将本次实验代码(.c、.cpp、.java等代码文件,删除编译产生的所有其他文件,不要打包)在规定时间内以作业附件(不可在线编辑、粘贴代码)的形式提交至网站,自己保存以备课程设计(本部有毕业设计要求的学生)参考。

3、纸质实验报告提交时间:临时要求。

实验指导(参考)一、实验步骤1、求取各非终结符的First及Follow集合;2、设计几个函数E(); Ep(); T(); Tp(); F();运用First集合进行递归函数选择,运用Follow集合进行出错情况判断;3、设计主函数:从键盘接受一个算术表达式串;在串尾添加尾部标志’#’;调用函数E()进行递归下降分析。

二、如何识别整数与浮点数在函数F()中要涉及到如何识别整数与浮点数。

识别的方法是:只要碰到‘0’~‘9’之间的字符就一直循环,循环到不是数字字符与小数点字符’.’为止,其间要运用一个标志变量来保证最多只能出现一个小数点,否则应该报错。

上述循环结束即表示识别了一个数,也即表达式文法中的i。

自顶向下的语法分析:递归下降法

自顶向下的语法分析:递归下降法

实验二:自顶向下的语法分析:递归下降法1、实验目的:编制一个递归下降分析程序,实现对词法分析程序所提供的单词序列的语法检查和结构分析。

2、实验要求:文法(教材199页)(1)把词法分析作为语法分析的子程序实现(5分)(2)独立的语法分析程序(4分)(3)输入串以‘#’结束,输出成功(success)或出错(error)、指出出错位置(行、列以及错误类型)#include<iostream>#include<fstream>#include<string>#include<stdlib.h>#define MAX 1024using namespace std;string DataType[] = {"int", "bool", "char", "void"};string KeyWords[] = {"if", "else", "do", "while", "for", "break", "in", "continue", "goto","switch", "case", "default", "foreach", "try", "catch", "finally", "throw", "return"};string Operator[] = {"+", "-", "*", "/", "%", "&&", "||", ">", "<", ">=", "<=", "==", "!=", "^", "&", "|","~", "<<", ">>", "=", "+=", "-=", "*=", "/=", "%=", "&=", "|=", "^=", "<<=", ">>="};char Seperator[] = {' ', '.', '(', ')', '[', ']', ';', '{', '}', ',', '?', ':'};struct Identity{string value;int type;};ifstream inFile("D:\\output.txt");int row = 1;Identity ID[10000];int nWord = 0;void Expression(){string word;int syn;inFile >> word >> syn;if(syn == 71){string tmp1;int tmp2;inFile >> tmp1 >> tmp2;if(tmp2 != 199){if(tmp2 >= 30 && tmp2 < 71){inFile >> tmp1 >> tmp2;if(tmp2 == 71){inFile >> tmp1 >> tmp2;if(tmp2 != 199)cout << "error occurs in row " << row << ", miss \";\"!" << endl;}elsecout << "error occurs in row " << row << ", miss identity!" << endl;}elsecout << "error occurs in row " << row << ", miss operator!" << endl;}}}int look(string value){int i;for(i=0; i<nWord; i++)if(ID[i].value == value)return i;return -1;}void GrammerAnalyse(){string word;int syn;int i;while(!inFile.eof()){i = 0;inFile >> word >> syn;if(word == "#")row++;else{if(syn > 0 && syn < 10){string tmp1;int tmp2;inFile >> tmp1 >> tmp2;if(tmp2 == 71){int index = look(tmp1);//ID[index].type = syn;inFile >> tmp1 >> tmp2;if(tmp2 != 199){if(tmp1 == "="){Expression();}elsecout << "error occurs in row " << row << ", miss \";\"!" << endl;}}elsecout << "error occurs in row " << row << ", miss identity!" << endl;}else if(syn == 71){inFile >> word >> syn;if(word == "="){Expression();}elsecout << "error occurs in row " << row << ", miss \"=\"!" << endl;}}}inFile.close();}int main(){GrammerAnalyse();return 0;}。

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

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

编译原理实验报告实验名称:实验二编写递归下降语法分析器实验类型:验证型实验指导教师:何中胜专业班级:13软件四姓名:丁越学号:13030504电子邮箱:862245792@实验地点:秋白楼B720实验成绩:日期:2016年4 月1 日一、实验目的通过设计、编制、调试一个递归下降语法分析程序,实现对词法分析程序所提供的单词序列进行语法检查和结构分析,掌握常用的语法分析方法。

通过本实验,应达到以下目标:1、掌握从源程序文件中读取有效字符的方法和产生源程序的内部表示文件的方法。

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

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

二、实验过程1、分析对象分析算术表达式的 BNF 定义如下:〈算术表达式〉→〈项〉|〈算术表达式〉+〈项〉|〈算术表达式〉-〈项〉〈项〉→〈因式〉|〈项〉*〈因式〉|〈项〉/〈因式〉〈因式〉→〈变量〉│(〈算术表达式〉)〈变量〉→i用符号表示如下:E→T|E+T|E-TT→F|T*F|T/FF→i│(E)递归下降分析程序实现思想简单易懂。

程序结构和语法产生式有直接的对应关系。

因为每个过程表示一个非终结符号的处理,添加语义加工工作比较方便。

递归下降分析程序的实现思想是:识别程序由一组子程序组成。

每个子程序对应于一个非终结符号。

每一个子程序的功能是:选择正确的右部,扫描完相应的字。

在右部中有非终结符号时,调用该非终结符号对应的子程序来完成。

自上向下分析过程中,如果带回溯,则分析过程是穷举所有可能的推导,看是否能推导出待检查的符号串。

分析速度慢。

而无回溯的自上向下分析技术,当选择某非终结符的产生时,可根据输入串的当前符号以及各产生式右部首符号而进行,效率高,且不易出错。

无回溯的自上向下分析技术可用的先决条件是:无左递归和无回溯。

无左递归:既没有直接左递归,也没有间接左递归。

无回溯:对于任一非终结符号 U 的产生式右部x1|x2|…|xn,其对应的字的首终结符号两两不相交。

2. 递归下降语法分析流程图实验分为五个模块,分别是:E( )函数,E1( )函数,T( )函数,T1( )函数,F( )函数。

实验二:语法分析(递归下降法)

实验二:语法分析(递归下降法)

实验二:语法分析(递归下降法)一、实验目的1、掌握语法分析的基本原理;2、掌握递归下降的分析法;3、熟悉C语言程序设计。

二、实验准备微机CPU主频1.3G以上,128M内存,安装好C语言,PASCAL语言,或C++。

三、实验时间2学时四、实验内容已给语言文法,写出该文法的递归下降法语法分析器。

输入:源符号串。

输出:语法是否合法。

:文法:(1) <程序> ::= begin<语句串>end(2) <语句串> ::= <语句>{;<语句>}(3) <语句> ::= <赋值语句>(4) <赋值语句> ::= ID:=<表达式>(5) <表达式> ::= <项>{+<项>|-<项>}(6) <项> ::= <因子>{*<因子>|/<因子>}(7) <因子> ::= ID|NUM|(<表达式>)五:源程序:lrparser()对应 <程序>yucu() 对应 <语句串>statement() 对应 <语句>expression()对应 <表达式>term() 对应 <项>factor() 对应 <因子>关键字,数字,字母,符号对应码如下"begin", "if", "then", "while", "do", "end" 1——6字母 10 数字11+,-,*,/,:,:=,<,<>,<=,>,>=,=,;,(,),# 13——28,0factor()#include "stdio.h"#include "string.h"char prog[80], token[8];char ch;int syn, p, m, n, sum, kk=0;char *rwtab[6]={"begin", "if", "then", "while", "do", "end"};void scaner();void lrparser();void yucu();void statement();void expression();void term();void factor();void main(){p=0;printf("Please input string:\n");do{scanf("%c", &ch);prog[p++]=ch;}while(ch!='#'); //当遇到‘#’,结束输入p=0;scaner();lrparser();}void scaner(){for(n=0; n<8; n++) token[n]=NULL;ch=prog[p++];while(ch==' '||ch=='\n') ch=prog[p++];m=0;if((ch>='A'&&ch<='Z') || (ch>='a'&&ch<='z')){while((ch>='A'&&ch<='Z') || (ch>='a'&&ch<='z')||(ch>='0'&&ch<='9')){token[m++]=ch;ch=prog[p++];//将prog数组的字母复制到ch数组中}token[m++]='\0';//把token的末尾设置结束符\0p--;//标记到当前token数组中不是字母的当前位置syn=10; //标记字母的对应码for(n=0; n<6; n++){if(strcmp(token, rwtab[n])==0)//判断token对应rwtab中的哪一个,并进行对应赋对应码{syn=n+1;break;}}}else if(ch>='0'&&ch<='9'){sum=0;while(ch>='0'&&ch<='9'){sum=sum*10+ch-'0';//number用来记录所对应的数字ch=prog[p++];}p--;syn=11;//标记数字的对应码}else{switch(ch){case '<':m=0;token[m++]=ch;ch=prog[p++];if(ch=='>'){syn=21; //标记”<>”的对应码token[m++]=ch;}else if(ch=='='){syn=22; //标记”<=”的对应码token[m++]=ch;}else{syn=20; //标记”<”的对应码p--;}break;case '>':token[m++]=ch;ch=prog[p++];if(ch=='='){syn=24; //标记”>=”的对应码token[m++]=ch;}else{syn=23; //标记”>”的对应码p--;}break;case ':':token[m++]=ch;ch=prog[p++];if(ch=='='){syn=18; //标记”:=”的对应码token[m++]=ch;}else{syn=17; //标记”:”的对应码p--;}break;case '+':syn=13; //标记”+”的对应码token[m++]=ch;break;case '-':syn=14; //标记”-”的对应码token[m++]=ch;break;case '*':syn=15; //标记”*”的对应码token[m++]=ch;break;case '/':syn=16; //标记”/”的对应码token[m++]=ch;break;case '=':syn=25; //标记”=”的对应码token[m++]=ch;break;case ';':syn=26; //标记”;”的对应码token[m++]=ch;break;case '(':syn=27; //标记”(”的对应码token[m++]=ch;break;case ')':syn=28; //标记”)”的对应码token[m++]=ch;break;case '#':syn=0; //标记”#”的对应码token[m++]=ch;break;default:syn=-1; //当不是上述字母,数字,符号时,设置syn=-1 }token[m++]='\0';}}void factor()//因子{if(syn==10 || syn==11) //当扫描的是数字或字母时,继续扫描{scaner();}else if(syn==27) //当扫描的‘(’时,继续扫描{scaner();expression();if(syn==28) //当扫描的是‘)’时,继续扫描scaner();else{kk=1;printf("ERROR: )错误\n");//表达式缺乏‘)‘,出错}}else{kk=1;printf("ERROR: 表达式错误\n");//扫描表达式,表达式开头不是‘(‘,出错}}void term()//项{factor();while(syn==15 || syn==16) //当开头扫描的是’*’或’/’时,继续扫描{scaner();factor();}}void expression()//表达式{term();while(syn==13 || syn==14) //当开头扫描的是’+’或’-’时,继续扫描{scaner();term();}}void statement()//语句{if(syn==10) //当开头扫描的是字母时,继续扫描{scaner();if(syn==18) //扫描的是’:=’时,继续扫描{scaner();expression();}else{kk=1;printf("ERROR: 赋值号错误\n");//当扫描的是’:=’,出错}}else{kk=1;printf("ERROR: 语句错误\n");}}void yucu()//语句串{statement();while(syn==26) //当开始扫描到的是’;’,继续扫描{scaner();statement();}}void lrparser()//程序{if(syn==1) //当开头扫描的是‘begin‘时,继续扫描{scaner();yucu();if(syn==6){scaner();if(syn==0 && kk==0) //当数字串的最后扫描的是‘#‘,而且并无出错,分析成功printf("success!\n");else if(syn!=0 && kk==0){kk=1;printf("ERROR: END后未正常结束\n");//数字串的最后并没有扫描到符号‘#‘,出// 错}}else{if(kk!=1){kk=1;printf("ERROR: 缺少end\n");//程序分析结束并没有扫描到’end’,出错}}}else{kk=1;printf("ERROR: begin错误\n");//开始时并没有扫描到’begin’,出错}}。

自顶向下分析——递归下降法

自顶向下分析——递归下降法

假设有文法
Z→aBa
B→bB |c
则相应的递归子程序可如下:
ReadToken
procedure Z( )
procedure B ( )
begin
begin
if token=a then Match(a);
B;
ReadToken
Match(a)
else err( )
end;
if token = b then Match(b); B;
else if token = c then Match(c); else err( )
end;
主程序:Begin ReadToken; Z end
产生式A→被选择的条件是: 当前的输入符属于predict(A→)。
至多一个产生式被选择的条件是: predict(A→k) predict(A→j )=,当k j
if tokenPredict(A2) then (2) else …… if tokenPredict(An) then (n) else err( )
end 其中对i=X1X2…Xn,(i) = ’(X1);’(X2);…;’(Xn); 如果XVN,’(X)= X 如果XVT,’(X)= Match(X) 如果X= , () = skip(空语句)
自顶向下分析——递归下降法
递归下降法(Recursive-Descent Parsing) 对每个非终极符按其产生式结构产生相应 语法分析子程序. 终极符产生匹配命令 非终极符则产生调用命令 文法递归相应子程序也递归,所以称这种 方法为递归子程序方法或递归下降法。
例:Stm→ while Exp do Stm 则对应产生式右部的语法分析程序部 分如下: begin Match($while); Exp; Match($do); Stm end

语法分析——递归下降分析法

语法分析——递归下降分析法

实验2 语法分析——递归下降分析法一、实验目的1、通过该课程设计要学会用消除左递归的方法来使文法满足进行确定自顶向下分析的条件。

2、学会用C/C++高级程序设计语言来设计一个递归下降分析法的语法分析器;3、通过该课程设计,加深对语法分析理论的理解,培养动手实践的能力。

二、设计内容参考算数运算的递归子程序构造方法及代码,完成以下任务:构造布尔表达式的文法,并编写其递归子程序。

程序设计语言中的布尔表达式有两个作用,一是计算逻辑值,更多的情况是二,用作改变控制流语句中条件表达式,如在if-then,if-then-else或是while-do 语句中使用。

布尔表达式是由布尔算符(and,or,not)施予布尔变量或关系运算表达式而成。

为简单起见,以如下文法生成的布尔表达式作为设计对象:E→E and E | E or E | not E | i rop i | true | falsei→标识符|数字rop→>= | > | <= | < | == | <>以上文法带有二义性,并且未消除左递归,请对之处理后,再构造递归下降程序。

可适当减少工作量,暂时忽略id的定义,输入时直接用数字或字母表示。

三、语法分析器的功能该语法分析器能够分析词法分析器的结果,即单词二元式。

在输入单词二元式后,能输出分析的结果。

四、算法分析1、语法分析的相关知识;2、递归子程序法的相关理论知识;3、根据递归子程序法相关理论,具体针对文法的每一条规则编写相应得递归子程序以及分析过程等。

//在递归子程序的编写过程中,当要识别一个非终结符时,需时刻留意该非终结符的FIRST集与FOLLOW集。

程序示例一:G:P→begin d;X end G’:P→begin d;X endX→d;X|Y X→d;X|YY→Y;s|s Y→sZ Z→;sZ|ε相应的递归子程序设计如下:P(){ if(token==“begin“){ Read(token);If(token==’d’)Read(token);ElseERROR;If (token==’;’)Read(token);ElseERROR;If (token==’d’ || ‘s’)X();Else ERROR;If(token==’end’) OK;}Else ERROR;}X() //X→d;X|Y{if(token==’d’){read(token);if(token==’;’)read(token);elseERROR;If(token==’d’)X();Else if (token==’s’) //注意:对Y的识别也可以是在X的过程中一开始就进行,所以在最外层分支中,加上一个token==s的分支Y();Else ERROR;}Else ERROR;}Y() //Y→sZ{if(token==’s’){read(token);If(token==’;’ || ‘end’)Z();Else ERROR;Else ERROR;}Z() //Z→;s Z|ε{if(token==’;’){read(token);If(token==’s’)Read(token);Else ERROR;If(token==’;’)Z();Else if (token==’end’) // 类似的,这里对于读到end,也要最外层添加一个分支Return;Else ERROR;}Else ERROR;}程序示例二(参考代码):构造文法G[E]:E→E + T | T T→T * F | F F→(E)| d的递归子程序(即语法分析器)。

编译原理实验报告二递归下降语法分析程序 (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. 消除二义性:确保文法中每个产生式都只有一个确定的意义。

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. 实验分析通过本次实验,我们深入了解了递归下降分析法的原理和应用。

在编写递归下降分析程序的过程中,我们学会了如何根据文法设计程序结构,以及如何实现分析过程。

同时,我们还掌握了如何对输入的符号串进行分析,并输出分析结果。

实验过程中,我们遇到了一些问题,如消除二义性、消除左递归、提取左因子等。

通过查阅资料和不断尝试,我们成功解决了这些问题。

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

实验二递归下降法判断算术表达式的正确性
学时数:2-4
一、实验目的和要求
1、用递归下降技术实现语法分析器;
2、理解自顶向下语法分析方法;
3、熟练掌握预测分析程序的构造方法。

二、实验内容
算术表达式的文法是G[E]:
E→E+T| T
T→T*F| F
F→(E)| i
用递归下降分析法按文法G[E]对算术表达式(包括+、*、()的算术表达式)进行语法分析,判断该表达式是否正确。

三、实验步骤
1、准备:阅读课本有关章节,将上述算术表达式的文法改造成LL(1)文法(即消除左递
归和提取左公因子);按P87例4.12编写程序。

2、上机调试,发现错误,分析错误,再修改完善。

四、测试要求
1、为降低难度,表达式中不含变量(只含单个无符号整数或i);
2、如果遇到错误的表达式,应输出错误提示信息(该信息越详细越好);
3、测试用的表达式建议事先放在文本文件中,一行存放一个表达式,以分号结束。


语法分析程序的输出结果写在另一个文本文件中;
4、选作:对学有余力的同学,可增加功能:当判断一个表达式正确时,输出计算结果。

5、程序输入/输出示例:
如参考C语言的运算符。

输入如下表达式(以分号为结束)和输出结果:
(a)1; 或 i;
输出:正确
(b)1+2; 或 i+i;
输出:正确
(c)(1+2)*3+4-(5+6*7); 或 (i+i)*i+i-(i+i*i);
输出:正确
(d)((1+2)*3+4 或 ((i+i)*i+i;
输出:错误,缺少右括号
(e)1+2+3+(*4/5) 或 i+i+i+(*4/5);
输出:错误
五、实验报告要求
1、写出修改后LL(1)文法
2、通过对核心代码做注释或通过程序流程图的方式说明递归下降分析程序的实现思想。

3、写出调试程序出现的问题及解决的方法。

4、给出测试的结果。

六、思考(选作)
文法G[E]所构造算术表达式只包含+和*。

请修改文法和程序,使得该语法程序可判断包含减号和除号的算术表达式的正确性。

[实验指导]
将文法G[E]改造为LL(1)文法如下:
G’[E]:
E → TE’
E’→ +TE’| ε
T → FT’
T’→ *FT’|ε
F → (E)| i
[补充说明]
预测分析法分析程序可以从网上下载,但要求:
(1)理解该程序,在实验报告中说明该程序所使用的文法及修改后的文法;
(2)实验报告要求同上。

相关文档
最新文档