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. The memory graph Shared by the method

    Phone类 package com.itheima_03; /* * 手机类 */ public class Phone { String brand; int price; String colo ...

  2. jQuery 小案例

    用jquery实现  百度换肤的模式; <!DOCTYPE html> <html lang="en"> <head> <meta cha ...

  3. 设计模式(16) 观察者模式(OBSERVER)C++实现

    意图: 定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新. 动机: 将一个系统设计成一系列相互协作的类有一个常见的副作用:需要维护相关对象之间的一 ...

  4. mysql服务器硬件配置选择参考

    这是在网上找的一个关于如何评估一个mysql服务器的硬件需求的文章,转载以备用 5 Minute DBA – Database Server Hardware Selection Posted on  ...

  5. .htaccess详解及.htaccess参数说明

    .htaccess文件(或者”分布式配置文件”)提供了针对目录改变配置的方法, 即,在一个特定的文档目录中放置一个包含一个或多个指令的文件, 以作用于此目录及其所有子目录.作为用户,所能使用的命令受到 ...

  6. iOS亮屏解锁命令【iOS自动化测试】--使用ssh

    前提:iOS越狱手机一个 越狱方法:使用pp助手, 爱思助手等 1.从Cydia安装以下软件: AppSync for iOSx(可安装破解软件).afc2add补丁(可访问整个iOS设备的系统文件) ...

  7. Chapter 5 Order Inversion Pattern

    5.1 Introdution The main focus of this chapter is to discuss the order inversion (OI) pattern, which ...

  8. Eclipse PHPEclipse 配置

    最近偶来兴致趁着有些时间,看了看php的书. 说到php就不得不提php的开发环境了,一般的都是采用apache做服务器.mysql做数据库,再加上php组合成一个完备的运行环境,但是好像没有写代码的 ...

  9. Debian9+PHP7+MySQL+Apache2配置Thinkphp运行环境LAMP

    因工作需要,配置了一台服务器,运行THINKPHP框架程序,记录配置过程如下: 安装net版Debian9,完成后,如下: 1.配置基本的网络 php install net-tools 安装net- ...

  10. Jackson实现Object对象与Json字符串的互转

    在项目开发过程中,当客户端与服务器响应时,数据交互是必不可少的.然而通过Json实现数据交互成为我们开发中的一部分,进而Jackson为我们的Json转化提供了很好的机制.下面我将利用实例总结如何使用 ...