SLR(1)方法的出现,解决了大部分的移进和规约冲突、规约和规约的冲突。并且SLR(1)其优点是状态数目少,造表算法简单,大多数程序设计语言基本上都可用SLR(1)文法来描述。

但是仍然有一些文法,不能用SLR(1)解决。

例如:

S->BB;

B->aB;

B->b;

该文法我们可以看到,在S->BB中,第一个B和第二个B的follow集是不同的。为了解决这个问题,于是诞生了LR(1)分析方法。

解决办法是在每个项目集的产生式后加上follow集。比如:

S-> ·BB, #

B-> · aB, a/b

B-> · b ,a/b

这样就是是同一个非终结符,但是仍旧可以根据不同状态集内的产生式的follow集进行不冲突的规约和移进。

目前LR(1)分析法仍旧是应用非常广泛,是当前最一般的分析方法,几乎所有的上下文无关文法描述的程序设计语言都可以通过LR(1)分析法分析。

为了解决LR(1)分析法状态过多的问题,于是提出了LALR(1)分析法,将“心”相同的状态合并,从而减少状态数。

具体例子如下:

文法G[E]

(0)S’->S

(1)S->BB

(2)B->Ab

(3)B->b

1、构造项目集

2、构造LR(分析表)

状态

a

b

#

S

B

0

S3

S4

1

2

1

Acc

2

S6

S7

5

3

S3

S4

8

4

R3

R3

5

R1

6

S6

S7

9

7

R3

8

R2

R2

9

R2

3、编程

  1 #include<bits/stdc++.h>
2 #define ROW 11
3 #define COLUMN 6
4 using namespace std;
5 //产生式
6 string products[4][2]={
7 {"S'","S"},
8 {"S","BB"},
9 {"B","aB"},
10 {"B","b"}
11 };
12 //分析表
13 string actiontable[ROW][COLUMN]={
14 {"","a","b","#","S","B"},
15 {"0","s3","s4","","1","2"},
16 {"1","","","acc","",""},
17 {"2","s6","s7","","","5"},
18 {"3","s3","s4","","","8"},
19 {"4","r3","r3","","",""},
20 {"5","","","r1","",""},
21 {"6","s6","s7","","","9"},
22 {"7","","","r3","",""},
23 {"8","r2","r2","","",""},
24 {"9","","","r2","",""}
25 };
26 stack<int> sstatus; //状态栈
27 stack<char> schar; //符号栈
28 struct Node{
29 char type;
30 int num;
31 };
32 //打印步骤
33 void print_step(int times){
34 stack<char> tmp2;
35 cout<<times<<setw(4);
36 while(!schar.empty()){
37 char t=schar.top();
38 schar.pop();
39 tmp2.push(t);
40 cout<<t;
41 }
42 while(!tmp2.empty()){
43 int t=tmp2.top();
44 tmp2.pop();
45 schar.push(t);
46 }
47 }
48 //查表
49 Node Action_Goto_Table(int status,char a){
50 int row=status+1;
51 string tmp;
52 for(int j=1;j<COLUMN;j++){
53 if(a==actiontable[0][j][0]){
54 tmp=actiontable[row][j];
55 }
56 }
57 Node ans;
58 if(tmp[0]>='0'&&tmp[0]<='9'){
59 int val=0;
60 for(int i=0;i<tmp.length();i++){
61 val=val*10+(tmp[i]-'0');
62 }
63 ans.num=val;
64 ans.type=' ';
65 }else if(tmp[0]=='s'){
66 int val=0;
67 for(int i=1;i<tmp.length();i++){
68 val=val*10+(tmp[i]-'0');
69 }
70 ans.type='s';
71 ans.num=val;
72 }else if(tmp[0]=='r'){
73 int val=0;
74 for(int i=1;i<tmp.length();i++){
75 val=val*10+(tmp[i]-'0');
76 }
77 ans.type='r';
78 ans.num=val;
79 }else if(tmp[0]=='a'){
80 ans.type='a';
81 }else{
82 ans.type=' ';
83 }
84 return ans;
85 }
86 //LR(1)分析法
87 bool LR1(string input){
88 while(!sstatus.empty()){
89 sstatus.pop();
90 }
91 while(!schar.empty()){
92 schar.pop();
93 }
94 int times=0;
95 bool flag=true;
96 int st=0;
97 sstatus.push(st);
98 schar.push('#');
99 int i=0;
100 char a=input[i];
101 while(true){
102 Node action=Action_Goto_Table(st,a);
103 if(action.type=='s'){
104 st=action.num;
105 sstatus.push(st);
106 schar.push(a);
107 a=input[++i];
108 print_step(++times);
109 cout<<setw(10)<<'s'<<st<<endl;
110
111 }else if(action.type=='r'){
112 int n=action.num;
113 string ls=products[n][0];
114 string rs=products[n][1];
115 for(int j=0;j<rs.length();j++){
116 sstatus.pop();
117 schar.pop();
118 }
119 schar.push(ls[0]);
120 st=sstatus.top();
121 action =Action_Goto_Table(st,ls[0]);
122 st=action.num;
123 sstatus.push(st);
124 print_step(++times);
125 cout<<setw(10)<<'r'<<" "<<ls<<"->"<<rs<<endl;
126
127 }else if(action.type=='a'){
128 flag=true;
129 break;
130 }else{
131 flag=false;
132 break;
133 }
134 }
135 return flag;
136 }
137 int main(){
138 string input;
139 while(cin>>input){
140 if(LR1(input)){
141 cout<<"syntax correct"<<endl;
142 }else{
143 cout<<"syntax error"<<endl;
144 }
145 }
146 return 0;
147 }

LR(1)分析法的更多相关文章

  1. 《编译原理》LR 分析法与构造 LR(1) 分析表的步骤 - 例题解析

    <编译原理>LR 分析法与构造 LR(1) 分析表的步骤 - 例题解析 笔记 直接做题是有一些特定步骤,有技巧.但也必须先了解一些基本概念,本篇会通过例题形式解释概念,会容易理解和记忆,以 ...

  2. 【编译原理】自底向上分析方法——LR文法分析方法的总结

    LR(0).SLR(1).LR(1).LALR(1) de 若干方面的区别 目录 推导过程 分析能力 本质区别 文法对比 可以适当利用物理意义对二义性文法进行冲突处理 推导过程 LR(0)的基础上才有 ...

  3. 【转】LR分析法

    转自:http://guanjy0129.blog.163.com/blog/static/1115494452010614113333509/ LR分析法的归约过程是规范推导的逆过程,所以LR分析过 ...

  4. 编译原理(六)自底向上分析之LR分析法

    自底向上分析之LR分析法 说明:以老师PPT为标准,借鉴部分教材内容,AlvinZH学习笔记. 基本概念 1. LR分析:从左到右扫描(L)自底向上进行规约(R),是规范规约,也即最右推导(规范推导) ...

  5. 从Elo Rating System谈到层次分析法

    1. Elo Rating System Elo Rating System对于很多人来说比较陌生,根据wikipedia上的解释:Elo评分系统是一种用于计算对抗比赛(例如象棋对弈)中对手双方技能水 ...

  6. Procrustes Analysis普氏分析法

    选取N幅同类目标物体的二维图像,并用上一篇博文的方法标注轮廓点,这样就得到训练样本集: 由于图像中目标物体的形状和位置存在较大偏差,因此所得到的数据并不具有仿射不变性,需要对其进行归一化处理.这里采用 ...

  7. AX中四种库存ABC分析法原理研究

    库存ABC分类,简单的说就是抓大放小,是为了让我们抓住重点,用最大精力来管理最重要的物料,而对于不太重要的物料则可以用较少的精力进行管理.它和我们平常说的八二法则有异曲同工之妙. 既然要应用库存ABC ...

  8. 黑盒测试用例设计方法&理论结合实际 -> 边界值分析法

    一. 概念 边界值分析法就是对输入或输出的边界值进行测试的一种黑盒测试方法.通常边界值分析法是作为对等价类划分法的补充,这种情况下,其测试用例来自等价类的边界. 二. 边界值分析法的应用 根据大量的测 ...

  9. 帕累托分析法(Pareto Analysis)(柏拉图分析)

    帕累托分析法(Pareto Analysis)(柏拉图分析) ABC分类法是由意大利经济学家帕雷托首创的.1879年,帕累托研究个人收入的分布状态图是地,发现少数人收入占全部人口收入的大部分,而多数人 ...

  10. SWOT分析法

    SWOT(Strengths Weakness Opportunity Threats)分析法,又称为态势分析法或优劣势分析法,用来确定企业自身的竞争优势(strength).竞争劣势(weaknes ...

随机推荐

  1. Unity 性能优化Shader分析处理函数:ShaderUtil.GetShaderGlobalKeywords用法

    Unity 性能优化Shader分析处理函数:ShaderUtil.GetShaderGlobalKeywords用法 点击封面跳转下载页面 简介 Unity 性能优化Shader分析处理函数:Sha ...

  2. 探析ElasticSearch Kibana在测试工作中的实践应用

    一. 为什么使用ES Kibana 离线数据测试中最重要的就是数据验证,一部分需要测试es存储数据的正确性,另一部分就需要验证接口从es取值逻辑的正确性.而为了验证es取值逻辑的正确性,就需要用到Ki ...

  3. Solution -「CF 1303G」Sum of Prefix Sums

    Description Link. 对于一棵树,选出一条链 \((u,v)\),把链上结点从 \(u\) 到 \(v\) 放成一个 长度 \(l\) 的数组,使得 \(\sum_{i=1}^{l}\s ...

  4. Centos7使用ssh免密登陆同时禁用root密码登陆

    Centos7使用ssh免密登陆同时禁用root密码登陆 首先配置免密登陆,参考:ssh免密登陆 禁用root密码登陆 修改 /etc/ssh/sshd_config 文件 找到: RSAAuthen ...

  5. 聊聊 QianKun JS 沙箱的那些事

    我们是袋鼠云数栈 UED 团队,致力于打造优秀的一站式数据中台产品.我们始终保持工匠精神,探索前端道路,为社区积累并传播经验价值. 本文作者:空山 什么是沙箱 沙箱即 SandBox,它是一种安全机制 ...

  6. Vue2系列(lqz)——slot插槽 (内容分发)、2 transition过渡、3 生命周期、4 swiper学习、5 自定义组件的封装、6 自定义指令、7 过滤器

    文章目录 1 slot插槽 (内容分发) 1.1 基本使用 1.2 插槽应用场景1 1.3 插槽应用场景2 1.4 具名插槽 2 transition过渡 3 生命周期 4 swiper学习 5 自定 ...

  7. Django框架——Web应用、基于SOCKET写一个web应用、 手撸简单web框架、http协议、Web框架(手撸自己的Web框架)、django简介以及简单使用

    文章目录 1 Web应用 一 Web应用程序是什么 1.1 Web应用程序的优点 1.2 Web应用程序的缺点 1.3 B/S架构优点 二 基于SOCKET写一个web应用 2.1 main.py 2 ...

  8. PAI-DSW常见问题

    PAI-DSW常见问题 更新时间:2023年6月5日 18:40:00 本文为您介绍PAI-DSW的相关问题. 什么是PAI-DSW? PAI-DSW实例如何挂载和使用自己的NAS文件系统? 如何在P ...

  9. windows开发环境备份,再也不怕重装系统了

    每次重装系统后,都要重新安装软件,配置环境变量,极为繁琐.故作环境环境变量备份,常用软件恢复记录,前提是你的软件要安装在非系统盘,D/E盘等 软件安装在非系统盘 开发软件安装在非系统盘,建好目录.重装 ...

  10. 从零开始搭建antd4.x + react16 + redux4 + webpack4 + react-router5基础框架解析

    以上是2020年10月份的版本,后来,我将xmind进行了完善,文档也写的差不多了,可是,电脑坏了,硬盘换了,文件都没有了.这已经是第三次写这个文档了,思维导图就不更新了,按照几个重点进行说明. 这个 ...