LR--用栈实现移进--归约分析(demo)
1.考虑文法
\(E->E+E\)
\(E->E*E\)
\(E->id\)
2.最右推导
不难看出,这个文法是而二义的,所以有多个最右推导
3.移进归约
用一个栈存文法符号,用输入缓存区保存要分析的输入串,用$标记栈底
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<stack>
using namespace std;
stack<string> stk, tmp;
string w;
bool flag = false;
int main(void) {
cin >> w; //输入串
w += "$"; //加上标识符
printf("----------|----------|----------\n");
printf(" 栈 | 输入 | 动作 \n");
printf("----------|----------|----------\n");
int now = 0; //当前扫描字符位置
while (!flag) {
now = 0;
if (stk.empty()) { //如果一开始栈为空,直接移进符号
stk.push("$");
cout << "$ |";
cout.setf(ios::right); //设置字符对其方式
cout.width(10); //设置字符宽度
cout << w;
cout<< "|移进" << endl;
printf("----------|----------|----------\n");
string tt;
if (w[now] == 'i') { //移进符号为id
tt = "id";
now = 2;
}
else { //移进符号不为id
tt = w[now];
now = 1;
}
stk.push(tt); //将符号压入栈
w = w.substr(now, w.size() - now); //丢弃已扫描的字符
continue;
}
while (!stk.empty()) { //用两个栈来回倒,输出字符
tmp.push(stk.top());
stk.pop();
}
while (!tmp.empty()) {
cout << tmp.top();
stk.push(tmp.top());
tmp.pop();
}
if (stk.top() == "id") { //E-->id归约,优先级最高
cout.width(10-stk.size());
cout << "|";
cout.setf(ios::right); //设置字符对其方式
cout.width(10); //设置字符宽度
cout << w;
cout<< "|按E-->id进行归约" << endl;
printf("----------|----------|----------\n");
stk.pop();
stk.push("E");
continue;
}
if (w[now]=='$'&&stk.size() == 2 && stk.top() == "E") { //接受状态
flag = true;
cout<< " | $|接受"<< endl;
printf("----------|----------|----------\n");
continue;
}
if (w[now]!='$') { //移进字符
string tp;
if (w[now] == 'i') {
tp = "id";
now = 2;
}
else {
tp = w[now];
now = 1;
}
cout.width(11 - stk.size());
cout << "|";
cout.setf(ios::right); //设置字符对其方式
cout.width(10); //设置字符宽度
cout << w;
cout<< "|移进" << endl;
printf("----------|----------|----------\n");
stk.push(tp);
w = w.substr(now, w.size() - now); //丢弃已扫描的字符
continue;
}
if (w[now] == '$' &&!flag) { //E-->E+E或者E-->E*E归约
string tc;
tc = stk.top();
if (tc == "E")
stk.pop();
tc += stk.top();
if (stk.top() != "E") {
stk.pop();
tc += stk.top();
cout.setf(ios::right); //设置字符对其方式
cout.width(9- stk.size());//设置字符宽度
cout << "|";
cout << " $|";
cout << "按E-->"<<tc<<"归约" << endl;
printf("----------|----------|----------\n");
stk.pop();
stk.push("E");
}
}
}
return 0;
}
4.Sample
输入
id*id+id

5.To be continued.
LR--用栈实现移进--归约分析(demo)的更多相关文章
- Java性能分析之线程栈详解与性能分析
Java性能分析之线程栈详解 Java性能分析迈不过去的一个关键点是线程栈,新的性能班级也讲到了JVM这一块,所以本篇文章对线程栈进行基础知识普及以及如何对线程栈进行性能分析. 基本概念 线程堆栈也称 ...
- 表单input中提示文字value随鼠标焦点移进移出而显示或隐藏的
jQuery代码 <input value="请输入用户名" type="text"> <input value="请输入密码&qu ...
- 大数据江湖之即席查询与分析(下篇)--手把手教你搭建即席查询与分析Demo
上篇小弟分享了几个“即席查询与分析”的典型案例,引起了不少共鸣,好多小伙伴迫不及待地追问我们:说好的“手把手教你搭建即席查询与分析Demo”啥时候能出?说到就得做到,差啥不能差人品,本篇只分享技术干货 ...
- C语言函数调用时候内存中栈的动态变化详细分析(彩图)
版权声明:本文为博主原创文章,未经博主允许不得转载.欢迎联系我qq2488890051 https://blog.csdn.net/kangkanglhb88008/article/details/8 ...
- Apache Flink:特性、概念、组件栈、架构及原理分析
2016-04-30 22:24:39 Yanjun Apache Flink是一个面向分布式数据流处理和批量数据处理的开源计算平台,它能够基于同一个Flink运行时(Flink Runtim ...
- CVE-2018-18820 icecast 栈缓冲区越界写漏洞分析
前言 icecast 是一款开源的流媒体服务器 , 当服务器配置了 url 认证时,服务器在处理 HTTP 头部字段时错误的使用了 snprintf 导致栈缓冲区的越界写漏洞( CVE-2018-18 ...
- Android可见APP的不可见任务栈(TaskRecord)销毁分析
Android依托Java型虚拟机,OOM是经常遇到的问题,那么在快达到OOM的时候,系统难道不能回收部分界面来达到缩减开支的目的码?在系统内存不足的情况下,可以通过AMS及LowMemoryKill ...
- linux内核中打印栈回溯信息 - dump_stack()函数分析【转】
转自:http://blog.csdn.net/jasonchen_gbd/article/details/45585133 版权声明:本文为博主原创文章,转载请附上原博链接. 目录(?)[-] ...
- 栈的讲解 和 栈的生长方向 源代码技巧分析,简直没SEI 啦
函数的局部变量,都是存放在"栈"里面,栈的英文是:STACK.STACK的大小,我们可以在stm32的启动文件里面设置,以战舰stm32开发板为例,在startup_stm32f1 ...
随机推荐
- 图片(imageView)
图片(imageView): 常用属性: android:scaleType(图片显示的格式) android:src(图片源,一般使用的资源) android:scaleType属性的常用取值 0. ...
- Android Weekly Notes Issue #247
Android Weekly Issue #247 March 5th, 2017 Android Weekly Issue #247. 本期内容包括: 离线模式的实现; RxJava2的测试支持; ...
- C# 串口
/// <summary> /// 串口初始化 /// </summary> private void OpenSerialPort ...
- pytorch 文本输入处理
https://blog.csdn.net/nlpuser/article/details/88067167 https://blog.csdn.net/u012436149/article/deta ...
- react入门参考资料
ReactJS简介 React 起源于 Facebook 的内部项目,因为该公司对市场上所有 JavaScript MVC 框架,都不满意,就决定自己写一套,用来架设 Instagram 的网站.做出 ...
- SpringMVC与shiro集成及配置文件说明!
在项目中xml文件的配置是必不可少的,特别是SpringMVC框架.但是几乎所有项目的配置都是大同小异,很多人都是直接复制黏贴了事,不少人对其具体含义及用途都不甚全知.本片文章将正对项目中常用的框架S ...
- jquery遍历之children()与find()的区别
hildren(selector) 方法是返回匹配元素集合中每个元素的所有子元素(仅儿子辈).参数可选,添加参数表示通过选择器进行过滤,对元素进行筛选. .find(selector)方法是返回匹配元 ...
- 【心得体会】我考完MOS我明白了…
[心得体会]我考完MOS我明白了… 原创 2017-11-10 MSP-李桑榆 MSPrecious成长荟 MOS备考 这篇文章写给还没有考或者准备考MOS的同学 网上有很多介绍MOS考试的 http ...
- 【解决方案】[XCUITest] WDA is not listening at 'http://localhost:8100/'
1. 使用Xcode 编译 WebDriver 发现端口为:serverurlhere->http://手机ip:0 <-serverurlhere 2. 解决方案: xcodebuild ...
- Angular2 constructor VS ngOnInit
constructor和ngOnInit钩子有什么不同? constructor constructor(构造函数)是ES6类或TypeScript类中的特殊方法,而不是Angular的方法,主要用来 ...