编译原理 实验2 语法分析——递归下降分析器

一、核心代码

1.题目要求

练习构造递归下降语法分析程序的方法,熟悉上下文无关文法的使用,加深对课堂教学的理解;提高语法分析方法的实践能力

文法 G[E]:
E→E+T|T
T→T*F|F
F→i|(E)

消除左递归后:
E→TX
X→+TX|^
T→FY
Y→*FY|^
F→i|(E)

要求: 采用递归下降语法分析法编写语法分析程序,该语法分析程序判断输入的字符串是否符合上述文法,并能够输出相应的结果(是语法成分或不是语法成分)。

2.代码实现

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char str[10];
int index = 0;
void E();  // E->TX;
void X();  // X->+TX | e
void T();  // T->FY
void Y();  // Y->*FY | e
void F();  // F->(E) | i
int main() {
    int len;
    int m;
    printf("请输入要测试的次数:");
    scanf("%d", &m);
    while (m--) {
        printf("请输入算数表达式:");
        scanf("%s", str);
        len = strlen(str);
        str[len] = '#';
        str[len + 1] = '\0';
        E();
        if (str[index] == '#')
            printf("正确语句!\n");
        else {
            printf("分析失败!\n");
        }
        strcpy(str, "");
        index = 0;
    }
    return 0;
}
void E() {
    T();
    X();
}
void X() {
    if (str[index] == '+') {
        index++;
        T();
        X();
    }
}
void T() {
    F();
    Y();
}
void Y() {
    if (str[index] == '*') {
        index++;
        F();
        Y();
    }
}
void F() {
    if (str[index] == 'i') {
        index++;
    } else if (str[index] == '(') {
        index++;
        E();
        if (str[index] == ')') {
            index++;
        } else {
            printf("分析失败!\n");
            exit(0);
        }
    } else {
        printf("分析失败!\n");
        exit(0);
    }
}

3.运行结果:

在这里插入图片描述

以上转自 https://blog.csdn.net/niu91/article/details/9155509

二、实现加,减,乘,除运算的表达式文法

1.题目要求

(1)给出不含左递归的,识别加,减,乘,除运算的表达式文法;
(2)采用递归下降分析方法编写识别所定义表达式文法的语法分析器;
(3)任意给出一个表达式句子,判断该表达式是否是合法的句子

文法 G[E]:
E→E+T|E-T|T
T→T*F|T/F|F
F→i|(E)

消除左递归后:
E→TX
X→+TX|-TX|^
T→FY
Y→*FY| /FY^
F→i|(E)

2.代码实现

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
using namespace std;
char str[10];
int index = 0;
void E();  // E->TX;
void X();  // X->+TX|-TX|^
void T();  // T->FY
void Y();  // Y->*FY|/FY|^
void F();  // F->(E) | i
int count;
void rank();
void latter();
int m ,n;
int len;
void analyze();
void remain();
int main() {
    int T;
    printf("请输入要测试的次数:");
    scanf("%d", &T);
    while (T--) {
		count = 0;m = -1,n = -1;index = 0;
        printf("请输入算数表达式:");
        scanf("%s", str);
		len = strlen(str);
		str[len] = '#';
		printf("步骤\t 文法\t\t 分析串\t\t\t分析字符\t\t剩余串\n"); 
        E();
      
       if (str[index] == '#')  printf("正确语句!\n");
		   
       else 
           printf("分析失败!\n");
    }
    return 0;
}
void E() {
	rank();printf("E -> TX\t\t");analyze();latter();remain();
    T();
    X();
}
void X() {
    if (str[index] == '+') {
		rank(); printf("X ->+TX\t\t");m++;n++;analyze();latter();remain();
        index++;
        T();
        X();
    }
   	 else if (str[index] == '-') {
		rank(); printf("X ->-TX\t\t");m++;n++;analyze();latter();remain();
        index++;
        T();
        X();
    }
	else{
		rank();printf("X -> ^\t\t");analyze();latter();remain();}
}
void T() {
	rank();	printf("T -> FY\t\t");analyze();latter();remain();
    F();
    Y();
}
void Y() {
    if (str[index] == '*') {
		rank();printf("Y ->*FY\t\t");m++;n++;analyze();
        latter();remain();index++;
        F();
        Y();
    }
	else if (str[index] == '/') {
		rank();printf("Y ->/FY\t\t");m++;n++;analyze();
        latter();remain();index++;
        F();
        Y();
    }
	else{
		rank();printf("Y -> ^\t\t");analyze();latter();remain();}

}
void F() {
    if (str[index] == 'i') 
	{
		rank();printf("F ->i\t\t");m++;n++;analyze();latter();remain();
        index++;
    } 
	else if (str[index] == '(') 
	{
		rank();printf("F ->(E)\t\t"); m++;n++;analyze();latter();remain();
		index++;
        E();
        if (str[index] == ')') {
			rank();printf("F ->(E)\t\t");m++;n++;analyze();latter();remain();
            index++;
        }else {
            printf("分析失败!\n");
            exit(0);
        }
    } 
	else 
	{
        printf("分析失败!\n");
        exit(0);
    }
}
void rank()
{
	
	printf("%d\t",count);
	count++;
}


void analyze()
{
	if(m<0) cout<<' ';
	else
	{
		for(int i = 0;i <= m;i++)  cout<<str[i]; 
	}
	cout<<'\t'<<'\t'<<'\t';
}

void latter()
{
	printf("%c",str[index]);
	cout<<'\t'<<'\t'<<'\t';
}

void remain()
{
	for(int j = n+1;j <= len;j++)  cout<<str[j];
	cout<<'\n';
}


3.运行结果

(代码本身没有问题滴 17行之后由于分析串太长 导致对不齐)
在这里插入图片描述

  • 15
    点赞
  • 144
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
递归下降分析法 一、实验目的: 根据某一文法编制调试递归下降分析程序,以便对任意输入的符号串进行分析。本次实验的目的主要是加深对递归下降分析法的理解。 二、实验说明 1、递归下降分析法的功能 词法分析器的功能是利用函数之间的递归调用模拟语法树自上而下的构造过程。 2、递归下降分析法的前提 改造文法:消除二义性、消除左递归、提取左因子,判断是否为LL(1)文法, 3、递归下降分析法实验设计思想及算法 为G的每个非终结符号U构造一个递归过程,不妨命名为U。 U的产生式的右边指出这个过程的代码结构: (1)若是终结符号,则和向前看符号对照, 若匹配则向前进一个符号;否则出错。 (2)若是非终结符号,则调用与此非终结符对应的过程。当A的右部有多个产生式时,可用选择结构实现。 三、实验要求 (一)准备: 1.阅读课本有关章节, 2.考虑好设计方案; 3.设计出模块结构、测试数据,初步编制好程序。 (二)上课上机: 将源代码拷贝到机上调试,发现错误,再修改完善。第二次上机调试通过。 (三)程序要求: 程序输入/输出示例: 对下列文法,用递归下降分析法对任意输入的符号串进行分析: (1)E->eBaA (2)A->a|bAcB (3)B->dEd|aC (4)C->e|dc 输出的格式如下: (1)递归下降分析程序,编制人:姓名,学号,班级 (2)输入一以#结束的符号串:在此位置输入符号串例如:eadeaa# (3)输出结果:eadeaa#为合法符号串 注意: 1.如果遇到错误的表达式,应输出错误提示信息(该信息越详细越好); 2.对学有余力的同学,可以详细的输出推导的过程,即详细列出每一步使用的产生式。 (四)程序思路 0.定义部分:定义常量、变量、数据结构。 1.初始化:从文件将输入符号串输入到字符缓冲区中。 2.利用递归下降分析法分析,对每个非终结符编写函数,在主函数中调用文法开始符号的函数。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值