编译原理实验三 LR(1)分析法
实验三 LR(1)分析法
构造 LR(1)分析程序,利用它进行语法分析,判断给出的符号串是否为该文 法识别的句子,了解 LR(K)分析方法是严格的从左向右扫描,和自底向上的 语法分析方法。
二、实验内容
对下列文法,用 LR(1)分析法对任意输入的符号串进行分析: (1)E-> E+T
(2)E->T
(3)T-> T*F
(4)T->F (5)F-> (E) (6)F-> i
三、LR(1)分析法实验设计思想及算法
(1)总控程序,也可以称为驱动程序。对所有的 LR 分析器总控程序都是相同的。 (2)分析表或分析函数,不同的文法分析表将不同,同一个文法采用的 LR 分析器 不同时,分析表将不同,分析表又可以分为动作表(ACTION)和状态转换(GOTO) 表两个部分,它们都可用二维数组表示。 (3)分析栈,包括文法符号栈和相应的状态栈,它们均是先进后出栈。 分析器的动作就是由栈顶状态和当前输入符号所决定。
LR 分析器由三个部分组成:
16
其中:SP 为栈指针,S[i]为状态栈,X[i]为文法符号栈。状态转换表用 GOTO[i,X]=j 表示,规定当栈顶状态为 i,遇到当前文法符号为 X 时应 转向状态 j,X 为终结符或非终结符。
ACTION[i,a]规定了栈顶状态为 i 时遇到输入符号 a 应执行。动作有四种 可能:
(1)移进:
action[i,a]= Sj:状态 j 移入到状态栈,把 a 移入到文法符号栈,其中 i,j 表
示状态号。 (2)归约:
action[i,a]=rk:当在栈顶形成句柄时,则归约为相应的非终结符 A,即文 法中有 A- B 的产生式,若 B 的长度为 R(即|B|=R),则从状态栈和文法符号栈中 自顶向下去掉 R 个符号,即栈指针 SP 减去 R,并把 A 移入文法符号栈内, j=GOTO[i,A]移进状态栈,其中 i 为修改指针后的栈顶状态。
(3)接受 acc:
当归约到文法符号栈中只剩文法的开始符号 S 时,并且输入符号串已结束即 当前输入符是'#',则为分析成功。
(4)报错:
当遇到状态栈顶为某一状态下出现不该遇到的文法符号时,则报错,说明输 入端不是该文法能接受的符号串。
17
四、实验要求
1、编程时注意编程风格:空行的使用、注释的使用、缩进的使用等。 2、如果遇到错误的表达式,应输出错误提示信息。 3、程序输入/输出实例: 输入一以#结束的符号串(包括+*()i#):在此位置输入符号串 输出过程如下:
步骤 状态栈 符号栈 剩余输入串 动作
1 0 # i+i*i# 移进
i+i*i 的 LR 分析过程 |
||||
步骤 |
状态栈 |
符号栈 |
输入串 |
动作说明 |
1 |
0 |
# |
i+i*i# |
ACTION[0,i]=S5,状态 5 入栈 |
2 |
05 |
#i |
+i*i# |
r6: F→i 归约,GOTO(0,F)=3 入栈 |
3 |
03 |
#F |
+i*i# |
r4: T→F 归约,GOTO(0,T)=3 入栈 |
4 |
02 |
#T |
+i*i# |
r2: E→T 归约,GOTO(0,E)=1 入栈 |
18
5 |
01 |
#E |
+i*i# |
ACTION[1,+]=S6,状态 6 入栈 |
6 |
016 |
#E+ |
i*i# |
ACTION[6,i]=S5,状态 5 入栈 |
7 |
0165 |
#E+i |
*i# |
r6: F→i 归约,GOTO(6,F)=3 入栈 |
8 |
0163 |
#E+F |
*i# |
r4: T→F 归约,GOTO(6,T)=9 入栈 |
9 |
0169 |
#E+T |
*i# |
ACTION[9,*]=S7,状态 7 入栈 |
10 |
01697 |
#E+T* |
i# |
ACTION[7,i]=S5,状态 5 入栈 |
11 |
016975 |
#E+T*i |
# |
r6:F→i 归约,GOTO(7,F)=10 入栈 |
12 |
0169710 |
#E+T*F |
# |
r3: T→T*F 归约,GOTO(6,T)=9 入栈 |
13 |
0169 |
#E+T |
# |
r1:E→E+T,GOTO(0,E)=1 入栈 |
14 |
01 |
#E |
# |
Acc:分析成功 |
4、输入符号串为非法符号串(或者为合法符号串)
算术表达式文法的 LR 分析表 |
|||||||||
状 态 |
ACTION |
GOTO |
|||||||
i |
+ |
* |
( |
) |
# |
E |
T |
F |
|
0 |
S5 |
S4 |
1 |
2 |
3 |
||||
1 |
S6 |
acc |
|||||||
2 |
r2 |
S7 |
r2 |
r2 |
|||||
3 |
r4 |
r4 |
r4 |
r4 |
|||||
4 |
S5 |
S4 |
8 |
2 |
3 |
||||
5 |
r6 |
r6 |
r6 |
r6 |
|||||
6 |
S5 |
S4 |
9 |
3 |
|||||
7 |
S5 |
S4 |
10 |
||||||
8 |
S6 |
S11 |
|||||||
9 |
r1 |
S7 |
r1 |
r1 |
|||||
10 |
r3 |
r3 |
r3 |
r3 |
|||||
11 |
r5 |
r5 |
r5 |
r5 |
五、实验步骤
1、根据流程图编写出各个模块的源程序代码上机调试。
19
2、编制好源程序后,设计若干用例对系统进行全面的上机测试,并通过所设计 的 LR(1)语法分析程序;直至能够得到完全满意的结果。
3、书写实验报告 ;实验报告正文的内容:
描述 LR(1)语法分析程序的设计思想。
程序结构描述:函数调用格式、参数含义、返回值描述、函数功能;函数
之间的调用关系图。
详细的算法描述(程序执行流程图)。
给出软件的测试方法和测试结果。
实验总结 (设计的特点、不足、收获与体会)。
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;public class Q3 {StringBuilder input = new StringBuilder();Deque<Integer> sStack = new LinkedList<>();Deque<Character> cStack = new LinkedList<>();void start() throws IOException {InputStreamReader reader = new InputStreamReader(Q2.class.getResourceAsStream("Q2"));for(int ch; (ch = reader.read()) != -1; ){input.append((char)ch);}sStack.add(0);cStack.add('#');int s = sStack.getLast();char a = input.charAt(0);while(true){String temp = ACTION.get(s).get(a);if(temp == null){print("ERROR");break;}else if(temp.startsWith("r")){print("");int index = Integer.parseInt(temp.substring(1));int length = production[index][1].length();while(length-- != 0){sStack.removeLast(); cStack.removeLast();}cStack.add(production[index][0].charAt(0));if(GOTO.get(sStack.getLast()).get(cStack.getLast()) == null){print("ERROR");break;}s = GOTO.get(sStack.getLast()).get(cStack.getLast());sStack.add(s);}else if(temp.startsWith("S")){print("");sStack.add(Integer.parseInt(temp.substring(1)));s = sStack.getLast();cStack.add(a);input.deleteCharAt(0);a = input.charAt(0);}else {print("SUCCESS");break;}}}void print(String msg){if("ERROR".equals(msg)){System.out.println(msg);}else if("SUCCESS".equals(msg)){System.out.println(sStack.toString() + '\t' + cStack.toString() + '\t' + input.toString() + '\t' + msg);}else {System.out.println(sStack.toString() + '\t' + cStack.toString() + '\t' + input.toString());}}static List<Map<Character, String>> ACTION = new ArrayList<>();static List<Map<Character, Integer>> GOTO = new ArrayList<>();static String[][] production = null;public static void main(String[] args) throws IOException {production = new String[][] {{}, {"E", "E+T"}, {"E", "T"}, {"T", "T*F"}, {"T", "F"}, {"F", "(E)"}, {"F", "i"}};ACTION.add(new HashMap<Character, String>(){{ put('i', "S5"); put('(', "S4"); }});ACTION.add(new HashMap<Character, String>(){{ put('+', "S6"); put('#', "acc"); }});ACTION.add(new HashMap<Character, String>(){{ put('+', "r2"); put('*', "S7"); put(')', "r2"); put('#', "r2"); }});ACTION.add(new HashMap<Character, String>(){{ put('+', "r4"); put('*', "r4"); put(')', "r4"); put('#', "r4"); }});ACTION.add(ACTION.get(0));ACTION.add(new HashMap<Character, String>(){{ put('+', "r6"); put('*', "r6"); put(')', "r6"); put('#', "r6"); }});ACTION.add(ACTION.get(0));ACTION.add(ACTION.get(0));ACTION.add(new HashMap<Character, String>(){{ put('+', "S6"); put(')', "S11"); }});ACTION.add(new HashMap<Character, String>(){{ put('+', "r1"); put('*', "S7"); put(')', "r1"); put('#', "r1"); }});ACTION.add(new HashMap<Character, String>(){{ put('+', "r3"); put('*', "r3"); put(')', "r3"); put('#', "r3"); }});ACTION.add(new HashMap<Character, String>(){{ put('+', "r5"); put('*', "S5"); put(')', "r5"); put('#', "r5"); }});GOTO.add(new HashMap<Character, Integer>(){{ put('E', 1); put('T', 2); put('F', 3); }});GOTO.add(new HashMap<>());GOTO.add(new HashMap<>());GOTO.add(new HashMap<>());GOTO.add(new HashMap<Character, Integer>(){{ put('E', 8); put('T', 2); put('F', 3); }});GOTO.add(new HashMap<>());GOTO.add(new HashMap<Character, Integer>(){{ put('T', 9); put('F', 3); }});GOTO.add(new HashMap<Character, Integer>(){{ put('F', 10); }});GOTO.add(new HashMap<>());GOTO.add(new HashMap<>());GOTO.add(new HashMap<>());GOTO.add(new HashMap<>());Q3 q3 = new Q3();q3.start();}
}
编译原理实验三 LR(1)分析法相关推荐
- 编译原理 实验三 LR(1)分析法 Java
1. 实验目的 构造 LR(1)分析程序,利用它进行语法分析,判断给出的符号串是否为该文法识别的句子,了解 LR(K)分析方法是严格的从左向右扫描,和自底向上的语法分析方法. 2. 实验内容 对下列文 ...
- java编程实现算符优先分析法,编译原理实验三-算符优先分析法
编译原理实验3-算符优先分析法 #include #include #include #include #define SIZE 128 char priority[6][6]; //算符优先关系表数 ...
- 编译原理 实验四 LR(0)分析法(LR0分析表的自动生成)
写在前面 由于代码较长,csdn对文章总长度有字数限制,想只看完整代码的请移步另一篇博客. https://blog.csdn.net/qq_46640863/article/details/1257 ...
- 编译原理 实验二 LL(1)分析法程序实现
源代码仓库:CompilePrincipleLearning/experiment_2 · yusixian/CompilePrincipleLearning (github.com) 一. 实验目的 ...
- 合工大 编译原理 实验三
合工大 编译原理 实验三 LR(1) 分析法 本项目使用c++实现,利用Windows API制作了简易的UI界面. 具体功能如下: 支持查看文法,项目族,LR(1) 分析表,句子归约过程. 可使用包 ...
- 编译原理-实验四-LR(0)语法分析程序的设计
一.实验目的 了解LR(0)语法分析算法的基本思想,掌握LR(0)语法分析程序的构造方法. 二.实验内容 根据LR(0)语法分析算法的基本思想,设计一个对给定文法进行LR(0)语法分析的程序,并用C. ...
- 编译原理实验三 语义分析程序设计与实现
一.实验目的 在实现词法.语法分析程序的基础上,编写相应的语义子程序,进行语义处理,加深对语法制导翻译原理的理解,进一步掌握将语法分析所识别的语法范畴变换为某种中间代码(四元式)的语义分析方法,并完成 ...
- 【编译原理】 实验三 LL(1)分析法(LL1分析表的自动生成)
写在前面 由于代码较长,csdn对文章总长度有字数限制,想只看完整代码的请移步另一篇博客. https://blog.csdn.net/qq_46640863/article/details/1257 ...
- 编译原理之语法分析(预测分析法)
编译器之语法分析 自顶向下 上下文无关文法 语法树 NFA→CFG 预测分析法 改写CFG 原因 消除二义性 消除左递归 消除左公因子 消除空产生式 消除回路 自顶向下 上下文无关文法 CFG本质上就 ...
最新文章
- 让C/C++程序一次编译,到处运行 (仅限Linux)
- c 语言文字输出函数,c/c++语言中文字输出函数总结
- KVM虚拟机IO处理过程(一) ----Guest VM I/O 处理过程
- php 上传多文件_php 多文件上传的实现实例
- java 以太坊 智能合约_web3j教程:java使用web3j开发以太坊智能合约交易
- linux小红帽系统能用微信,小红帽腾讯QQ微信登录版-小红帽腾讯版v1.0.3 安卓版-腾牛安卓网...
- 【excel技巧读书笔记007】此工作薄包含一个或多个无法更新的链接
- SpringBoot自动装配原理与自己写一个starter
- 【C语言】井字棋游戏
- python调用qq互联_实现QQ互联一键登录代码教程
- Error:field larger than field limit(131072)解决方法
- java logger 乱码_Log4j乱码
- 全球400多支团队参加,鹅厂是如何拿下冠军的
- React基础(壹)———脚手架项目初始化
- 登录计算机隐藏用户名,win10系统隐藏登录界面administrator用户名的办法介绍
- OpenCV-Python击中击不中HITMISS形态变换详解
- 拦截电话--- 关于利用反射 调用系统 hiden的 方法
- Redis缓存:java解析excel数据
- python中import requests是什么意思_python中requests库使用方法详解
- java timer schedule_Java Timer的使用,timer.schedule定时执行
热门文章
- 系统评价和meta分析是什么?了解系统评价和meta分析的区别联系
- 中睿计算机科技,AssayZap 丨 实验分析计算器软件
- 2023年泰迪杯数据挖掘挑战赛B题--产品订单数据分析与需求预测(1.数据处理)
- STM8S003xx学习笔记(1):模拟 / 数字转换器(ADC)
- php中html解析器,PHP Simple HTML DOM解析器
- 用计算机怎么管理小米路由器,小米无线路由器怎么设置?
- 初中班主任常用ppt制作技巧之二-Leo老师
- 当一个页面从B返回到A后,取消B页面的所有请求
- Windows下Rstudio的下载安装步骤详解
- 番茄会计记账软件发布