构造SLR语法分析表
构造SLR语法分析表
方法:
1)构造G‘的规范LR(0)项集族
2)根据规则生成动作
3)生成转换
4)设置报错
/**
* P157 规范LR(0)项集族
* @param grammar
*/
public List<SetOfItems> items(Grammar grammar) { int setId = 0; List<SetOfItems> result = new ArrayList<>();
Map<Symbol, SetOfItems> gotoMap = new HashMap<>(); List<Production> production = grammar.getProduction(grammar.start); // 开始状态
SetOfItems startSet = new SetOfItems();
startSet.add(Item.of(production.get(0), 0));
startSet = closure(startSet, grammar);
startSet.setId(setId++);
result.add(startSet); boolean hasNew;// 是否产生新的项集
do {
hasNew = false;
List<SetOfItems> allSet = new ArrayList<>(result);
for (SetOfItems setOfItems : allSet) {
for (Symbol symbol : grammar.allSymbols) { SetOfItems gotoTarget = gotoSet(grammar, setOfItems, symbol);
// 在符号symbol上没有GOTO集合
if (gotoTarget == null) {
continue;
} // 判断项集是否已经存在
SetOfItems pre = CollectionUtil.find(result, gotoTarget);
if (pre != null) {// 已经存在只记录GOTO
setOfItems.addGoto(symbol, pre);
continue;
} gotoTarget.setId(setId++);
setOfItems.addGoto(symbol, gotoTarget);
result.add(gotoTarget);
hasNew = true;
}
}
} while (hasNew); return result;
}
语法分析表的结构
1.动作函数ACTION,移入,规约,接受,报错
2.转换函数GOTO
/**
* 语法分析表
*/
public class ParsingTable { private Map<Integer, Map<Symbol, Action>> set_symbol_action = new HashMap<>();
private Map<Integer, Map<Symbol, Integer>> set_symbol_set = new HashMap<>(); public void addAction(int fromId, Symbol symbol, Action action) {
Map<Symbol, Action> actionMap = set_symbol_action.computeIfAbsent(fromId, k -> new HashMap<>());
actionMap.put(symbol, action);
} public void addGoto(int fromId, Symbol symbol, int toId) {
Map<Symbol, Integer> actionMap = set_symbol_set.computeIfAbsent(fromId, k -> new HashMap<>());
actionMap.put(symbol, toId);
} public Action getAction(int setId, Symbol symbol) {
Map<Symbol, Action> actionMap = set_symbol_action.get(setId);
if (actionMap == null) {
return null;
}
return actionMap.get(symbol);
} public Integer gotoSet(int setId, Symbol symbol) {
Map<Symbol, Integer> setMap = set_symbol_set.get(setId);
if (setMap == null) {
return null;
}
return setMap.get(symbol);
}
}
构建语法分析表
/**
* P161 算法4.46 构造一个SLR语法分析表
* @param grammar
* @param setList
* @return
*/
public ParsingTable buildParsingTable(Grammar grammar, List<SetOfItems> setList) {
ParsingTable result = new ParsingTable(); for (SetOfItems from : setList) { for (Item item : from.getItems()) { if (item.pos != item.getProduction().getBody().size()) {
continue;
} Nonterminal head = item.getProduction().getHead();
if (head.equals(grammar.start)) {
// 如果[S' -> S·]在I中,那么将ACTION[i $]设置为接受
Set<Terminal> follows = grammar.follow(head);
for (Terminal symbol : follows) {
result.addAction(from.getId(), symbol, AcceptAction.of());
}
} else {
// 如果[A -> α·]在I中,那么对于所有FOLLOW(A)中的所有a,将ACTION[i a]设置为规约
Set<Terminal> follows = grammar.follow(head);
for (Terminal symbol : follows) {
result.addAction(from.getId(), symbol, ReduceAction.of(item.getProduction()));
}
}
} for (Map.Entry<Symbol, SetOfItems> entry : from.getGotoMap().entrySet()) {
Symbol symbol = entry.getKey();
SetOfItems to = entry.getValue(); // 如果[A -> α·aβ]在from中并且GOTO(from, a) = to,那么将Action[from,a]设置为移入to,a必须为一个终结符
if (symbol instanceof Terminal) {
result.addAction(from.getId(), symbol, ShiftAction.of(to.getId()));
} else {
result.addGoto(from.getId(), symbol, to.getId());
} }
} return result;
}
构造SLR语法分析表的更多相关文章
- SLR,语法分析表的构建
太累了,感觉不会再爱了.执行了跟编译原理上的一模一样的例子,输出了正确结果 #include <stdio.h> #include <malloc.h> #include &l ...
- 基于表的数据字典构造MySQL建表语句
表的数据字典格式如下: 如果手动写MySQL建表语句,确认麻烦,还不能保证书写一定正确. 写了个Perl脚本,可快速构造MySQL脚本语句. 脚本如下: #!/usr/bin/perl use str ...
- UOJ343 清华集训2017 避难所 构造、打表
传送门 玄学题 考虑构造三个数\(p_1p_2,p_1p_2,p_1p_2\)满足贪心分解会分解为\(p_1^3,p_2,p_2,p_2\),那么需要满足条件 1.\(p_1 , p_2 \in Pr ...
- 非标准的xml解析器的C++实现:二、解析器的基本构造:语法表
解析器的目的:一次从头到尾的文本遍历,文本数据 转换为 xml节点数据. 这其实是全世界所有编程语言编译或者转换为虚拟代码的基础,学会这种方法,发明一种编程语言其实只是时间问题,当然了,时间也是世界上 ...
- 编译原理_P1004
龙书相关知识点总结 //*************************引论***********************************// 1. 编译器(compiler):从一中语言( ...
- LL(1),LR(0),SLR(1),LALR(1),LR(1)对比与分析
前言:考虑到这几种文法如果把具体内容讲下来肯定篇幅太长,而且繁多的符号对初学者肯定是极不友好的,而且我相信看这篇博客的人已经对这几个文法已经有所了解了,本篇博客的内容只是对 这几个文法做一下对比,加深 ...
- 编译原理-第四章 语法分析-4.6 简单LR技术
简单LR分析方法 一.LR语言分析器模型与算法 1.输入.输出.栈和方法 2.LR语法分析表 3.LR分析程序 4.例 例1: 例2: 二.LR语法分析算法 1.LR语法分析算法的定义和概念 定义: ...
- C# 语法分析器(二)LR(0) 语法分析
系列导航 (一)语法分析介绍 (二)LR(0) 语法分析 (三)LALR 语法分析 (四)二义性文法 (五)错误恢复 (六)构造语法分析器 首先,需要介绍下 LALR 语法分析的基础:LR(0) 语法 ...
- 学了编译原理能否用 Java 写一个编译器或解释器?
16 个回答 默认排序 RednaxelaFX JavaScript.编译原理.编程 等 7 个话题的优秀回答者 282 人赞同了该回答 能.我一开始学编译原理的时候就是用Java写了好多小编译器和 ...
- 【编译原理】自底向上分析方法——LR文法分析方法的总结
LR(0).SLR(1).LR(1).LALR(1) de 若干方面的区别 目录 推导过程 分析能力 本质区别 文法对比 可以适当利用物理意义对二义性文法进行冲突处理 推导过程 LR(0)的基础上才有 ...
随机推荐
- Visual Studio & VS Code
前言 会写这篇是因为想记入一个 bug. 随便以后记入一些 Visual Studio 和 VS Code 相关的冬冬呗. 当 VS Code Hot Reload 遇上 View Component ...
- AI老照片修复神器,Anole下载介绍
最近AI老照片修复上色,再一次火出圈,一些社交平台关于此话题内容流量满满,尤其是在小红书和抖音火的不得了,本期文章就来给大家分享下AI修复老照片的方式方法 本文主要介绍使用Anole修复老照片的方法, ...
- Servlet——idea创建Servlet模板
idea创建Servlet模板 以前新建一个Servlet是通过新建一个Class文件 可以直接新建一个idea内的Servlet模板 可以通过设置 更改 ...
- 技术分享 | 徐轶韬:从MySQL5.7升级到MySQL 8.0
在6月20日举办的[墨天轮数据库沙龙-MySQL 5.7 停服影响与应对方案]中,甲骨文MySQL解决方案首席工程师徐轶韬分享了<从MySQL5.7升级到MySQL 8.0>主题演讲,本文 ...
- Data Summit 2022 大会资料分享(共23个)
Data Summit (数据峰会)是国际上关于数据管理.分析方面最新战略和技术研讨的顶尖峰会,通过行业领先的企业.专家的分享,共同探讨大数据和数据科学领域的发展现状与最新技术研究. 2022年5月1 ...
- OpenGL RHI优化
前言 随着Vulkan的普及,OpenGL已经在被慢慢淘汰,更轻的API调用可以节省不少性能,尤其是在移动平台上,可以减少CPU开销,进而减少功耗.看起来很完美,但是问题是目前移动平台Vulkan驱动 ...
- 云原生周刊:Flux 2.3 发布 | 2024.5.20
开源项目推荐 kubeinvaders kubeinvaders 专为 Kubernetes 用户设计.它提供了一种有趣而交互式的方式来探索和可视化您的 Kubernetes 集群.通过类似游戏的界面 ...
- 图菱科技 SaaS 系统容器化最佳实践
大家好,我是龚承明,在图菱(成都)科技有限公司任职,主要负责公司的产品系统研发以及公司IT基础设施的建设工作.本篇文章将为大家介绍下我司在采用 KubeSphere 平台实现公司业务系统容器化过程中的 ...
- C++容器概览
容器 容器是用来存储数据的序列,它们提供了不同的存储方式和访问模式. STL 中的容器可以分为三类: 1.序列容器:存储元素的序列,允许双向遍历. vector:动态数组,支持快速随机访问. dequ ...
- .NET云原生应用实践(三):连接到PostgreSQL数据库
本章目标 实现基于PostgreSQL的SDAC(简单数据访问层) 将Stickers微服务切换到使用PostgreSQL SDAC 为什么选择PostgreSQL数据库? 其实并不一定要选择Post ...