递归下降分析程序的设计和实现

递归下降分析程序的设计和实现递归下降分析程序的设计和实现一 实验的目的和要求 1 了解语法分析的主要任务 2 实现基本的递归下降分析器 能够分析任意的符号串是否为该文法所定义的合法算术表达式 二 实验环境 Windows7 Dev C 三 实验准备先将递归下降分析程序的生成认真的学习一遍 理解递归下降分析程序的构成过程 已知文法 G S S aB bD B bC C aS

递归下降分析程序的设计和实现

一、实验的目的和要求
1、了解语法分析的主要任务。 2、实现基本的递归下降分析器,能够分析任意的符号串是否为该文法所定义的合法算术表达式。 
二、实验环境
Windows7 + Dev-C++ 
三、实验准备
先将递归下降分析程序的生成认真的学习一遍,理解递归下降分析程序的构成过程。 已知文法G[S]: S → aB | bD B → bC C → aS | bD | ε D → aB | bD | ε 
  1. 经观察此文法不含左公因式,也不含左递归,求出此文法的FIRST、FOLLOW以及SELECT集。
产生式 FIRST FOLLOW SELECT
S → aB {a} {#} {a}
S → bD {b} {b}
B → bC {b} {#} {b}
C → aS {a} {#} {a}
C → bD {b} {#} {b}
C → ε {ε} {#}
D → aB {a} {#} {a}
D → bD {b} {b}
D → ε {ε} {#}
  1. 因为S、B、C、D的SELECT集有交集且为空,所以此文法为LL(1)文法。
  2. 测试用例如下(文法推导所得,推导过程略):
    ab abb abaab ababbbbbbbbb bbbbbbbbbbbbbbbbbbbbbbbbbbb baaaaabbbb(错误用例) ab#(错误用例) abcdefg(错误用例) ABCDEFG(错误用例) 
四、实验内容及步骤

1. 用递归下降分析程序测试自己写的文法

#include<stdio.h> // 函数声明 void S(void); void B(void); void C(void); void D(void); // 定义一个长度为100的字符数组 char s[100]; // 用来作数组索引,当每次匹配成功存入数据时index自增1 int i; // 用来标记语句是否正确 int SIGN; int main() { 
    printf("please input a yuju ends with #\n"); // 一个死循环 while( 1 ) { 
    SIGN = 0;//语句是否正确用SIGN i=0; // 类似Java中的Scanner,读取输入的字符串 scanf("%s",&s[0]); // 当输入的第一个字符为#时,程序直接结束 if( s[0] == '#') return 0; S(); // 如果最后的字符以#结束则输出下面 if(s[i] == '#' && SIGN == 0){ 
    printf("This is a right yuju!\n"); }else{ 
    printf("This a wrong yuju\n"); } printf("please input a yuju ends with #\n"); } return 1; } void S() { 
    if(SIGN==0) { 
    // 当输入的字符串中首字母为a时 if(s[i]=='a'){ 
    ++i; // 自增操作 B(); }else if(s[i]=='b'){ 
    ++i; D(); }else{ 
    SIGN=1; } } } void B() { 
    if(SIGN==0){ 
    if(s[i]=='b'){ 
    ++i; C(); }else if(s[i] == '#'){ 
    SIGN=1; } } } void C() { 
    if(SIGN==0){ 
    if(s[i]=='a'){ 
    ++i; S(); }else if(s[i]=='b'){ 
    ++i; D(); }else if(s[i]!='#'){ 
    SIGN=1; } } } void D() { 
    if(SIGN==0){ 
    if(s[i]=='a'){ 
    ++i; B(); }else if(s[i]=='b'){ 
    ++i; D(); }else if(s[i]!='#'){ 
    SIGN=1; } } } 

注: 此代码正好100行,不过可以看出代码质量很差(冗余代码很多),每个函数中的功能都是一样的,应该抽取一下,代码应该可以简洁很多。

2. 测试用例测试如下
在这里插入图片描述

五、实验小结

1. 遇到的主要问题
答:
刚开始测试测试用例时,根据文法推导的句子在程序中一直报错,首先我确定自己推导没有问题,又看了程序代码好像也没有问题,找了好久没有找到,最后使用Xcode(Mac平台下由apple公司维护用来开发iPhone程序和Mac程序的一款集成开发环境)打断点通过单步调试把问题找了出来,因为我把s[i] = ‘p’ 写成了s[i] = ‘P’ 将小写字母写成了大写。这就表现出调试程序的重要性,通过调试可以看计算机如何一步步来执行程序的,对程序有更好的理解。(附上一张调试图)
在这里插入图片描述
这是S函数,当我从控制台录入pba时,第一个字符p和s[i]相同,但是当程序执行直接从39行调到了45行,没有执行if(s[i] == ‘P’)语句,我才找到上面所说的错误!



3. 得到的经验
答:
①:C语言函数声明,这和Java以及其他编程语言不相同,当在main()函数中调用其他函数时,编译器会在main()函数上面找这些函数,如果函数没有声明就会编译报错(找不到),若将函数写在main()函数上,就不会报错。
②:首先更加清晰的理解了语法分析的主要任务,它是在词法分析的基础上将单词组合起来,组成一些语句,比如说在Java中,public static void main(String[]args);方法中,如果void写在public前面编译器就会报错,那是因为编译器已经做好了语法分析的工作,说白了对源代码在结构是否正确这就是语法分析的任务。
③:理解了递归下降分析法,它是一种自顶向下的分析,根据文法来构造C函数,遇到终结符时通过和自己在屏幕中录入的数据作比较,若相同修改数组索引,这个终结符后面若是一个非终结符则调用这个非终结符的函数。一层一层的向下分析,有时会在函数体中调用自己,这就形成了递归。



版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/232674.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 微软校招试题

    把微软的这个笔试题贴出来,纯粹是为了方便大家学习交流,相信微软不会那么小气来追究我的责任吧。确实觉得微软出的这些题都不错,虽然只有20道选择,但是考察的面很全,数据结构,网络,算法,操作系统,概率等等

    2021年12月25日
    50
  • Linux安装CUDA的正确姿势[通俗易懂]

    Linux安装CUDA的正确姿势CUDA(ComputeUnifiedDeviceArchitecture,统一计算架构)是由NVIDIA所推出的一种集成技术,是该公司对于GPGPU的正式名称。透过这个技术,用户可利用NVIDIA的GeForce8以后的GPU和较新的QuadroGPU进行计算。查看显卡是否支持CUDA输入下面命令查看电脑的NVIDIA型号:v…

    2022年4月18日
    1.7K
  • js二维码生成器_url生成二维码

    js二维码生成器_url生成二维码二维码又称QRCode,是一个近几年来移动设备上很流行的一种编码方式它比传统的一维码(条形码)能存更多的信息,也能表示更多的数据类型。按照一定规律排列组成的几何图形构成,它巧妙地利用构成计算机内部逻辑基础的“0”、“1”比特流的概念生活中的应用也是非常的广泛人们的生活方方面面都离不开二维码,而且她也给人们带来了极大的便利。<br><br>(二维码自动识别)二维码有哪些优缺点:优点:1.高密度编码,信息容量大。 2.编码范围广。 3.容错能力强,..

    2022年10月10日
    2
  • css 半透明滚动条「建议收藏」

    css 半透明滚动条「建议收藏」::-webkit-scrollbar{width:10px;height:10px;}::-webkit-scrollbar-thumb{background:hsl(0,0%,51%);-webkit-box-shadow:none;border-radius:10px;-webkit-box-shadow:none;}::-webki…

    2022年7月13日
    14
  • linux中的ldd命令简介

    linux中的ldd命令简介在linux中,有些命令是大家通用的,比如ls,rm,mv,cp等等,这些我觉得没有必要再细说了。而有些命令,只有开发人员才会用到的,这类命令,作为程序员的我们,是有必要了解的,有的甚至需要熟练使用。有的人总说,这些命令不重要,用的时候去查就行了,这么多么扯淡的说法啊。具体用法细节是可以可查,但至少得知道有ldd这个东西吧。连ldd都不知道,怎么知道ldd是干啥的呢?

    2022年4月28日
    76
  • 阿里矢量图标_ui矢量图

    阿里矢量图标_ui矢量图阿里iconfunt官网对于图标的调用写的不够详细,许多初用者不会用,下面具体介绍下总结的两种方法:一、在线调用方式1、首先建立新浪微博账号,用微博号登录iconfunt官网;2、所需要图标加入

    2022年8月1日
    7

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号