递归子程序法实现语法分析器

预习报告

实验题目:递归子程序法实现语法分析器

一、实验目的

1.学习语法分析器的构造原理,掌握递归下降法的编程方法。

2.编制一个递归下降分析程序,实现对词法分析程序所提供的单词序列的语法检查和结构分析。

二、实验原理

     语法分析器从词法分析器获得一个词素序列,并验证这个序列是否可以由源语言的文法生成。语法分析器会构造一棵语法分析树,并把它传递给编译器的其他部分进一步处理,在构建语法分析树的过程中,就验证了这个词素序列是否符合源语言的文法。语法分析器的任务主要是确定是否可以以及如何从语法的起始符号推导出输入符号串(输入文本),主要可以通过两种方式完成:自顶向下分析(根据形式语法规则,在语法分析树的自顶向下展开中搜索输入符号串可能的最左推导。单词按从左到右的顺序依次使用)、自底向上分析(语法分析器从现有的输入符号串开始,尝试将其根据给定的形式语法规则进行改写,最终改写为语法的起始符号)。递归子程序法也称为递归下降分析法。该方法的实现思想是:对文法中的每个非终结符号U都编写出一个子程序,以完成该非终结符号所对应的语法成分的分析和识别任务。高级程序设计语言的语法规则通常都是用上下文无关文法来描述的,文法中的符号分为终结符号和非终结符号。

三、实验要求

1.功能要求

自动区分终结符号VT和非终结符号VN

消除直接左递归、间接左递归和提取左公因子(未实现)

自动生成FIRST和FOLLOW集合

自动判断是否是LL(1)文法

自动构建预测分析表

输入要分析的单词串自动输出分析过程

2.待分析的源程序的输入形式和识别后单词的输出形式

明确输入以文件输入,输出二元组中单词种别码的表述形式。

  1. 算法设计

本次实验采用递归下降分析算法,该算法分析程序由一组子程序组成,每个非终结符按其产生式结构写出相应的子程序,每个子程序的名字可以用该非终结符表示。

子程序的编写:每匹配一个终结符,则再读入一个符号;对于非终结符,则调用相应的子程序。当一个非终结符有多个候选式,可按选择集SELECT来决定选用哪个候选式 。通过子程序间的相互调用实现对输入串的识别。

语法分析就是根据高级语言的语法规则对程序的语法结构进行分析。语法分析的任务就是在词法分析识别出正确的单词符号串是否符合语言的语法规则,分析并识别各种语法成分,同时进行语法检查和错误处理,为语义分析和代码生成做准备。判断依据是对给定的输入符号串能否根据文法的规则建立起一颗语法树。自上而下的语法分析方法就是对任何输入串(由token串构成的源程序),从文法开始符号(根结点)出发,自上而下的为输入串建立一棵语法树,或者说,为输入串寻找一个最左推导。

void lrparser();            /*声明语法分析函数*/

void statementString();     /*声明语句串分析函数*/

void statement();           /*声明语句分析函数*/

void expression();          /*声明(等号右边的)表达式分析函数*/

void term();                /*声明项分析函数*/

void factor();              /*声明因子分析函数*/

实验报告

实验题目:递归子程序法实现语法分析器

一、概述
    本次实验的任务是使用递归子程序法实现一个简单的语法分析器,能够对输入的程序代码进行语法分析,并输出相应的语法树。在实验中使用了C++语言来实现该语法分析器。
在实验中首先设计了一个文法,然后根据该文法编写了相应的递归子程序,用于对输入的程序代码进行语法分析。在语法分析的过程中使用了递归下降的方法,即每个非终结符对应一个递归子程序,用于对该非终结符进行语法分析。在递归子程序中,使用了LL(1)分析表,用于确定下一个输入符号应该是哪个终结符或非终结符。 LL(1)分析表是一种常用的语法分析表,其构造简单,能够有效地处理大部分文法。
    本实验的亮点在于递归子程序法实现语法分析器,递归子程序法是一种常用的语法分析方法,其实现简单,易于理解。在本次实验中,使用递归子程序法实现了一个简单的语法分析器,能够对输入的程序代码进行语法分析,并输出相应的语法树。
    通过本次实验,深入了解了递归子程序法和LL(1)分析表的原理和实现方法,掌握了语法分析的基本技术和方法,同时对编译原理的理论和实践都有了更深入的了解和认识。

二、实验方案

1. 分析器的结构

预处理:按行读取文本信息,生成字符流信息;

读取流信息,识别单词:读取每行的每一个字符,交由分析函数处理;

用递归子程序法对识别出的所有单词进行语法分析;

将输出保存并输出到指定文件。

  1. 语法分析器的设计步骤

子程序的编写:每匹配一个终结符,则再读入一个符号;对于非终结符,则调用相应的子程序。当一个非终结符有多个候选式,可按选择集SELECT来决定选用哪个候选式。

通过子程序间的相互调用实现对输入串的识别。

注意:由于文法的定义通常是递归的,分析程序也常具有递归结构,所以也称为递归子程序法

3. 法分析器的程序流程图

三、实验过程及结果分析

1.测试过程

测试数据1:   (i)#

测试结果:

测试数据2:

(abc)#

测试结果:

2.调试分析

本次实验遇到了以下问题:语法分析器需要使用符号表来存储变量和函数等信息,在处理变量和函数时,需要对符号表进行读写操作,由于符号表存在错误,导致语法分析器无法正确分析语法。解决办法是对符号表进行仔细的设计和实现,并且在语法分析器中正确地使用符号表。对程序进行测试时。由于测试不充分,可能会导致无法发现潜在的错误。解决办法是设计良好的测试用例,并且对程序进行全面的测试,特别是对边界情况进行测试。

四、总结与体会

本次实验是使用递归子程序法实现语法分析器,通过实验掌握编译原理中语法分析的基本方法和技巧,对于加深对编译原理的理解和掌握具有重要意义。整个实验的难度适中,通过提前预习课堂上的相关知识,让我能够快速上手完成实验。通过实验,我深刻认识到了语法分析的重要性,只有正确的语法分析才能保证编译器的正确性和效率。
    实验结果与预期相符。在实验过程中逐步完成了语法分析器的构建,并成功地对输入的代码进行了语法分析。通过实验,我对递归子程序法的原理和实现方法有了更深入的了解。在实验过程中,也遇到了一些困难,例如在编写递归子程序时,需要注意递归调用的顺序和参数传递的正确性,否则会导致程序出错。为了解决这些问题,通过查找资料并结合实际情况进行调试和修改,最终成功地完成了实验。
    本次实验让我深刻认识到了语法分析的重要性,掌握了递归子程序法的实现方法和技巧,对于加深对编译原理的理解和掌握具有重要意义。同时,也让我更加深入地理解了课程理论知识,为后续的学习和实践打下了坚实的基础。

  • 17
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实验2 语法分析 一、 实验目的 编制一个递归下降分析程序,实现对词法分析程序所提供的单词序列的语法检查和结构分析。 二、 实验内容 利用C语言编制递归下降分析程序,并对简单语言进行语法分析。 1、 待分析的简单语言的语法 用扩充的BNF表示如下: (1)::=beginend (2)::={;} (3)::= (4)::=ID:= (5)::={+|-} (6)::={*|/} (7)::=ID| NUM|() 2、实验要求说明 输入单词串,以“#”结束,如果是文法正确的句,则输出成功信息,打印“success”,否则输出“error”。 三、 结果验证 1. 输入:begin_a:=9;_x:=2*3;_b:=a+x_end# 输出:success! 2. 分别验证其他错误(至少2个) 四、 语法分析程序的源程序代码 #include #include #include char prog[80],token[8]; char ch; int syn,p,m=0,n,sum=0,kk; //p是缓冲区prog的指针,m是token的指针 char *rwtab[6]={"begin","if","then","while","do","end"}; void scaner(); void factor(); void term(); void expression(); void statement(); #include #include #include char prog[80],token[8]; char ch; int syn,p,m=0,n,sum=0; //p是缓冲区prog的指针,m是token的指针 char *rwtab[6]={"begin","if","then","while","do","end"}; void scaner() { 同实验一代码 } void factor() { …完成函数代码 } void term() { ……完成函数代码 } void expression() { ……完成函数代码 } void statement() {//cout<<"调用statement,syn="<<syn<<endl; if(判断语句) {scaner(); if(syn==18) {//cout<<"syn=18"<<endl; scaner(); expression(); } else{cout<<"缺:=错误!"<<endl;kk=1;} } else {cout<<"error!"<<endl;kk=1;} return; } void yucu() {…..完成函数代码 } //return; } void lrparser() {//cout<<"调用Irparser"<<endl; if(syn==1) {scaner(); yucu(); if(syn==6){scaner(); if(syn==0&&(kk==0)) cout<<"success!"<<endl; } else {if(kk!=1) cout<<"缺end错误!"<<endl;kk=1;} } else{cout<<"缺begin错误!"<<endl;kk=1;} //return; } void main() {p=0; cout<>ch; 执行语句3; }while(ch!='#'); p=0; scaner(); lrparser(); //cout<<syn<<','<<kk<<endl; }

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值