构造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语法分析表的更多相关文章

  1. SLR,语法分析表的构建

    太累了,感觉不会再爱了.执行了跟编译原理上的一模一样的例子,输出了正确结果 #include <stdio.h> #include <malloc.h> #include &l ...

  2. 基于表的数据字典构造MySQL建表语句

    表的数据字典格式如下: 如果手动写MySQL建表语句,确认麻烦,还不能保证书写一定正确. 写了个Perl脚本,可快速构造MySQL脚本语句. 脚本如下: #!/usr/bin/perl use str ...

  3. 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 ...

  4. 非标准的xml解析器的C++实现:二、解析器的基本构造:语法表

    解析器的目的:一次从头到尾的文本遍历,文本数据 转换为 xml节点数据. 这其实是全世界所有编程语言编译或者转换为虚拟代码的基础,学会这种方法,发明一种编程语言其实只是时间问题,当然了,时间也是世界上 ...

  5. 编译原理_P1004

    龙书相关知识点总结 //*************************引论***********************************// 1. 编译器(compiler):从一中语言( ...

  6. LL(1),LR(0),SLR(1),LALR(1),LR(1)对比与分析

    前言:考虑到这几种文法如果把具体内容讲下来肯定篇幅太长,而且繁多的符号对初学者肯定是极不友好的,而且我相信看这篇博客的人已经对这几个文法已经有所了解了,本篇博客的内容只是对 这几个文法做一下对比,加深 ...

  7. 编译原理-第四章 语法分析-4.6 简单LR技术

    简单LR分析方法 一.LR语言分析器模型与算法 1.输入.输出.栈和方法 2.LR语法分析表 3.LR分析程序 4.例 例1: 例2: 二.LR语法分析算法 1.LR语法分析算法的定义和概念 定义: ...

  8. C# 语法分析器(二)LR(0) 语法分析

    系列导航 (一)语法分析介绍 (二)LR(0) 语法分析 (三)LALR 语法分析 (四)二义性文法 (五)错误恢复 (六)构造语法分析器 首先,需要介绍下 LALR 语法分析的基础:LR(0) 语法 ...

  9. 学了编译原理能否用 Java 写一个编译器或解释器?

    16 个回答 默认排序​ RednaxelaFX JavaScript.编译原理.编程 等 7 个话题的优秀回答者 282 人赞同了该回答 能.我一开始学编译原理的时候就是用Java写了好多小编译器和 ...

  10. 【编译原理】自底向上分析方法——LR文法分析方法的总结

    LR(0).SLR(1).LR(1).LALR(1) de 若干方面的区别 目录 推导过程 分析能力 本质区别 文法对比 可以适当利用物理意义对二义性文法进行冲突处理 推导过程 LR(0)的基础上才有 ...

随机推荐

  1. JavaScript – 数据类型

    前言 写着 TypeScript 学习笔记, 顺便也写点 JS 的呗. 参考 JS数据类型分类和判断 阮一峰 – 数据类型 JS 数据类型 string number boolan undefined ...

  2. Servlet——Request请求转发

    Request请求转发       特点:     

  3. 【赵渝强老师】Docker的日志

    Docker的日志分两类,一类是 Docker引擎的日志:另一类是容器日志.下面我们分别进行介绍. 一.Docker引擎的日志 Docker 引擎日志 一般是交给了 Upstart(Ubuntu 14 ...

  4. 解密prompt系列39. RAG之借助LLM优化精排环节

    RAG的部分我们之前讨论过信息召回的多样性,信息密度和质量,主要集中在召回,融合,粗排的部分.这一章我们集中看下精排的部分.粗排和精排的主要差异其实在于效率和效果的balance.粗排模型复杂度更低, ...

  5. 墨天轮沙龙 | 麦杰科技卢学东:openPlant 实时数据库系统及应用

    在8月24日举办的[墨天轮数据库沙龙第九期-工业实时数据库专场]中,麦杰科技创始人 卢学东分享了<麦杰openPlant实时数据库系统及应用>主题演讲,本文为整理内容. 导读 工业互联网推 ...

  6. base64 是什么,有什么作用?

    base64 是图片编码的一种形式,可以替代图片的url进行网络访问和请求等操作: 使用图片的url形式操作图片,每次都要请求一次网络,因为每次请求都是一个http:都是一个网络开销,都是对服务器的负 ...

  7. C#查漏补缺----值类型与引用类型,值类型一定分配在栈上吗?

    前言 环境:.NET 8.0 系统:Windows11 参考资料:<CLR via C#>, <.Net Core底层入门>,<.NET 内存管理宝典> 栈空间与堆 ...

  8. spring cloud openfeign 源码

    一.读取注解信息 入口 1 import org.springframework.boot.SpringApplication; 2 import org.springframework.boot.a ...

  9. spring boot shardingsphere 使用hikari连接池配置

    shardingsphere 使用hikari连接池配置: shardingsphere: datasource: names: ds ds: type: com.zaxxer.hikari.Hika ...

  10. PL/SQL查询中文乱码问题

    使用PL/SQL查询数据时,有中文的内容显示乱码,如下所示: 解决方案:配置环境变量 新建系统变量: 变量名:NLS_LANG 变量值:AMERICAN_AMERICA.ZHS16GBK 然后重启PL ...