LR(0)分析法
LR(0)是一种自底向上的语法分析方法。两个基本动作是移进和规约。
具体例子如下
已知文法G[E]
(1) E→aА
(2) E→bB
(3) A→cА
(4) A→d
(5) B→cB
(6) B→d
编写LR(0)分析算法,用于识别符号串是否为合法的句子。
设计方法
a.将文法 G[E]拓广为文法 G[E']
(0) S'→E
(1) E→aA
(2) E→bB
(3) A→cA
(4) A→d
(5) B→cB
(6) B→d
b.构造识别可归约前缀的 NFA

c. 将识别可归约前缀的 NFA 确定化成DFA

d. 根据识别可归约前缀的 DFA 构造文法的 LR(0)分析表
表2-1 LR(0)分析表
|
状态 |
a |
b |
c |
d |
# |
E |
A |
B |
|
0 |
S1 |
S2 |
3 |
|||||
|
1 |
S4 |
S5 |
6 |
|||||
|
2 |
S7 |
S8 |
9 |
|||||
|
3 |
acc |
|||||||
|
4 |
S4 |
S5 |
10 |
|||||
|
5 |
r4 |
r4 |
r4 |
r4 |
r4 |
|||
|
6 |
r1 |
r1 |
r1 |
r1 |
r1 |
|||
|
7 |
S7 |
S8 |
11 |
|||||
|
8 |
r6 |
r6 |
r6 |
r6 |
r6 |
|||
|
9 |
r2 |
r2 |
r2 |
r2 |
r2 |
|||
|
10 |
r3 |
r3 |
r3 |
r3 |
r3 |
|||
|
11 |
r5 |
r5 |
r5 |
r5 |
r5 |
e. 设计 LR(0)分析程序
自底向上的语法分析的两个基本动作就是,移进与规约。分析一下表 2-1 中 文法的 LR(0)分析表,可以发现这两个动作在表中都有。进一步分析可知,这些 移进与规约动作在表的前面终结符列中,因此,这部分称之为 ACTION 表。
表中不但给出了两个基本动作,还给出了规约时,弹出产生式右部,压入左 部之后,应该转换到的状态。例如,当前状态为 9,状态 9 为句柄识别态,查表 得:r2,表示使用第二个产生式E→bB 进行规约。规约动作分为两步:第一步弹 出句柄 bB,从识别文法可归约前缀的 DFA 中可知,弹出句柄 bB后,从当前状态为 9 回到状态 0;第二步就是压入左部 E, 从当前状态 0,转换到状态 3。在表中 的第 0 行第 E 列中就给出状态 3。
分析表 可知,表中的非终结符列填入的是某一规约动作,压入产生式左 部(非终结符)之后,转换到的状态。因此,这部分称之为 GOTO 表。
实验代码:
1 #include<bits/stdc++.h>
2 #define ROW 13
3 #define COLUMN 9
4 using namespace std;
5 //产生式
6 string products[7][2]={
7 "","",
8 "E","aA",
9 "E","bB",
10 "A","cA",
11 "A","d",
12 "B","cB",
13 "B","d"
14 };
15 //LR(0)分析表
16 string actiontable[ROW][COLUMN]={
17 {" " ,"a" ,"b" ,"c" ,"d" ,"#" ,"E" ,"A" ,"B"},
18 {"0" ,"s1" ,"s2" ," " ," " ," " ,"3" ," " ," "},
19 {"1" ," " ," " ,"s4" ,"s5" ," " ," " ,"6" ," "},
20 {"2" ," " ," " ,"s7" ,"s8" ," " ," " ," " ,"9"},
21 {"3" ," " ," " ," " ," " ,"acc"," " ," " ," "},
22 {"4" ," " ," " ,"s4" ,"s5" ," " ," " ,"10" ," "},
23 {"5" ,"r4" ,"r4" ,"r4" ,"r4" ,"r4" ," " ," " ," "},
24 {"6" ,"r1" ,"r1" ,"r1" ,"r1" ,"r1" ," " ," " ," "},
25 {"7" ," " ," " ,"s7" ,"s8" ," " ," " ," " ,"11"},
26 {"8" ,"r6" ,"r6" ,"r6" ,"r6" ,"r6" ," " ," " ," "},
27 {"9" ,"r2" ,"r2" ,"r2" ,"r2" ,"r2" ," " ," " ," "},
28 {"10","r3" ,"r3" ,"r3" ,"r3" ,"r3" ," " ," " ," "},
29 {"11","r5" ,"r5" ,"r5" ,"r5" ,"r5" ," " ," " ," "}};
30 stack<int> sstatus; //状态栈
31 stack<char> schar; //符号栈
32 struct Node{
33 char type;
34 int num;
35 };
36 //打印步骤
37 void print_step(int times){
38 stack<char> tmp2;
39 cout<<times<<setw(4);
40 while(!schar.empty()){
41 char t=schar.top();
42 schar.pop();
43 tmp2.push(t);
44 cout<<t;
45 }
46 while(!tmp2.empty()){
47 int t=tmp2.top();
48 tmp2.pop();
49 schar.push(t);
50 }
51 }
52 //查表
53 Node Action_Goto_Table(int status,char a){
54 int row=status+1;
55 string tmp;
56 for(int j=1;j<COLUMN;j++){
57 if(a==actiontable[0][j][0]){
58 tmp=actiontable[row][j];
59 }
60 }
61 Node ans;
62 if(tmp[0]>='0'&&tmp[0]<='9'){
63 int val=0;
64 for(int i=0;i<tmp.length();i++){
65 val=val*10+(tmp[i]-'0');
66 }
67 ans.num=val;
68 ans.type=' ';
69 }else if(tmp[0]=='s'){
70 int val=0;
71 for(int i=1;i<tmp.length();i++){
72 val=val*10+(tmp[i]-'0');
73 }
74 ans.type='s';
75 ans.num=val;
76 }else if(tmp[0]=='r'){
77 int val=0;
78 for(int i=1;i<tmp.length();i++){
79 val=val*10+(tmp[i]-'0');
80 }
81 ans.type='r';
82 ans.num=val;
83 }else if(tmp[0]=='a'){
84 ans.type='a';
85 }else{
86 ans.type=' ';
87 }
88 return ans;
89 }
90 //LR(0)分析算法
91 bool LR0(string input){
92 while(!sstatus.empty()){
93 sstatus.pop();
94 }
95 while(!schar.empty()){
96 schar.pop();
97 }
98 int times=0;
99 bool flag=true;
100 int st=0;
101 sstatus.push(st);
102 schar.push('#');
103 int i=0;
104 char a=input[i];
105 while(true){
106 Node action=Action_Goto_Table(st,a);
107 if(action.type=='s'){
108 st=action.num;
109 sstatus.push(st);
110 schar.push(a);
111 a=input[++i];
112 print_step(++times);
113 cout<<setw(10)<<'s'<<st<<endl;
114
115 }else if(action.type=='r'){
116 int n=action.num;
117 string ls=products[n][0];
118 string rs=products[n][1];
119 for(int j=0;j<rs.length();j++){
120 sstatus.pop();
121 schar.pop();
122 }
123 schar.push(ls[0]); //only one char
124 st=sstatus.top();
125 action =Action_Goto_Table(st,ls[0]);
126 st=action.num;
127 sstatus.push(st);
128 print_step(++times);
129 cout<<setw(10)<<'r'<<" "<<ls<<"->"<<rs<<endl;
130
131 }else if(action.type=='a'){
132 flag=true;
133 break;
134 }else{
135 flag=false;
136 break;
137 }
138 }
139 return flag;
140 }
141 int main(){
142 string input;
143 while(cin>>input){
144 if(LR0(input)){
145 cout<<"syntax correct"<<endl;
146 }else{
147 cout<<"syntax error"<<endl;
148 }
149 }
150 return 0;
151 }
LR(0)分析法的更多相关文章
- 编译原理根据项目集规范族构造LR(0)分析表
转载于https://blog.csdn.net/Johan_Joe_King/article/details/79058597?utm_medium=distribute.pc_relevant.n ...
- 《编译原理》LR 分析法与构造 LR(1) 分析表的步骤 - 例题解析
<编译原理>LR 分析法与构造 LR(1) 分析表的步骤 - 例题解析 笔记 直接做题是有一些特定步骤,有技巧.但也必须先了解一些基本概念,本篇会通过例题形式解释概念,会容易理解和记忆,以 ...
- LL(1),LR(0),SLR(1),LALR(1),LR(1)对比与分析
前言:考虑到这几种文法如果把具体内容讲下来肯定篇幅太长,而且繁多的符号对初学者肯定是极不友好的,而且我相信看这篇博客的人已经对这几个文法已经有所了解了,本篇博客的内容只是对 这几个文法做一下对比,加深 ...
- LR(0)文法项目集规范族、DFA和分析表的构建实例
最近在复习编译原理,考试之前以为自己懂了,眼高手低就没去实践.结果一考试出问题了.... 学习就要脚踏实地,容不得半点模糊.凭着侥幸心理很危险的.以后要引以为戒啊. 特别写出这篇文章 :一来总结一下这 ...
- 【编译原理】自底向上分析方法——LR文法分析方法的总结
LR(0).SLR(1).LR(1).LALR(1) de 若干方面的区别 目录 推导过程 分析能力 本质区别 文法对比 可以适当利用物理意义对二义性文法进行冲突处理 推导过程 LR(0)的基础上才有 ...
- LR(0)语法分析
# include <stdio.h> # include <string.h> //存储LR(0)分析表 struct node { char ch; int num; }; ...
- 编译原理LR(0)项目集规范族的构造详解
转载于https://blog.csdn.net/johan_joe_king/article/details/79051993#comments 学编译原理的时候,感觉什么LL(1).LR(0).S ...
- 【转】LR分析法
转自:http://guanjy0129.blog.163.com/blog/static/1115494452010614113333509/ LR分析法的归约过程是规范推导的逆过程,所以LR分析过 ...
- 编译原理(六)自底向上分析之LR分析法
自底向上分析之LR分析法 说明:以老师PPT为标准,借鉴部分教材内容,AlvinZH学习笔记. 基本概念 1. LR分析:从左到右扫描(L)自底向上进行规约(R),是规范规约,也即最右推导(规范推导) ...
- LL(1),LR(0),SLR(1),LR(1),LALR(1)的 联系与区别
一:LR(0),SLR(1),规范LR(1),LALR(1)的关系 首先LL(1)分析法是自上而下的分析法.LR(0),LR(1),SLR(1),LALR(1)是自下而上的分析法. ...
随机推荐
- 《小白WEB安全入门》01. 扫盲篇
@ 目录 基础知识 什么是WEB 什么是前端 什么是后端 什么是数据库 什么是协议 什么是WEB安全 什么是服务器 什么是IP地址.端口 什么是局域网.广域网.内网.外网 什么是URL 什么是MAC地 ...
- 一篇关于获得拼多多商品详情 API的使用说明
拼多多(Pinduoduo)是中国一家快速发展的电商平台,为了帮助开发者更好地接入拼多多,平台提供了丰富的 API 接口供开发者使用,其中包括获取拼多多商品详情的 API.接下来,我们将介绍如何使用拼 ...
- Nextcloud 维护管理
Nextcloud 维护管理 目录 Nextcloud 维护管理 1.管理员被禁用怎么办 2.管理员密码忘了怎么办 1.管理员被禁用怎么办 通过命令行解禁管理员用户: 方法一:通过命令行解禁管理员用户 ...
- JAVA-Springboot实践项目-用户注册
Smiling & Weeping ----我本没喜欢的人, 见你的次数多了, 也就有了. 1.创建数据表 1.1.选中数据表: use store 1.2.创建t_user表: 2创建用户实 ...
- 关闭k8s的pod时减小对服务的影响
在应用程序的整个生命周期中,正在运行的 pod 会由于多种原因而终止.在某些情况下,Kubernetes 会因用户输入(例如更新或删除 Deployment 时)而终止 pod.在其他情况下,Kube ...
- KRPano最新官方文档中文版
KRPano最新官方文档中文版: KRPano作为VR全景开发中常用的工具软件,深受广大开发者喜爱,但由于软件本身是国外软件,因此官方的文档都是以英文为主,对于一些国内不太熟悉英文的开发者来说比较不友 ...
- 初露头角!Walrus入选服贸会“数智影响力”数字化转型创新案例
9月5日,由北京市通信管理局.工业和信息化部新闻宣传中心联合主办的"企业数字化转型论坛"在2023中国国际服务贸易交易会期间召开,论坛以"数字化引领 高质量发展" ...
- 带宽优化新思路:RoCE网卡聚合实现X2增长
本文分享自华为云社区<2个RoCE网卡Bond聚合,实现带宽X2>,作者: tsjsdbd . 我们知道操作系统里面,可以将2个实际的物理网卡,合体形成一个"逻辑网卡" ...
- 研发提速:nacos+openfeign环境下的本地链接服务
项目研发过程中,经常会遇到与测试人员工作重叠的情况,十分影响效率. 做了一个修改,可以在本地环境启动项目后和测试环境交互,并且不影响测试环境,理论上也可以用于线上环境的异常的快速处理. 准备事项如下: ...
- python---简单最大类间方差法(OTSU)算法
from matplotlib import pyplot as plt # cv2.imread()用于读取图片文件 # imread函数有两个参数,第一个参数是图片路径,第二个参数表示读取图片的形 ...