设计三:语法分析之递归下降分析法

一、实验目的:

    根据某一文法编制调试递归下降分析程序,以便对任意输入的符号串进行分析。本次实验的目的主要是加深对递归下降分析法的理解。

二、实验预习提示

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为前进一个字符函数。

三、实验过程和指导:

(一)准备:

1.阅读课本有关章节,

2.考虑好设计方案;

3.设计出模块结构、测试数据,初步编制好程序。

(二)上课上机:

将源代码拷贝到机上调试,发现错误,再修改完善。第二次上机调试通过。

(三)程序要求:

程序输入/输出示例:

对下列文法,用递归下降分析法对任意输入的符号串进行分析:

(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)递归下降分析程序,编制人:姓名,学号,班级

(2)输入一以#结束的符号串(包括+—*/()i#):在此位置输入符号串例如:i+i*i#

(3)输出结果:i+i*i#为合法符号串

 

备注:输入一符号串如i+i*#,要求输出为“非法的符号串”。

引用也要改变)。

注意:1.表达式中允许使用运算符(+-*/)、分割符(括号)、字符I,结束符#;

2.如果遇到错误的表达式,应输出错误提示信息(该信息越详细越好);

3.对学有余力的同学,可以详细的输出推导的过程,即详细列出每一步使用的产生式。

 

(四)程序思路(仅供参考):

0.定义部分:定义常量、变量、数据结构。

1.初始化:从文件将输入符号串输入到字符缓冲区中。

2.利用递归下降分析法分析,对每个非终结符编写函数,在主函数中调用文法开始符号的函数。

(五)练习该实验的目的和思路:

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

(六)为了能设计好程序,注意以下事情:

1.模块设计:将程序分成合理的多个模块(函数),每个模块做具体的同一事情。

2.写出(画出)设计方案:模块关系简图、流程图、全局变量、函数接口等。

3.编程时注意编程风格:空行的使用、注释的使用、缩进的使用等。

#include <bits/stdc++.h>
#define EMPTY 0
#define ERROR -1
#define RIGHT 1

using namespace std;

void S();
void F();
void E();
void T();
void G();
void NextChar();

int index = 0;
string s = "";

int main()
{
    
    cin>>s;
    E();
    cout<<s<<"是合法的符号串!"<<endl;
    return 0;
}

void S()
{
    if(s[index] != '#')
    {
        if(s[index] == '*' || s[index] == '/')
        {
            NextChar();
            int now_index = index;
            F();
            S();
            if(s[now_index] != 'i')
            {
                cout<<"非法符号串"<<endl;
                exit(0);
            }
        }
    }
}

void F()
{
    if(s[index] != '#')
    {
        if(s[index] == '(')
        {
            NextChar();
            E();
            if(s[index]==')')
            {
                index++;
            }
            else
            {
                cout<<"非法的符号串!"<<endl;
                exit(0);
            }
        }
        else if(s[index] == 'i')
        {
            NextChar();
        }
    }
}

void G()
{
    if(s[index] != '#')
    {
        if(s[index] == '+' || s[index] == '-')
        {
            NextChar();
            int now_index = index;
            T();
            G();
            if(s[now_index] != 'i')
            {
                cout<<"非法符号串"<<endl;
                exit(0);
            }
        }
    }
}

void T()
{
    if(s[index] != '#')
    {
        F();
        S();
    }
}

void E()
{
    if(s[index] != '#')
    {
        T();
        G();
    }
    else if (s[index] != '#' && index == 0)
    {
        cout<<"空符号串"<<endl;
        exit(0);
    }
}

void NextChar()
{
    index++;
}

 

  • 6
    点赞
  • 56
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值