构造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)的基础上才有 ...
随机推荐
- Windows右下角时间显示具体星期
事件起因: 有时候脑子不清楚,过着过着就会忘记今天是星期几,错过一些重要事情,于是乎就想看看Windows右下角能不能显示到具体星期,果然在查了资料之后这个需求可以达成 解决办法: 控制面板 - 日期 ...
- laravel框架中保留条件搜索
前段代码 <form action="admin_index" method="get"> <input type="text&qu ...
- vector<char>转string的方法
要将 std::vector<char> 转换为 std::string,可以通过 std::string 的构造函数直接从 vector 中构建字符串. 假设 std::vector&l ...
- Linux 提高cache命中率方法
提高缓存命中率是优化系统性能的关键策略之一.以下是一些提高缓存命中率的有效方法: 数据局部性优化: 空间局部性:优化数据访问模式,使得数据访问在空间上连续,比如通过循环展开和数据重排. 时间局部性:确 ...
- k8s-NFS系统配置
k8s-NFS系统配置 NFS(network filesystem),nfs文件系统在k8s中主要用于持久化存储,可以被多个pod访问和共享数据. 特点 数据持久性 nfs为k8s的pod提供了一种 ...
- 云原生动态周刊:你订阅 GitHub README 播客了吗?
云原生一周动态要闻: Apache Kafka 3.0.0 发布 Deis Labs 推出 WebAssembly PaaS 平台 Hippo Mirantis Flow 将数据中心重塑为云原生系统 ...
- LDAP和SSO
什么是LDAP(Lightweight Directory Access Protocol)?很多公司会使用各种开源平台(例如: gitlab. Jenkins. chat 等等),维护这些账号是一件 ...
- css flex布局的使用
felx弹性布局 display:flex; 属性值 flex-direction 属性定义容器要在哪个方向上堆叠 flex 项目.默认为水平方向 row, column 值设置垂直方向.如:flex ...
- Python实现微博舆情分析的设计与实现
引言 随着互联网的发展,社交媒体平台如微博已经成为公众表达意见.分享信息的重要渠道.微博舆情分析旨在通过大数据技术和自然语言处理技术,对微博上的海量信息进行情感分析.热点挖掘和趋势预测,为政府.企业和 ...
- 适合才最美:Shiro安全框架使用心得
大家好,我是 V 哥.Apache Shiro 是一个强大且灵活的 Java 安全框架,专注于提供认证.授权.会话管理和加密功能.它常用于保护 Java 应用的访问控制,特别是在 Web 应用中.相比 ...