编写一个程序实现LR(1)项目集及状态转换图构造、LR(1)分析表构造、并实现在利用LR(1)分析表分析字符串同时生成逆波兰式
时间: 2023-09-15 21:24:31 浏览: 110
小程序 编译原理--LR(1)分析表构造(JAVA)(源码).rar
以下是一个基于Java实现的LR(1)语法分析程序,包括LR(1)项目集及状态转换图构造、LR(1)分析表构造和利用LR(1)分析表分析字符串同时生成逆波兰式的功能。程序中使用了JavaCC工具生成LR(1)语法分析器。
LR1Parser.jj:
```
options {
STATIC = false;
}
PARSER_BEGIN(LR1Parser)
package com.example.lr1parser;
import java.util.*;
PARSER_END(LR1Parser)
// Define terminals
TOKEN : {
<PLUS: "+"> |
<MINUS: "-"> |
<TIMES: "*"> |
<DIV: "/"> |
<LPAREN: "("> |
<RPAREN: ")"> |
<NUM: (["0"-"9"])+>
}
// Define non-terminals
void start() : {} {
expression()
}
void expression() : {} {
term() ( <PLUS> term() )*
}
void term() : {} {
factor() ( <TIMES> factor() )*
}
void factor() : {} {
<NUM> |
<LPAREN> expression() <RPAREN>
}
// Define LR(1) items
List<Item> items = new ArrayList<Item>();
Item startItem = new Item(new Production("S", "E"), 0, "$");
items.add(startItem);
// Define LR(1) item set
Set<ItemSet> itemSetSet = new HashSet<ItemSet>();
// Define LR(1) transition table
Map<ItemSet, Map<String, ItemSet>> transitionTable = new HashMap<ItemSet, Map<String, ItemSet>>();
// Define LR(1) action table
Map<ItemSet, Map<String, Action>> actionTable = new HashMap<ItemSet, Map<String, Action>>();
// Define LR(1) goto table
Map<ItemSet, Map<String, ItemSet>> gotoTable = new HashMap<ItemSet, Map<String, ItemSet>>();
// Define stack for parsing
Stack<ItemSet> stack = new Stack<ItemSet>();
Stack<String> input = new Stack<String>();
// Define output queue for reverse polish notation
Queue<String> outputQueue = new LinkedList<String>();
// Define state counter for generating state IDs
int stateCounter = 0;
// Define action types
enum ActionType {
SHIFT,
REDUCE,
ACCEPT,
ERROR
}
// Define action
class Action {
ActionType type;
int stateOrProduction;
public Action(ActionType type, int stateOrProduction) {
this.type = type;
this.stateOrProduction = stateOrProduction;
}
}
// Define item
class Item {
Production production;
int dot;
String lookahead;
public Item(Production production, int dot, String lookahead) {
this.production = production;
this.dot = dot;
this.lookahead = lookahead;
}
public boolean isReduceItem() {
return dot == production.getRight().size();
}
public String getNextSymbol() {
if (isReduceItem()) {
return null;
}
return production.getRight().get(dot);
}
public Item getNextItem() {
if (isReduceItem()) {
return null;
}
return new Item(production, dot + 1, lookahead);
}
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(production.getLeft());
sb.append(" ->");
for (int i = 0; i < production.getRight().size(); i++) {
if (i == dot) {
sb.append(" .");
}
sb.append(" ");
sb.append(production.getRight().get(i));
}
if (dot == production.getRight().size()) {
sb.append(" .");
}
sb.append(", ");
sb.append(lookahead);
return sb.toString();
}
}
// Define item set
class ItemSet {
int id;
Set<Item> items = new HashSet<Item>();
public ItemSet() {
this.id = stateCounter++;
}
public ItemSet(Set<Item> items) {
this.id = stateCounter++;
this.items = items;
}
public void addItem(Item item) {
items.add(item);
}
public Set<String> getLookaheads(String symbol) {
Set<String> lookaheads = new HashSet<String>();
for (Item item : items) {
if (!item.isReduceItem() && item.getNextSymbol().equals(symbol)) {
lookaheads.add(item.lookahead);
}
}
return lookaheads;
}
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("I" + id + ":\n");
for (Item item : items) {
sb.append(" " + item + "\n");
}
return sb.toString();
}
}
// Define production
class Production {
String left;
List<String> right;
public Production(String left, String... right) {
this.left = left;
this.right = Arrays.asList(right);
}
public String getLeft() {
return left;
}
public List<String> getRight() {
return right;
}
public boolean isNullable() {
for (String symbol : right) {
if (!isNullable(symbol)) {
return false;
}
}
return true;
}
public static boolean isNullable(String symbol) {
return symbol.equals("$") || symbol.equals("ε");
}
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(left);
sb.append(" ->");
for (String symbol : right) {
sb.append(" ");
sb.append(symbol);
}
return sb.toString();
}
}
// Generate LR(1) items
void generateItems() {
for (Production production : Productions.productions) {
for (int i = 0; i <= production.getRight().size(); i++) {
for (String lookahead : Productions.first(production.getRight().subList(i, production.getRight().size()))) {
Item item = new Item(production, i, lookahead);
items.add(item);
}
}
}
}
// Generate LR(1) item set closure
ItemSet closure(ItemSet itemSet) {
ItemSet closure = new ItemSet(itemSet.items);
boolean changed = true;
while (changed) {
changed = false;
Set<Item> newItems = new HashSet<Item>();
for (Item item : closure.items) {
String nextSymbol = item.getNextSymbol();
if (nextSymbol != null) {
for (Item i : items) {
if (i.production.getLeft().equals(nextSymbol) && Productions.first(i.production.getRight()).contains(item.lookahead)) {
Item newItem = new Item(i.production, 0, item.lookahead);
if (!closure.items.contains(newItem)) {
newItems.add(newItem);
}
}
}
}
}
if (!newItems.isEmpty()) {
closure.items.addAll(newItems);
changed = true;
}
}
return closure;
}
// Generate LR(1) item set goto
ItemSet goTo(ItemSet itemSet, String symbol) {
Set<Item> newItems = new HashSet<Item>();
for (Item item : itemSet.items) {
String nextSymbol = item.getNextSymbol();
if (nextSymbol != null && nextSymbol.equals(symbol)) {
newItems.add(item.getNextItem());
}
}
return closure(new ItemSet(newItems));
}
// Generate LR(1) item set family
void generateItemSetFamily() {
ItemSet startItemSet = closure(new ItemSet(Collections.singleton(startItem)));
itemSetSet.add(startItemSet);
boolean changed = true;
while (changed) {
changed = false;
Set<ItemSet> newSets = new HashSet<ItemSet>();
for (ItemSet itemSet : itemSetSet) {
for (String symbol : Productions.getAllSymbols()) {
ItemSet newItemSet = goTo(itemSet, symbol);
if (!newItemSet.items.isEmpty() && !itemSetSet.contains(newItemSet)) {
newSets.add(newItemSet);
changed = true;
}
}
}
if (!newSets.isEmpty()) {
itemSetSet.addAll(newSets);
}
}
}
// Generate LR(1) transition table
void generateTransitionTable() {
for (ItemSet itemSet : itemSetSet) {
Map<String, ItemSet> transitionMap = new HashMap<String, ItemSet>();
for (String symbol : Productions.getAllSymbols()) {
ItemSet newItemSet = goTo(itemSet, symbol);
if (!newItemSet.items.isEmpty()) {
transitionMap.put(symbol, newItemSet);
}
}
transitionTable.put(itemSet, transitionMap);
}
}
// Generate LR(1) action table
void generateActionTable() {
for (ItemSet itemSet : itemSetSet) {
Map<String, Action> actionMap = new HashMap<String, Action>();
for (Item item : itemSet.items) {
if (item.isReduceItem()) {
if (item.production.getLeft().equals("S")) {
actionMap.put("$", new Action(ActionType.ACCEPT, 0));
} else {
for (String lookahead : Productions.follow(item.production.getLeft())) {
actionMap.put(lookahead, new Action(ActionType.REDUCE, Productions.getProductionIndex(item.production)));
}
}
} else {
String nextSymbol = item.getNextSymbol();
if (nextSymbol != null) {
ItemSet nextStateSet = transitionTable.get(itemSet).get(nextSymbol);
actionMap.put(nextSymbol, new Action(ActionType.SHIFT, nextStateSet.id));
}
}
}
for (String symbol : Productions.getAllSymbols()) {
if (!actionMap.containsKey(symbol)) {
actionMap.put(symbol, new Action(ActionType.ERROR, -1));
}
}
actionTable.put(itemSet, actionMap);
}
}
// Generate LR(1) goto table
void generateGotoTable() {
for (ItemSet itemSet : itemSetSet) {
Map<String, ItemSet> gotoMap = new HashMap<String, ItemSet>();
for (String symbol : Productions.getAllNonTerminals()) {
ItemSet newItemSet = goTo(itemSet, symbol);
if (!newItemSet.items.isEmpty()) {
gotoMap.put(symbol, newItemSet);
}
}
gotoTable.put(itemSet, gotoMap);
}
}
// Parse input string and generate reverse polish notation
void parse(String inputStr) {
stack.clear();
input.clear();
outputQueue.clear();
stack.push(itemSetSet.iterator().next());
input.push("$");
for (int i = inputStr.length() - 1; i >= 0; i--) {
input.push(String.valueOf(inputStr.charAt(i)));
}
while (true) {
ItemSet state = stack.peek();
String symbol = input.peek();
Action action = actionTable.get(state).get(symbol);
switch (action.type) {
case SHIFT:
stack.push(transitionTable.get(state).get(symbol));
input.pop();
阅读全文