博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
LR--用栈实现移进--归约分析(demo)
阅读量:6567 次
发布时间:2019-06-24

本文共 2353 字,大约阅读时间需要 7 分钟。

1.考虑文法

\(E->E+E\)

\(E->E*E\)
\(E->id\)

2.最右推导

不难看出,这个文法是而二义的,所以有多个最右推导

3.移进归约

用一个栈存文法符号,用输入缓存区保存要分析的输入串,用$标记栈底

#include
#include
#include
#include
#include
using namespace std;stack
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-->"<
<<"归约" << endl; printf("----------|----------|----------\n"); stk.pop(); stk.push("E"); } } } return 0;}

4.Sample

输入

id*id+id

1165691-20181110213828188-477544359.png

5.To be continued.

转载于:https://www.cnblogs.com/FlyerBird/p/9940723.html

你可能感兴趣的文章
OSChina 技术周刊第十六期 —— 每周技术精粹
查看>>
OSChina 技术周刊第二十九期 —— HTTP 有时候比 HTTPS 好?
查看>>
在Win7下利用VirtualBox和Vagrant安装Docker
查看>>
Elasticsearch 2.2.0 索引配置详解
查看>>
【工具使用系列】关于 MATLAB 液压元件,你需要知道的事
查看>>
给研发工程师的代码质量利器 | SOFAChannel#5 直播整理
查看>>
icinga安装介绍,监控软件
查看>>
正则表达式总结图
查看>>
Quartz 实现分布式任务调度
查看>>
IntelliJ IDEA 安装go插件
查看>>
Javascript基础知识 - 基础部分
查看>>
RHEL6.4换CentOS源
查看>>
编译安装openresty+mariadb+php7
查看>>
ArrayList如何实现插入的数据按自定义的方式有序存放
查看>>
activiti no processes deployed with key ""
查看>>
php autoload机制学习
查看>>
intellij idea 配置远程访问本地的tomcat项目
查看>>
利用onSaveInstanceState()方法保存Activity状态
查看>>
java线程入门篇(一)
查看>>
Failed to load JavaHL Library(windows和mac)
查看>>