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)的更多相关文章

  1. Java性能分析之线程栈详解与性能分析

    Java性能分析之线程栈详解 Java性能分析迈不过去的一个关键点是线程栈,新的性能班级也讲到了JVM这一块,所以本篇文章对线程栈进行基础知识普及以及如何对线程栈进行性能分析. 基本概念 线程堆栈也称 ...

  2. 表单input中提示文字value随鼠标焦点移进移出而显示或隐藏的

    jQuery代码 <input value="请输入用户名" type="text"> <input value="请输入密码&qu ...

  3. 大数据江湖之即席查询与分析(下篇)--手把手教你搭建即席查询与分析Demo

    上篇小弟分享了几个“即席查询与分析”的典型案例,引起了不少共鸣,好多小伙伴迫不及待地追问我们:说好的“手把手教你搭建即席查询与分析Demo”啥时候能出?说到就得做到,差啥不能差人品,本篇只分享技术干货 ...

  4. C语言函数调用时候内存中栈的动态变化详细分析(彩图)

    版权声明:本文为博主原创文章,未经博主允许不得转载.欢迎联系我qq2488890051 https://blog.csdn.net/kangkanglhb88008/article/details/8 ...

  5. Apache Flink:特性、概念、组件栈、架构及原理分析

     2016-04-30 22:24:39    Yanjun Apache Flink是一个面向分布式数据流处理和批量数据处理的开源计算平台,它能够基于同一个Flink运行时(Flink Runtim ...

  6. CVE-2018-18820 icecast 栈缓冲区越界写漏洞分析

    前言 icecast 是一款开源的流媒体服务器 , 当服务器配置了 url 认证时,服务器在处理 HTTP 头部字段时错误的使用了 snprintf 导致栈缓冲区的越界写漏洞( CVE-2018-18 ...

  7. Android可见APP的不可见任务栈(TaskRecord)销毁分析

    Android依托Java型虚拟机,OOM是经常遇到的问题,那么在快达到OOM的时候,系统难道不能回收部分界面来达到缩减开支的目的码?在系统内存不足的情况下,可以通过AMS及LowMemoryKill ...

  8. linux内核中打印栈回溯信息 - dump_stack()函数分析【转】

    转自:http://blog.csdn.net/jasonchen_gbd/article/details/45585133 版权声明:本文为博主原创文章,转载请附上原博链接.   目录(?)[-] ...

  9. 栈的讲解 和 栈的生长方向 源代码技巧分析,简直没SEI 啦

    函数的局部变量,都是存放在"栈"里面,栈的英文是:STACK.STACK的大小,我们可以在stm32的启动文件里面设置,以战舰stm32开发板为例,在startup_stm32f1 ...

随机推荐

  1. Apache + WordPress + SSL 完全指南

    似乎不少使用国外主机的站长都想弄个 https:// "玩",但是许多人对 SSL/TLS.HTTPS.证书等概念了解有限,而中文互联网上相关的教程也不是很完备,各种杂乱.正好,本 ...

  2. No toolchains found in the NDK toolchains folder for ABI with prefix: arm-linux-androideabi

    产生背景最近把Android Studio更新到3.0,更新之后出现了build错误:No toolchains found in the NDK toolchains folder for ABI ...

  3. asp.net mvc4 小问题

    最近在学习mvc4中间出现一些问题.留作记录.. 1.新建立的项目在vs2013中运行后会出现一个长轮询..这个叫browserLink 是vs2013中新加入的东西.至于更多解释.直接百度.. 关闭 ...

  4. MySQL5.7.20编译安装

    1:官网下载source code源码安装文件 https://cdn.mysql.com//Downloads/MySQL-5.7/mysql-boost-5.7.20.tar.gz 2:安装准备 ...

  5. Git访问TFS出现权限不足(Using Personal Access Tokens to access Visual Studio Online)

    使用GIT克隆TFS服务器上的代码到本地时出现错误如下: fatal: Authentication failed for 'https://***.visualstudio.com/***Proje ...

  6. C#中IL, CTS, CLR, CLS, JIT含义

    1. IL/MSIL  (Microsoft Intermediate Language) 微软中间语言 (IL是MSIL的缩写,译为中间语言) 2. CTS  (Common Type System ...

  7. Python实例---利用正则实现计算器[参考版]

    利用正则进行运算规则的计算 版本一: # import re # # ss = '1 - 2 * ((60 - 30 + (-40/5) * (9 - 2 * 5 / 3 + 7 / 3 * 99 / ...

  8. Linux telnet命令详解

    telnet命令通常用来远程登录.telnet程序是基于TELNET协议的远程登录客户端程序.Telnet协议是TCP/IP协议族中的一员,是Internet远程登陆服务的标准协议和主要方式.它为用户 ...

  9. linux服务器安全配置10大技巧

    1.禁止ping/etc/rc.d/rc.localecho 1 > /proc/sys/net/ipv4/icmp_echo_ignore_all2.对用户和口令文件进行权限控制chmod 6 ...

  10. SQL脚本修改表结构

    SQL脚本修改表结构 新建表:create table [表名]([自动编号字段] int IDENTITY (1,1) PRIMARY KEY ,[字段1] nVarChar(50) default ...