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. 基于velero及minio实现etcd数据备份与恢复

    1.Velero简介 Velero 是vmware开源的一个云原生的灾难恢复和迁移工具,它本身也是开源的,采用Go语言编写,可以安全的备份.恢复和迁移Kubernetes集群资源数据:官网https: ...

  2. LeetCode952三部曲之二:小幅度优化(137ms -> 122ms,超39% -> 超51%)

    欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本篇概览 本文是<LeetCode952三部曲& ...

  3. Frida环境配置

    目录 安装Linux客户端 配置Android服务端 测试运行效果 官方手册 安装Linux客户端 github地址:https://github.com/frida/frida pip instal ...

  4. python入门基础(14)--类的属性、成员方法、静态方法以及继承、重载

    上一篇提到过类的属性,但没有详细介绍,本篇详细介绍一下类的属性 一 .类的属性 方法是用来操作数据的,而属性则是建模必不的内容,而且操作的数据,大多数是属性,比如游戏中的某个boss类,它的生命值就是 ...

  5. 创建及管理DSW实例

      机器学习PAI 产品概述 快速入门 操作指南 准备工作 工作空间管理 AI计算资源管理 AI开发 开发流程 快速开始 智能标注(iTAG) 可视化建模(PAI-Designer) 交互式建模(PA ...

  6. Gossip in Hyperledger Fabric

    1. Gossip协议基础 1.1 什么是分布式系统 分布式系统(Distributed System)是由多台计算机或计算节点组成的计算机系统,这些计算节点通过网络连接在一起,并协同工作以完成共同的 ...

  7. Java虚拟机(JVM):第五幕:自动内存管理 - HotSpot算法细节以及低延迟垃圾收集器

    一.HotSpot算法细节 1.根节点枚举:所有的收集器在根节点枚举的时候,必须暂停用户线程,同时要保证一致性的快照中得以进行.一致性:整个枚举期间执行子系统看起来就像是冻结在某一个时间点上,不会出现 ...

  8. TIM-有感BLDC转速解析

    TIM-有感BLDC转速解析 1.基本概念解析 霍尔传感器的原理:通电线圈产生的磁场会使得转子所在位置会产生磁场,其中离得最近的霍尔传感器的磁场最强,进而导致最近霍尔传感器会产生最大的电压信号,这个最 ...

  9. windows平板的开发和选型

    今天谈一个老话题,windows系统的选型和开发.问题的起因是我们一个客户说,用安卓平板不安全,苹果系统不考虑,于是他们要用自认为安全的WIN7系统. 提到WINDOWS平台下的的平板系统,此事说来话 ...

  10. Iksevi 题解

    Iksevi 题目大意 \(n\) 次询问,每次给定一个点 \((x,y),x\ge 0, y\ge 0\),问有多少种对角线长为偶数的正方形使得在用该正方形正密铺第一象限的情况下该点位于正方形顶点上 ...