编译原理--递归下降分析实验C++

一、实验项目要求

1.实验目的

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

2.实验要求

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

(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.如果遇到错误的表达式,应输出错误提示信息(该信息越详细越好);

二、理论分析或算法分析

1、程序设计:

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

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

(3)程序编写:

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

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

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

三、实验方法

程序流程图如图所示:

四、实验结果分析

实验结果图

遇到的问题

(1)遇到如图所示的问题:

解决办法

(1)在文件顶部加入一行#define _CRT_SECURE_NO_WARNINGS后可以解决;

通过本次实验,学习了语法分析,让我对语法分析有了一定的认识和了解。递归下降分析法,是一种确定的自顶向下分析技术,它的实现思想是,对文法分别代表一种语法成分的每个非终结符号编写一个子程序,已完成非终结符号所对应的语法成分的分析任务。在分析过程中调用一系列过程或函数,对源程序进行语法语义分析直到整个程序处理结束;即使理解了理论知识,我也不一定会编程。

五、代码

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include<dos.h>
#include<stdlib.h>
#include<string.h>char a[50], b[50], d[500], e[10];
char ch;
int n1, i1 = 0, flag = 1, n = 5;
int E();
int E1();
int T();
int G();
int S();
int F();
void input();
void input1();
void output();
void main()                      /*递归分析*/
{int f, p, j = 0;char x;d[0] = 'E';d[1] = '=';d[2] = '>';d[3] = 'T';d[4] = 'G';d[5] = '#';printf("递归下降分析程序,编制人:***,**号,******班\n");printf("输入一以#结束的符号串(包括+ - * / ( ) i #,且长度小于50):");do {scanf("%c", &ch);a[j] = ch;j++;} while (ch != '#');n1 = j;ch = b[0] = a[0];printf("文法\t分析串\t\t\t分析字符\t\t剩余串\n");f = E1();if (f == 0) return;if (ch == '#'){printf("accept\n");p = 0;x = d[p];//	{//			printf("%c",x);p=p+1;x=d[p];          /*输出推导式*///		}	while (a[p] != '#')printf("%c", a[p++]);printf("为合法字符!\n");}else {//	printf("error\n");j = 0;while (a[j] != '#')printf("%c", a[j++]);printf("非法字符!\n");printf("回车返回\n");getchar(); getchar();return;}printf("\n");printf("回车返回\n");getchar();getchar();
}
int E1()
{int f, t;printf("E-->TG\t");flag = 1;input();input1();f = T();if (f == 0) return(0);t = G();if (t == 0) return(0);else return(1);
}int E()
{int f, t;printf("E-->TG\t");e[0] = 'E'; e[1] = '='; e[2] = '>'; e[3] = 'T'; e[4] = 'G'; e[5] = '#';output();flag = 1;input();input1();f = T();if (f == 0)return(0);t = G();if (t == 0) return(0);else return(1);
}
int T()
{int f, t;printf("T-->FS\t");e[0] = 'T'; e[1] = '='; e[2] = '>'; e[3] = 'F'; e[4] = 'S'; e[5] = '#';output();flag = 1;input();input1();f = F();if (f == 0)return(0);t = S();if (t == 0) return(0);else return(1);
}
int  G()
{int f;if (ch == '+'){b[i1] = ch;printf("G-->+TG\t");e[0] = 'G'; e[1] = '='; e[2] = '>'; e[3] = '+'; e[4] = 'T'; e[5] = 'G'; e[6] = '#';output();flag = 0;input(); input1();ch = a[++i1];f = T();if (f == 0)return(0);f = G();if (f == 0)return 0;else return 1;}else if (ch == '-'){b[i1] = ch;printf("G-->-TG\t");e[0] = 'G'; e[1] = '='; e[2] = '>'; e[3] = '-'; e[4] = 'T'; e[5] = 'G'; e[6] = '#';output();flag = 0;input(); input1();ch = a[++i1];f = T();if (f == 0){//			printf("G=%d\n",f);return(0);}f = G();if (f == 0)return 0;else return 1;}else{printf("G-->^\t");e[0] = 'G'; e[1] = '='; e[2] = '>'; e[3] = '^'; e[4] = '#';output();flag = 1;input(); input1();return(1);}
}int S()
{int f, t;if (ch == '*'){b[i1] = ch;printf("S-->*FS\t");e[0] = 'S'; e[1] = '='; e[2] = '>'; e[3] = '*'; e[4] = 'F'; e[5] = 'S'; e[6] = '#';output();flag = 0;input(); input1();ch = a[++i1];f = F();if (f == 0)return(0);t = S();if (t == 0)return(0);else return(1);}else if (ch == '/'){b[i1] = ch;printf("S-->/FS\t");e[0] = 'S'; e[1] = '='; e[2] = '>'; e[3] = '/'; e[4] = 'F'; e[5] = 'S'; e[6] = '#';output();flag = 0;input(); input1();ch = a[++i1];f = F();if (f == 0)return(0);t = S();if (t == 0)return(0);else return(1);}else{printf("S-->^\t");e[0] = 'S'; e[1] = '='; e[2] = '>'; e[3] = '^'; e[4] = '#';output();flag = 1;a[i1] = ch;input(); input1();return(1);}
}
int F()
{int f; int j;if (ch == '('){b[i1] = ch;printf("F-->(E)\t");e[0] = 'F'; e[1] = '='; e[2] = '>'; e[3] = '('; e[4] = 'E'; e[5] = ')'; e[6] = '#';output();flag = 0;input(); input1();ch = a[++i1];f = E();if (f == 0) return(0);if (ch == ')'){b[i1] = ch;printf("F-->(E)\t");flag = 0; input(); input1();ch = a[++i1];}else{printf("error\n");j = 0;while (a[j] != '#')printf("%c", a[j++]);printf("非法字符!\n");return(0);}}else if (ch == 'i'){b[i1] = ch;printf("F-->i\t");e[0] = 'F'; e[1] = '='; e[2] = '>'; e[3] = 'i'; e[4] = '#';output();flag = 0; input(); input1();ch = a[++i1];}else {printf("error\n");j = 0;while (a[j] != '#')printf("%c", a[j++]);printf("非法字符!\n");return(0);}return(1);
}
void input()
{int j = 0;for (; j <= i1 - flag; j++)printf("%c", b[j]);                    /*输出分析串*/printf("\t\t\t");printf("%c\t\t\t", ch);                  /*输出分析字符*/
}void input1()
{int j;for (j = i1 + 1 - flag; j < n1; j++)printf("%c", a[j]);                     /*输出剩余字符*/printf("\n");
}
void output() {                              /*推导式计算*/int m, k, j, q;int i = 0;m = 0; k = 0; q = 0;i = n;d[n] = '='; d[n + 1] = '>'; d[n + 2] = '#'; n = n + 2; i = n;i = i - 2;while (d[i] != '>'&&i != 0) i = i - 1;i = i + 1;while (d[i] != e[0]) i = i + 1;q = i;m = q; k = q;while (d[m] != '>')  m = m - 1;m = m + 1;while (m != q) {d[n] = d[m]; m = m + 1; n = n + 1;}d[n] = '#';for (j = 3; e[j] != '#'; j++) {d[n] = e[j];n = n + 1;}k = k + 1;while (d[k] != '=') {d[n] = d[k]; n = n + 1; k = k + 1;}d[n] = '#';
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/361454.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vue中通过js控制页面样式方法

在使用vue.js框架的时候&#xff0c;有时候会希望在页面渲染完成之后&#xff0c;再执行函数方法来处理初始化相关的操作&#xff0c;如果只处理页面位置、宽或者高时&#xff0c;必须要在页面完全渲染之后才可以&#xff0c;页面没有加载完成之前&#xff0c;获取到的宽高不准…

快速指南:剖析JBoss BPM跨进程通信

&#xff08;文章来宾与北美红帽公司高级解决方案架构师杰伊保拉杰共同撰写&#xff09; 几周的提示与技巧文章将深入探讨JBoss BPM Suite&#xff0c;特别是有关如何在两个流程之间进行通信的问题。 在进入解决方案详细信息之前&#xff0c;让我们首先约束将要讨论的用例。 …

使用命令行工具创建WildFly OpenShift应用程序

通过使用快速入门&#xff0c;可以在OpenShift上轻松配置WildFly的新实例。 只需单击一下&#xff0c;您就可以准备就绪&#xff01; 通常&#xff0c;OpenShift的高级用户使用命令行工具 。 但是&#xff0c;您无法使用CLI工具创建WildFly墨盒。 但现在已解决错误1134134 。 …

word-break属性和css换行显示

这几天在做项目的时候&#xff0c;遇到了比较棘手的问题&#xff0c;便是在一个标签里边展示内容&#xff0c;如果说展示中文汉字&#xff0c;一点问题都没有&#xff0c;但是只要连续展示英文字母或者中文的标点符号&#xff08;中间不带空格&#xff09;&#xff0c;那么所渲…

第四种行转列

--动态处理 select A.StuName,A.BZKTypeName,cast(A.BKCODE as varbinary(MAX)) even, row_number() over (partition by StuName,BZKTypeName order by getdate()) ID into #t1 from BKLIST A --where StuName林健辉 declare sql1 varchar(max) declare sql2…

React-router的基本使用

1、安装使用 $ npm install -S react-router import { Router, Route, hashHistory } from react-router;render((<Router history{hashHistory}><Route path"/" component{App}/></Router> ), document.getElementById(app)); 1.1、版本问题 reac…

九宫格有规律高亮滚动效果

前几天朋友去面试&#xff0c;面试官要求当场用九宫格写出一个滚动有规律的大转盘滚动高亮效果&#xff0c;结果可想而知。如下图&#xff1a; 也就是说当页面刚进来的时候&#xff0c;红色方块在左上角&#xff0c;接下来按照图上所标注的箭头方向来依次循环。当我听说了这个面…

使用Maven原型高效创建Eclipse模块

Maven Archetype是一个项目模板工具包&#xff0c;可为开发人员提供生成内置或自定义脚手架工件的参数化版本的方法。 最近&#xff0c;我将其应用于我们的Xiliary P2存储库&#xff0c;以实现Eclipse模块存根创建的自动化。 由于效果很好&#xff0c;所以我认为值得在这篇文章…

framelayout

编写的mail.xml文件: <?xml version"1.0" encoding"utf-8"?><FrameLayout xmlns:android"http://schemas.android.com/apk/res/android" android:id"id/frame" android:layout_width"fill_parent" android:layou…

扩展Asterisk1.8.7的CLI接口

我之前有一篇文章&#xff08;http://www.cnblogs.com/MikeZhang/archive/2012/04/14/asteriskCLIAppTest20120414.html&#xff09;介绍过如何扩展asterisk的cli接口&#xff0c;本篇是它的继续&#xff0c;总结下&#xff0c;也方便我以后查阅。 大部分情况下&#xff0c;配置…

CSS中的 ',' 、''、'+'、'~'

1、群组选择器&#xff08;,&#xff09; /* 表示既h1&#xff0c;又h2 */ h1, h2 {color: red; } 2、后代选择器&#xff08;空格&#xff09; /* 表示 h1 下面的所有 span 元素&#xff0c;不管是否以 h1 为直接父元素 */ h1 span {} 3、子元素选择器&#xff08;>&#x…

单片机第三季-第七课:STM32中断体系

目录 1&#xff0c;NVIC 2&#xff0c;中断和事件的区别 3&#xff0c;优先级的概念 4&#xff0c;如何实际编程使用外部中断 5&#xff0c;STM32开发板通过按键控制LED 5.1&#xff0c;打开相应GPIO模块时钟 5.2&#xff0c;NVIC设置 5.3&#xff0c;外部中断线和配套…

【学亮IT手记】angularJS select2多选下拉框实例

永远保持对大部分知识的好奇心&#xff0c;学习从不枯燥&#xff0c;也没有被逼学习一说&#xff0c;乐此不疲才是该有的心态和境界&#xff01;&#xff01;&#xff01; 引入相关js库&#xff1a; html部分代码&#xff1a; angularJS定义数据源变量&#xff1a; 更多专业前端…

Devoxx Hackergarten的企业Web应用程序原型

我已经连续10年参加DevoxxBe了 。 这是我最喜欢的Java会议&#xff0c;但是谈话时间表并不总是最佳的&#xff1a;有时我想同时看2个精彩的谈话&#xff01; 因此&#xff0c;在Devoxx的Hackergarten&#xff0c;在参加讲座之间&#xff0c;我们中的一些人开始构建Web应用程序以…

谈一谈Http Request 与 Http Response

谈一谈Http Request 与 Http Response   写在前面的话&#xff1a;最近帮朋友弄弄微信商城&#xff0c;对于微信的基础开发&#xff0c;基本上就是各种post、get&#xff0c;有时是微信服务器向我们的服务器post、get数据&#xff0c;有时需要我们自己的服务器向微信服务器各…

增压的jstack:如何以100mph的速度调试服务器

使用jstack调试实时Java生产服务器的指南 jstack就像U2一样-从时间的黎明就一直在我们身边&#xff0c;我们似乎无法摆脱它 。 除了笑话&#xff0c;到目前为止&#xff0c;jstack是您调试军用生产服务器中最方便的工具之一。 即便如此&#xff0c;我仍然认为它在情况恶化时能够…

Zabbix监控多个JVM进程

一、场景说明&#xff1a; 我们这边的环境用的是微服务&#xff0c;每个程序都是有单独的进程及单独的端口号&#xff0c;但用jps查询出来的结果有些还会有重名的情况&#xff0c;所以某些脚本不太适用本场景&#xff1b; 二、需求说明&#xff1a; 需使用Zabbix-server监控每个…

Android 4.0 Launcher源码分析系列(二)

原文&#xff1a;http://mobile.51cto.com/hot-314700.htm 上一节我们研究了Launcher的整体结构&#xff0c;这一节我们看看整个Laucher的入口点&#xff0c;同时Laucher在加载了它的布局文件Laucher.xml时都干了些什么。 我们在源代码中可以找到LauncherApplication&#xff0…

使用JFace Viewer延迟获取模型元素

Eclipse JFace Viewers显示的模型元素有时需要花费大量时间来加载。 因此&#xff0c; 工作台提供了IDeferredWorkbenchAdapter类型以在后台获取此类模型元素。 不幸的是&#xff0c;似乎仅通过DeferredTreeContentManager派生的AbstractTreeViewer支持此机制。 因此&#xff…

Eclipse扩展的轻量级集成测试

最近&#xff0c;我为Eclipse扩展点评估引入了一个小助手。 辅助程序努力减少通用编程步骤的样板代码&#xff0c;同时增加开发指导和可读性。 这篇文章是希望的后续文章&#xff0c;展示了如何将实用程序与AssertJ定制断言结合使用&#xff0c;以编写针对Eclipse扩展的轻量级…