用Java编写 LR(0)分析表的构造

时间: 2024-03-07 10:47:04 浏览: 16
以下是使用Java语言编写LR(0)分析表构造的示例代码: ``` import java.util.*; public class LR0Parser { private Grammar grammar; // 存储文法的对象 private Map<String, Integer> nonTerminals; // 非终结符号的编号 private Map<String, Integer> terminals; // 终结符号的编号 private List<Set<Item>> canonicalCollection; // LR(0)自动机的状态集合 private int[][] actionTable; // 移进-规约表 private int[][] gotoTable; // 转移表 public LR0Parser(Grammar grammar) { this.grammar = grammar; this.nonTerminals = new HashMap<>(); this.terminals = new HashMap<>(); this.canonicalCollection = new ArrayList<>(); this.actionTable = null; this.gotoTable = null; } public void buildTables() { // 初始化非终结符号和终结符号的编号 int id = 0; for (String symbol : grammar.getSymbols()) { if (grammar.isNonTerminal(symbol)) { nonTerminals.put(symbol, id++); } else { terminals.put(symbol, id++); } } // 构造LR(0)自动机 canonicalCollection.add(closure(new HashSet<>(Collections.singletonList( new Item(grammar.getProduction(0), 0))))); int i = 0; while (i < canonicalCollection.size()) { Set<Item> itemSet = canonicalCollection.get(i++); for (String symbol : grammar.getSymbols()) { Set<Item> nextSet = gotoSet(itemSet, symbol); if (!nextSet.isEmpty() && !canonicalCollection.contains(nextSet)) { canonicalCollection.add(nextSet); } } } // 构造移进-规约表和转移表 actionTable = new int[canonicalCollection.size()][terminals.size()]; gotoTable = new int[canonicalCollection.size()][nonTerminals.size()]; for (i = 0; i < canonicalCollection.size(); i++) { Set<Item> itemSet = canonicalCollection.get(i); for (Item item : itemSet) { if (item.isReduceItem()) { Production production = item.getProduction(); int j = nonTerminals.get(production.getLeft()); if (actionTable[i][terminals.size() - 1] != 0) { throw new RuntimeException("LR(0)文法不是SLR文法"); } actionTable[i][terminals.size() - 1] = -production.getId() - 1; } else { String symbol = item.getSymbol(); int j = grammar.isNonTerminal(symbol) ? nonTerminals.get(symbol) : terminals.get(symbol); int k = canonicalCollection.indexOf(gotoSet(itemSet, symbol)); if (grammar.isNonTerminal(symbol)) { gotoTable[i][j] = k; } else { actionTable[i][j] = k; } } } } } public int parse(List<Token> tokens) { Stack<Integer> stateStack = new Stack<>(); // 状态栈 Stack<Integer> symbolStack = new Stack<>(); // 符号栈 stateStack.push(0); symbolStack.push(terminals.get("$")); for (Token token : tokens) { int state = stateStack.peek(); int symbol = token.getType(); int action = actionTable[state][symbol]; if (action > 0) { // 移进操作 stateStack.push(action); symbolStack.push(symbol); } else if (action < 0) { // 规约操作 Production production = grammar.getProduction(-action - 1); for (int i = 0; i < production.getRight().size(); i++) { stateStack.pop(); symbolStack.pop(); } int newState = gotoTable[stateStack.peek()][nonTerminals.get(production.getLeft())]; stateStack.push(newState); symbolStack.push(nonTerminals.get(production.getLeft())); } else { // 错误处理 throw new RuntimeException("语法错误"); } } return symbolStack.pop(); } // 计算项目集闭包 private Set<Item> closure(Set<Item> itemSet) { Queue<Item> queue = new LinkedList<>(itemSet); while (!queue.isEmpty()) { Item item = queue.poll(); if (!item.isReduceItem() && grammar.isNonTerminal(item.getSymbol())) { String symbol = item.getNextSymbol(); for (Production production : grammar.getProductions(symbol)) { Item newItem = new Item(production, 0); if (!itemSet.contains(newItem)) { itemSet.add(newItem); queue.offer(newItem); } } } } return itemSet; } // 计算项目集的转移 private Set<Item> gotoSet(Set<Item> itemSet, String symbol) { Set<Item> result = new HashSet<>(); for (Item item : itemSet) { if (!item.isReduceItem() && item.getSymbol().equals(symbol)) { result.add(new Item(item.getProduction(), item.getPosition() + 1)); } } return closure(result); } } ``` 注:上述代码中,`Grammar`是一个存储文法的对象,`Token`是一个存储词法分析结果的对象,`Item`是一个表示项目的对象,`Production`是一个表示产生式的对象。在实际使用中,需要根据具体的需求进行相应的修改和扩展。

相关推荐

最新推荐

recommend-type

编译原理课程设计 LR(0)分析表和分析器的构造和程序实现

LR(0)分析表算法的程序实现 1. 对任意给定的文法 ,完成识别文法活前缀的 、 的状态转化矩阵及 项目集规范族的构造; 2. 判断该文法是否为 文法,实现 分析表的构造,并输出到指定文件中; 3. 实现 分析器总控程序...
recommend-type

编译原理LR(1)自动构造,自动分析输入语句

LR(1)分析表自动构造程序的实现,对输入语句分析 设计内容及要求:对任意给定的文法G构造LR(1)项目集规范族(要求实现CLOSURE(I)、GO(I,X)、FIRST;然后实现LR(1)分析表构造算法。构造并输出其LR(1)分析表。由分析表...
recommend-type

4 实验四:LR分析程序的设计与实现

1、了解LR(0)分析方法是严格的从左向右扫描,和自底向上的语法分析方法。 2、掌握LR(0)语法分析方法。
recommend-type

LR(0)语法分析的设计与实现.doc

内含代码片段。原理包含CLOSURE和GOTO函数的构造说明,前缀、项目、拓广文法的定义说明,文法项目集规范族的构造伪代码,判断文法是否为LR(0)文法的说明,以及分析表构造讲解与输入串合法性分析步骤。
recommend-type

LR(0)语法分析的实现

LR(0)语法分析的实现:对于所输入的LR(0)文法,不论对错,都应有明确的信息告诉外界。对于符合规则的LR(0)文法,将输出LR(0)分析表,并可以对输入的句子进行语法分析输出相应语法树。
recommend-type

zigbee-cluster-library-specification

最新的zigbee-cluster-library-specification说明文档。
recommend-type

管理建模和仿真的文件

管理Boualem Benatallah引用此版本:布阿利姆·贝纳塔拉。管理建模和仿真。约瑟夫-傅立叶大学-格勒诺布尔第一大学,1996年。法语。NNT:电话:00345357HAL ID:电话:00345357https://theses.hal.science/tel-003453572008年12月9日提交HAL是一个多学科的开放存取档案馆,用于存放和传播科学研究论文,无论它们是否被公开。论文可以来自法国或国外的教学和研究机构,也可以来自公共或私人研究中心。L’archive ouverte pluridisciplinaire
recommend-type

实现实时数据湖架构:Kafka与Hive集成

![实现实时数据湖架构:Kafka与Hive集成](https://img-blog.csdnimg.cn/img_convert/10eb2e6972b3b6086286fc64c0b3ee41.jpeg) # 1. 实时数据湖架构概述** 实时数据湖是一种现代数据管理架构,它允许企业以低延迟的方式收集、存储和处理大量数据。与传统数据仓库不同,实时数据湖不依赖于预先定义的模式,而是采用灵活的架构,可以处理各种数据类型和格式。这种架构为企业提供了以下优势: - **实时洞察:**实时数据湖允许企业访问最新的数据,从而做出更明智的决策。 - **数据民主化:**实时数据湖使各种利益相关者都可
recommend-type

解释minorization-maximization (MM) algorithm,并给出matlab代码编写的例子

Minorization-maximization (MM) algorithm是一种常用的优化算法,用于求解非凸问题或含有约束的优化问题。该算法的基本思想是通过构造一个凸下界函数来逼近原问题,然后通过求解凸下界函数的最优解来逼近原问题的最优解。具体步骤如下: 1. 初始化参数 $\theta_0$,设 $k=0$; 2. 构造一个凸下界函数 $Q(\theta|\theta_k)$,使其满足 $Q(\theta_k|\theta_k)=f(\theta_k)$; 3. 求解 $Q(\theta|\theta_k)$ 的最优值 $\theta_{k+1}=\arg\min_\theta Q(
recommend-type

JSBSim Reference Manual

JSBSim参考手册,其中包含JSBSim简介,JSBSim配置文件xml的编写语法,编程手册以及一些应用实例等。其中有部分内容还没有写完,估计有生之年很难看到完整版了,但是内容还是很有参考价值的。