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)是自下而上的分析法. ...
随机推荐
- Excel单元格快速交换相邻位置内容
一.相邻两列内容交换(A1与B1交换)1.首先选择A1单元格的边框位置,出现了向上下左右的十字标志 2.此时按住shift键,并且拖向B1单元格的右边,出现"工"汉字标志 3.松开 ...
- 「openjudge / poj - 1057」Chessboard
link. 调起来真的呕吐,网上又没篇题解.大概是个不错的题. 首先行和列一定是独立的,所以我们把行列分开考虑.这样的问题就弱化为:在一个长度为 \(n\) 的格子带上,有 \(n\) 个物品,每个物 ...
- Solution -「洛谷 P5610」「YunoOI 2013」大学
Description Link. 区间查 \(x\) 的倍数并除掉,区间查和. Solution 平衡树. 首先有个基本的想法就是按 \(a_{i}\) 开平衡树,即对于每个 \(a_{i}\) 都 ...
- SonarQube系列-认证&授权的配置
参考文档:https://docs.sonarqube.org/latest/instance-administration/security/ 概述 SonarQube具有许多全局安全功能: 认证和 ...
- 创建及管理DSW实例
机器学习PAI 产品概述 快速入门 操作指南 准备工作 工作空间管理 AI计算资源管理 AI开发 开发流程 快速开始 智能标注(iTAG) 可视化建模(PAI-Designer) 交互式建模(PA ...
- 【Dotnet 工具箱】基于 .NET 6 和 Angular 构建项目任务管理平台
1.Reha 时间管理大师 Rhea 是一个基于 C# 和 .NET 6 开发的在线任务管理平台,类似于 禅道.Jira.Redmine, 滴答清单等. 支持多视图多维度统一管理任务.多级结构,工作区 ...
- Python shape+size详解
import cv2 from PIL import Image # pic.JPG 图片的路径 img = cv2.imread("pic.JPG",-1) print(&quo ...
- 【Unity3D】UI Toolkit容器
1 前言 UI Toolkit简介 中介绍了 UI Builder.样式属性.UQuery.Debugger,UI Toolkit元素 中介绍了 Label.Button.TextField.To ...
- YXの每日挂分记录
7.11 T1 不开两倍数组 100->60. 7.18 T2 dp+矩乘 转移不判边界 100->10. 7.20 T2 人类智慧 1e6 n log n 100->10,求前 5 ...
- trafilatura 网页解析原理分析
trafilatura 介绍 Trafilatura是一个Python包和命令行工具,用于收集网络上的文本.其主要应用场景包括网络爬虫下载和网页解析等. 今天我们不讨论爬虫和抓取,主要看他的数据解析是 ...