递归下降语法分析程序设计

合集下载

递归下降法

递归下降法
例 设有文法G[E]: E→ E + T | T T→ T * F | F F→ (E) | id
试构造一个识别该文法句子的递归下 降分析程序。
递归下降分析法
分析 首先消去文法左递归,得到文法 G'[E]
E→E + T |T T→T * F |F
F→(E) | id
E → TE' E'→ +TE' | ε T → FT' T'→ *FT' | ε F → (E) | id
T( ); E'( ); }
E'( )
E → TE'
{
E' → +TE' | ε
if (sym = =‘+’) {
GetSym( );
T → FT ' T ' → *FT ' | ε
F → (E) | id
T();
E ( );
}
else if ((sym!=‘)’)&&(sym!=‘#’))
error( );
递归下降分析法
递归下降分析法是确定的自上 而下分析法,这种分析法要求文 法是LL(1)文法。
递归下降分析法
基本思想 对文法中的每个非终结符编写一个函
数 (或子程序), 每个函数(或子程序)的 功能是识别由该非终结符所表示的语法成 分。由于描述语言的文法常常是递归定义 的,因此相应的这组函数(或子程序)必 然以相互递归的方式进行调用,所以将此 种分析法称为递归下降分析法。
F→ (E) | id
递归下降分析法
该文法是LL(1)文法,其递归下降分 析程序中主函数和函数F( )同上,对函 数E( )和函数T( )用while语句描述如下:

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

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

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

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

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

编译原理递归下降分析法C语言编译原理是计算机科学中的一个重要领域,主要研究如何将高级语言程序转化为机器可执行的目标代码。

在编译原理中,递归下降分析法是一种常用的语法分析方法,它通过递归地从上至下对程序进行分析,最终确定程序的语法结构。

递归下降分析法是一种自顶向下的语法分析方法,基于产生式和预测分析表来实现对程序的语法分析。

该方法的基本思想是,每个非终结符对应一个处理过程,通过递归调用这些处理过程来分析整个程序。

在C语言的递归下降分析法中,需要定义对应C语言语法结构的处理过程,这些处理过程通常对应于C语言中的各种语句、表达式、声明等。

递归下降分析法的实现主要包括两个步骤:构造预测分析表和编写递归下降分析程序。

预测分析表是一个二维表格,行对应于非终结符,列对应于终结符,表格中的每个元素记录了该产生式的编号。

通过预测分析表,可以预测下一个分析符号,并选择相应的产生式进行语法分析。

编写递归下降分析程序时,首先需要确定递归下降分析程序的数据结构和接口。

一般来说,分析程序的数据结构包括符号栈、语法树等,接口包括初始化、语法分析、错误处理等。

接下来,根据语法规则编写对应的递归下降分析函数,每个函数对应一个非终结符的处理过程。

在实际编写过程中,通常使用递归调用来实现对程序的逐步分析,直到达到终结符。

递归下降分析法在C语言编译器中的应用非常广泛。

通过该方法,可以对C语言程序进行语法分析,检测代码中的语法错误,并生成相应的语法树。

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

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

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

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

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

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

编译原理实验报告实验名称:实验二编写递归下降语法分析器实验类型:验证型实验指导教师:何中胜专业班级: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.定义语法产生式规则:首先需要定义待分析的文法的产生式规则。

产生式规则由左部和右部组成,左部表示非终结符,右部表示由终结符和非终结符组成的字符串。

例如,对于表达式文法E->E+T,T,E为非终结符,+为终结符,T为非终结符,表示一个表达式可以是一个表达式加一个项,或者仅仅是一个项。

2.构建预测分析表:根据产生式规则,构建一个预测分析表。

预测分析表是一个二维表,由非终结符和终结符构成,表中的每个元素表示哪个产生式规则应该被应用。

例如,对于表达式文法,预测分析表可能如下所示:, + , * , id , ( , ) ,---,---,---,---,---,---,--E,-,-,T,T,-,T,F,-,F,F,-,F , - , - , id , (E), - ,表中的'-'代表无动作。

3.实现递归函数:根据预测分析表中的产生式规则,实现对应的递归函数。

每个非终结符对应一个递归函数,函数的实现根据当前输入符号和预测分析表中选择对应的产生式规则进行推导。

例如,对于表达式文法,可以定义如下的递归函数:```pythondef E(:if symbol == '+':match('+')TEelif symbol == 'id' or symbol == '(':TEelse:# Errordef T(:if symbol == '+':FTelif symbol == 'id' or symbol == '(':FTelse:# Errordef F(:if symbol == 'id':match('id')elif symbol == '(':match('(')Ematch(')')else:# Error```在每个递归函数中,首先需要判断当前输入符号与预测分析表的元素是否匹配,如果匹配则进行相应的操作(例如推导产生式、移动指针等),如果不匹配则报错。

《递归下降分析法》实验报告

《递归下降分析法》实验报告

《编译原理》课程实验报告姓名: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)⽂法。

递归下降程序实验报告

递归下降程序实验报告

一、实验目的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.将文法规则转换为程序中的递归子程序。

每个递归子程序对应一个语法片段,并按照文法规则递归地扩展子节点。

3.设计词法分析器将输入的语法串分词为单个有效的词法单元。

4.从语法树的根节点开始,根据递归子程序逐步扩展子节点,直到达到终结符。

同时,将每一步的扩展结果记录在语法树中。

接下来,我们需要构建语法分析器。

语法分析器是一个根据语法规则判断输入语法串是否符合语法规则的程序。

它可以通过递归下降分析法来实现。

具体来说,我们可以通过以下步骤来构建语法分析器:1.定义一个语法分析器的函数,作为程序的入口。

2.在语法分析器函数中,根据文法规则调用递归子程序,分析输入的语法串。

3.每个递归子程序对应一个语法片段,它会对输入的语法串进行识别和匹配,并根据文法规则进行扩展。

4.如果递归子程序无法匹配当前的输入,那么意味着输入的语法串不符合文法规则。

5.如果递归子程序成功扩展,并继续匹配下一个输入,则语法分析器会一直进行下去,直到分析完整个语法串。

总结起来,递归下降分析法是一种简单而有效的语法分析方法。

它通过构建递归子程序来解析输入的语法串,并构造出对应的语法树。

虽然递归下降分析法在处理左递归和回溯等问题上存在一定的困难,但它仍然是一种重要的语法分析方法,被广泛应用于编译器和自然语言处理等领域。

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

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

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

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

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

编译原理词法分析和语法分析报告+代码(C语言版)[1]

编译原理词法分析和语法分析报告+代码(C语言版)[1]

词法分析一、实验目的二、设计、编制并调试一个词法分析程序, 加深对词法分析原理的理解。

三、实验要求2.1 待分析的简单的词法(1)关键字:begin if then while do end所有的关键字都是小写。

(2)运算符和界符: = + - * / < <= <> > >= = ; ( ) #(3)其他单词是标识符(ID)和整型常数(SUM), 通过以下正规式定义:ID = letter (letter | digit)*NUM = digit digit*(4)空格有空白、制表符和换行符组成。

空格一般用来分隔ID.SUM、运算符、界符和关键字, 词法分析阶段通常被忽略。

2.2 各种单词符号对应的种别码:输入: 所给文法的源程序字符串。

输出: 二元组(syn,token或sum)构成的序列。

其中: syn为单词种别码;token为存放的单词自身字符串;sum为整型常数。

例如: 对源程序begin x:=9: if x>9 then x:=2*x+1/3; end #的源文件, 经过词法分析后输出如下序列:(1,begin)(10,x)(18,:=)(11,9)(26,;)(2,if)……三、词法分析程序的算法思想:算法的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号, 其基本思想是根据扫描到单词符号的第一个字符的种类, 拼出相应的单词符号。

3.1 主程序示意图:主程序示意图如图3-1所示。

其中初始包括以下两个方面:⑴关键字表的初值。

关键字作为特殊标识符处理, 把它们预先安排在一张表格中(称为关键字表), 当扫描程序识别出标识符时, 查关键字表。

如能查到匹配的单词, 则该单词为关键字, 否则为一般标识符。

关键字表为一个字符串数组, 其描述如下:Char *rwtab[6] = {“begin”, “if”, “then”, “while”, “do”, “end”,};图3-1(2)程序中需要用到的主要变量为syn,token和sum3.2 扫描子程序的算法思想:首先设置3个变量: ①token用来存放构成单词符号的字符串;②sum用来整型单词;③syn 用来存放单词符号的种别码。

编译原理实验(递归向下语法分析法实验)

编译原理实验(递归向下语法分析法实验)

//定义一个数组大小常量
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-递归下降法

第四章3-递归下降法

注意
对于具有多个产生式的非终极符,可用 Case语句进行多分支选择 到底选择哪个产生式进行分析呢? 产生式A→被选择的条件是: 当前要匹配的输入符属于predict(A→)。

问题
例如: 文法中有:A →ac A → ab A的两个产生式的预测集合中都有a,该 调用哪个产生式呢? Swithc(symb){ case a:{….} case a:{….} }
while x>y do if x>z then x:= x+y else x:= y
Begin Match($while); Exp; Match($do); Stm
End
具有多个产生式的非终极符

当产生式中形如: A 1| 2| …| n 则按下面的方法编写子程序A: procedure A( ) begin if tokenPredict(A1) then (1) else if tokenPredict(A2) then (2) else …… if tokenPredict(An) then (n) else err( ) end 其中对i=X1X2…Xn,(i) = ’(X1);’(X2);…;’(Xn); 如果XiVN,’(Xi)= Xi 如果XiVT,’(Xi)= Match(Xi) 如果Xi= , () = skip(空语句)
具有多个产生式的非终极符

当产生式中形如: A 1| 2| …| n 也可以写成 则按下面的方法编写子程序A: Case结构 procedure A( ) begin if tokenPredict(A1) then (1) else if tokenPredict(A2) then (2) else …… if tokenPredict(An) then (n) else err( ) end 其中对i=X1X2…Xn,(i) = ’(X1);’(X2);…;’(Xn); 如果XiVN,’(Xi)= Xi 如果XiVT,’(Xi)= Match(Xi) 如果Xi= , () = skip(空语句)

编译原理——语法分析程序设计实验报告

编译原理——语法分析程序设计实验报告

实验二语法分析程序设计[实验目的]:1.了解语法分析的主要任务。

2.熟悉编译程序的编制。

[实验内容]:根据某文法,构造一基本递归下降语法分析程序。

给出分析过程中所用的产生式序列。

[实验要求]:1.选择一个文法,进行实验,可选的文法包括以下三个:P190 4.8P190 4.9P190 4.102.设计语法分析程序的输出形式(输出应为语法树或推导),一个可以参考的例子,可见图1。

3.编写递归下降语法分析程序(参考P148-149 Topdown parsing byrecursive-descent),实现基本的递归下降分析器,能够分析任给的符号串是否为该文法所定义的合法句子。

实验报告中要说明分析使用的方法。

4.根据所作业题选项e所给出的input,生成并输出分析过程中所用的产生式序列(show the actions of parser):1 产生式12 产生式2……5.自已设计一个不合法的句子,作为输出进行分析,给出结果。

[实验过程]本次实验选择的文法为P190 4.8lexp->atom|listatom->number|identifierlist->(lexp-seq)lexp-seq->lexp lexp-seq1.写出实现的算法,并画流程图。

本次实验采用递归下降算法,算法流程图如下图1-1:图1-1 算法流程图2.根据你选择的文法,分析左递归或左因子是否会影响本算法的结果。

会影响本算法的结果。

递归下降分析法要求的文法是LL(1)文法,需要消除左递归和左因子的影响。

如果存在左因子,对相同的字符跳转到不同的函数,无法实现递归。

3.列举实验设计过程中出现的问题及解决的方法(至少3条,选择实验中最困扰的问题)。

1).会多次输出accept/error结果解决方案:所有的递归函数返回类型为int,若accept返回1,error返回0,在main主函数中统一判断输出语句。

语法分析器的实现

语法分析器的实现

语法分析器的实现
一.课程设计成员
组长:
成员:
二.实验目的
采用自上而下的语法分析方法,实现对词法分析程序所提供的单词序列的语法检查和结构分析。

三.实验要求
利用C++语言编写自上而下(递归下降)语法分析程序,实现对简单语言进行语法分析。

待分析的简单语言的语法(用扩充的BNF表示)如下:
⑴<程序>-> <语句串>
⑵<语句串>-><语句>{;<语句>}
⑶<语句>-><赋值语句>
⑷<赋值语句>->ID=<表达式>
⑸<表达式>-><项>{+<项> | -<项>}
⑹<项>-><因子>{*<因子> | /<因子>
⑺<因子>->ID | NUM | (<表达式>)
四、实验输入、输出
输入单词串,以“#”结束,如果是文法正确的句子,则输出成功信息,打印“success”,否则指出错误位置和错误原因。

例如:
输入y=x+2;#
输出success!
Int a,b,c;
输入x=a+bc; #
输出错误原因和位置
五、语法分析程序的算法思想(流程图)
六、算法实现
参考:(1)教材第4、5章语法分析
(2)教材第10章编译程序实现范例
(3)网络资料。

LL(!)语法分析

LL(!)语法分析

LL(1)语法分析一、实验目的:理解语法分析程序的主要任务和实现技术。

二、实验内容:为无二义性表达式文法G[E]构造语法分析程序G[E]: E->E+T|T T->T*F|F F->(E)|i三、实验要求:1.用递归下降分析方法实现,要求能够对正确的和错误的输入串进行分析,给出分析结果(accept/error)。

2.程序输入为形如i+i*i# 或者ii#的串,输出为推导所用的产生式序列四、程序流程图#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <stack>using namespace std;struct Node1{char vn;char vt;char s[10];}MAP[20];//存储分析预测表每个位置对应的终结符,非终结符,产生式int k;//用R代表E',W代表T',e代表空charG[10][10]={"E->TR","R->+TR","R->e","T->FW","W->*FW","W->e","F->( E)","F->i"};//存储文法中的产生式char VN[6]={'E','R','T','W','F'};//存储非终结符char VT[6]={'i','+','*','(',')','#'};//存储终结符char SELECT[10][10]={"(,i","+","),#","(,i","*","+,),#","(","i"};//存储文法中每个产生式对应的SELECT集charRight[10][8]={"->TR","->+TR","->e","->FW","->*FW","->e","->(E)","->i"} ;stack <char> stak,stak1,stak2;bool compare(char *a,char *b){int i,la=strlen(a),j,lb=strlen(b);for(i=0;i<la;i++)for(j=0;j<lb;j++){if(a[i]==b[j])return 1;}return 0;}char *Find(char vn,char vt){int i;for(i=0;i<k;i++){if(MAP[i].vn==vn && MAP[i].vt==vt)return MAP[i].s;}return "error";}//当非终结符遇到终结符时应采用哪个产生式来推导char * Analyse(char * word){char p,action[10],output[10];int i=1,j,l=strlen(word),k=0,l_act,m;while(!stak.empty())stak.pop();//清空了分析栈stak.push('#');stak.push('E');printf("_____________________________________________________________ ___________________\n");printf("\n 对符号串%s的分析过程\n",word);printf(" 步骤栈顶元素剩余输入串推到所用产生式或匹配\n");p=stak.top();while(p!='#'){printf("%7d ",i++);p=stak.top();stak.pop();//栈顶元素出栈printf("%6c ",p);for(j=k,m=0;j<l;j++)output[m++]=word[j];output[m]='\0';printf("%10s",output);//剩余的输入串if(p==word[k]){if(p=='#'){printf(" 接受\n");return "SUCCESS";}printf(" “%c”匹配\n",p);k++;}else{strcpy(action,Find(p,word[k]));if(strcmp(action,"error")==0){printf(" 没有可用的产生式\n");return "ERROR";}printf(" %c%s\n",p,action);int l_act=strlen(action);//产生式长度if(action[l_act-1]=='e')continue;for(j=l_act-1;j>1;j--)//如果不是空产生式stak.push(action[j]);//将推导用的产生式倒叙入栈}}if(strcmp(output,"#")!=0)return "ERROR";}int main (){char c;int e=0;//freopen("in.txt","r",stdin);// freopen("c:\out.txt","w",stdout);char source[100];int i,j,flag,l,m;printf("\n*****为了方便编写程序,用R代表E',W代表T',e代表空*****\n\n");printf("该文法的产生式如下:\n");for(i=0;i<8;i++)printf(" %s\n",G[i]);printf("_____________________________________________________________ ___________________\n");printf("\n该文法的SELECT集如下:\n");for(i=0;i<8;i++){printf(" SELECT(%s) = { %s }\n",G[i],SELECT[i]);}printf("_____________________________________________________________ ___________________\n");//判断是否是LL(1)文法flag=1;for(i=0;i<8;i++){for(j=i+1;j<8;j++){if(G[i][0]==G[j][0])//产生式左部相同{if(compare(SELECT[i],SELECT[j])){flag=0;break;}}}if(j!=8)break;}if(flag)printf("\n有相同左部产生式的SELECT集合的交集为空,所以文法是LL(1)文法。

递归下降分析器程序(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)。

编译方法实验报告令狐采学实验名称:简单的语法分析程序设计实验要求1.功能:对简单的赋值语句进行语法分析随机输入赋值语句,输出所输入的赋值语句与相应的四元式2.采用递归下降分析程序完成(自上而下的分析)3.确定各个子程序的功能并画出流程图4.文法如下:5.编码、调试通过采用标准输入输出方式。

输入输出的样例如下:【样例输入】x:=a+b*c/d(e+f)【样例输出】(说明,语句和四元式之间用5个空格隔开)T1:=b*c (*,b,c,T1)T2:=T1/d (/,T1,d,T2)T3:=a+T2 (+,a,T2,T3)T4:=e+f (+,e,f,T4)T5:=T3T4 (,T3,T4,T5)x:=T5 (:=,T5,,x)【样例说明】程序除能够正确输出四元式外,当输入的表达式错误时,还应能检测出语法错误,给出相应错误提示。

6.设计35个赋值语句测试实例,检验程序能否输出正确的四元式;当输入错误的句子时,检验程序能够给出语法错误的相应提示信息。

7.报告内容包括:递归程序的调用过程,各子程序的流程图和总控流程图,详细设计,35个测试用例的程序运行截图及相关说明,有详细注释的程序代码清单等。

目录1.语法分析递归下降分析算法51.1背景知识51.2消除左递归62.详细设计及流程图62.1 函数void V( ) // V > a|b|c|d|e...|z62.2 函数void A( ) // A > V:=E72.3 函数void E() //E > TE'72.4函数void T( ) // T > FT'82.5函数void E1( ) //E'> +TE'|TE'|null82.6函数void T1() // T'> *FT'|/FT'|null93.测试用例及截图93.1测试用例1及截图93.2测试用例2及截图103.3测试用例3及截图11代码清单111.语法分析递归下降分析算法1.1背景知识无回溯的自上向下分析技术可用的先决条件是:无左递归和无回溯。

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

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

如果一个文法不含回路,也不含以ε为右部的产生式,那么可以通过执行消除文法左递归的算法消除文法的一切左递归(改写后的文法可能含有以ε为右部的产生式)。

文法的左递归消除算法:1、将文法G的所有非终结符排序为U1 ,U2 ,… ,Un;2、For(i=1;i++;i≥n){for j→1 to i1把产生式Ui→Ujα替换成Ui→β1α| β2α|…|βmα;其中:Uj→ β1| β2 |… |βm 消除Ui产生式中的直接左递归;}3.化简改写之后的文法,删除多余产生式。

文法的直接左递归消除公式:直接左递归形式:U→Ux|y;其中:x,y∈(VN∪VT)* ,y不以U打头。

直接左递归的消除:U→yU‟U‟→xU‟|ε直接左递归的一般形式:U→Ux1|Ux2|…|Uxm|y1|y2|…|yn;其中:xi≠ε ,yi都不以U打头。

一般形式直接左递归的消除:U→y1U‟| y2U‟ |…| ynU‟U‟→x1U‟| x2U‟| …| xmU‟|ε回溯的消除的前提是文法不得含有左递归,可提左因子来消除回溯。

1.2消除左递归根据实验中给出的文法,进行消除左递归及回溯,得到下列的式子A > V:=EE > TE'E'> +TE'|TE'|nullT > FT'T'> *FT'|/FT'|nullF > V|(E)V > a|b|c|d|e...|z2.详细设计及流程图根据消除左递归后的文法,可以编写相应的函数。

2.1 函数void V( ) // V > a|b|c|d|e...|zvoid V() // V > a|b|c|d|e...|z函数设计主要用来识别小写字母的,如果是小写字母的话,放入字符表,不是的话,输出语法错误。

函数比较简单,代码如下:if(islower(s[sym])){Table[list_n][0] = s[sym]; //把读取的小写字母存入符号表,便于分析是生成中间代码Table[list_n][1] = '\0';list_n++;sym++;}else{printf("Operand Errors!\n"); //运算对象错误SIGN=1;exit(0);}2.2函数void A() // A > V:=Evoid A() // A > V:=E函数主要用来实现赋值的操作,流程图如图1所示。

图1 A( ) 函数流程图2.3函数void E() //E > TE'函数E()里面主要递归调用函数T( )和E'( )。

当没有出现语法错误时就可正常的运行。

函数比较简单,代码如下:{if(SIGN==0){T();E1();}}2.4函数void T() // T > FT'函数T()里面主要递归调用函数F ( )和T''( )。

当没有出现语法错误时就可正常的运行。

函数比较简单,代码如下:if(SIGN==0){F();T1();}2.5函数void E1( )//E'> +TE'|TE'|null函数void E1() //E'> +TE'|TE'|null,主要用来实现加减法的语义分析。

流程图如图2所示。

图2 E1 ( ) 函数流程图2.6函数void T1() // T'> *FT'|/FT'|null函数void T1() // T'> *FT'|/FT'|null,主要用来实现乘除法的语义分析。

流程图如图3所示。

图3T1 ( ) 函数流程图3.测试用例及截图3.1测试用例1及截图用例1为实验要求上的的用例。

测试结果图4所示。

图4 测试用例1及结果截图3.2测试用例2及截图用例2为出现大写字母,出现报错。

测试结果图5所示。

图5 测试用例2及结果截图3.3测试用例3及截图用例3为随意编写用例。

测试结果图6所示。

图6 测试用例3及结果截图代码清单#include<stdio.h>#include<stdlib.h>#include<string.h>#include <ctype.h>void A(); // A > V:=Evoid E(); // E > TE'void T(); // T > FT'void E1(); // E'> +TE'|TE'|nullvoid T1(); // T'> *FT'|/FT'|nullvoid F(); // F > V|(E)void V(); // V > a|b|c|d|e...|zchar s[50],n='1'; //s[50]用于存放输入的赋值表达式char Table[50][3]; //产生中间代码所需的符号表int SIGN,sym; //sym为s[50]中当前读入符号的下标int list_n=0; //符号表的下标/*消除左递归及回溯A > V:=EE > TE'E'> +TE'|TE'|nullT > FT'T'> *FT'|/FT'|nullF > V|(E)V > a|b|c|d|e...|z*/int main(){SIGN = 0; //SIGN用于指示赋值表达式是否出现错误sym=0;scanf("%s",&s);if( s[0] == '\0') //没有输入的情况直接退出return 0;A();if(s[sym]!='\0'&&SIGN==0){printf("ERROR!\n");exit(0);}return 0;}void A() // A > V:=E{V();if(s[sym]==':'&&s[sym+1]=='=') //判断赋值号是否有拼写错误{sym+=2;E();printf("%s:=%s",Table[list_n2],Table[list_n1]);printf(" (:=,%s,,%s)\n",Table[list_n1],Table[list_n2]);}else{printf("The assignment Symbol spelling mistakes!\n"); //赋值号拼写错误SIGN=1;exit(0);}}void V() // V > a|b|c|d|e...|z{if(islower(s[sym])){Table[list_n][0] = s[sym]; //把读取的小写字母存入符号表,便于分析是生成中间代码Table[list_n][1] = '\0';list_n++;sym++;}else{printf("Operand Errors!\n"); //运算对象错误SIGN=1;exit(0);}}void E() //E > TE'{if(SIGN==0){T();E1();}}void T() // T > FT'{if(SIGN==0){F();T1();}}void E1() //E'> +TE'|TE'|null{int p;if(SIGN==0){if(s[sym] == '+'||s[sym]==''){p=sym; //用p记录出现'+'或''时sym 的值sym++;T();char ch[3];ch[0] = 'T';ch[1] = n;ch[2] = '\0';if(s[p] == '+'){printf("%s:=%s+%s",ch,Table[list_n2],Table[list_n1]); //输出三地址代码printf(" (+,%s,%s,%s)\n", Table[list_n2],Table[list_n1],ch); //输出四元式}else{printf("%s:=%s%s",ch,Table[list_n2],Table[list_n1]);//输出三地址代码printf(" (,%s,%s,%s)\n", Table[list_n2],Table[list_n1],ch); //输出四元式}strcpy(Table[list_n2],ch); //将当前结果归结式放在符号表中list_n;n++;E1();}}}void T1() // T'> *FT'|/FT'|null{int p;if(SIGN==0){if(s[sym] == '*'||s[sym]=='/'){p=sym;sym++;F();char ch[3];ch[0] = 'T';ch[1] = n;ch[2] = '\0';if(s[p] == '*'){printf("%s:=%s*%s",ch,Table[list_n2],Table[list_n1]); //输出三地址代码printf(" (*,%s,%s,%s)\n",Table[list_n2],Table[list_n1],ch);//输出四元式}else{printf("%s:=%s/%s",ch,Table[list_n2],Table[list_n1]); //输出三地址代码printf(" (/,%s,%s,%s)\n", Table[list_n2],Table[list_n1],ch);//输出四元式}strcpy(Table[list_n2],ch); //将当前结果归结式放在符号表中list_n;n++;T1();}}}void F() //F > V|(E){if(SIGN==0){if(s[sym]=='('){sym++;E();if(s[sym]==')') sym++;else{printf("ERROR!\n");SIGN=1;exit(0);}}else if(islower(s[sym])) //判断s[sym]是否是小写字母V();else{printf("ERROR!\n");SIGN=1;exit(0);}}}。

相关文档
最新文档