构造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. CSS – initial, Inherit, unset, revert

    参考 Understanding the "Initial", "Inherit" and "Unset" CSS Keywords [译] ...

  2. .Net Web项目中,实现轻量级本地事件总线 框架

    一.事件总线设计方案 1.1.事件总线的概念 事件总线是一个事件管理器,负责统一处理系统中所有事件的发布和订阅. 事件总线模式通过提供一种松耦合的方式来促进系统内部的业务模块之间的通信,从而增强系统的 ...

  3. Spirng Aop 实现自定义注解及实现

    需求:日志记录 需要记录当前用户访问的每个接口对应的前端页面功能信息 声明一个注解 @Documented @Retention(RetentionPolicy.RUNTIME) @Target({E ...

  4. 【赵渝强老师】管理Docker镜像

    一.什么是Docker的镜像 Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙 ...

  5. 从SQL Server过渡到PostgreSQL:理解模式的差异

    从SQL Server过渡到PostgreSQL:理解模式的差异 前言 随着越来越多的企业转向开源技术,商业数据库管理员和开发者也逐渐面临向PostgreSQL迁移的需求. 虽然SQL Server和 ...

  6. USB编码方式(NRZI)及时钟同步方式

    1.概述 在同步通讯系统中,两个设备通讯则需要同步信号,同步信号分为时钟同步信号和自同步信号两种,时钟同步方式在通讯链路上具有时钟信号(IIC.SPI),自同步方式在通讯链路中没有同步信号(PCIE. ...

  7. /proc/sys/vm 使用

    这些参数主要是用来调整virtual memory子系统的行为以及数据的写出(从RAM到ROM). 这些节点(参数)的默认值和初始化的过程大部分都可以在mm/swap.c中找到. 目前,/proc/s ...

  8. 28. 找出字符串中第一个匹配项的下标 Golang实现

    题目描述: 给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串的第一个匹配项的下标(下标从 0 开始).如果 needle 不是 hay ...

  9. jenkins拉取git https报错

    报错内容 解决方式 在Jenkins服务器执行命令 git config --global http.sslVerify false

  10. 使用notepad++批量在每行首尾添加内容

    1 简介 在程序员开发过程中,一个不错的工具是notepad++,该工具为notepad的增强,增强了许多的功能,包括程序员喜欢的列块编辑模式,支持众多的插件,例如json格式化,支持markdown ...