版权声明:本文为博主原创文章,未经博主允许不得转载。如果你非要转载,麻烦加上我的原网址,谢谢。http://blog.csdn.net/qinglingLS https://blog.csdn.net/qinglingLS/article/details/89814398
经历了一些辛苦,终于把这个部分也写出来了!现在心情挺激动0v0
凡事情还是亲自做过,才能体验到成功的乐趣~~!!
程序猿还是要多写代码
下面展示一下思路和效果,先放效果吧!
目标文法如下:
S' -> S
S -> C C
C -> c C|d
应得到结果:
实现结果:
{I9=[C->cC.,$/], I0=[S'->.S,$/, S->.CC,$/, C->.cC,c/d/, C->.d,c/d/], I1=[S'->S.,$/],
I2=[S->C.C,$/, C->.cC,$/, C->.d,$/], I3=[C->c.C,c/d/, C->.cC,c/d/, C->.d,c/d/],
I4=[C->d.,c/d/], I5=[S->CC.,$/], I6=[C->c.C,$/, C->.cC,$/, C->.d,$/], I7=[C->d.,$/],
I8=[C->cC.,c/d/]}
{(I2,C)=I5, (I2,c)=I6, (I1,)=I1, (I5,)=I5, (I9,)=I9, (I6,c)=I6, (I3,C)=I8,
(I8,)=I8, (I6,d)=I7, (I0,d)=I4, (I3,d)=I4, (I7,)=I7, (I0,c)=I3, (I4,)=I4,
(I6,C)=I9, (I3,c)=I3, (I0,S)=I1, (I0,C)=I2, (I2,d)=I7}
自己一一对应一下,没问题~~~
包的结构如下:
说起来程序写的时候,主要还是得保证思路正确,不能说是结果对就可以,
所以下面放代码和思路~!
ItemTable.java
package parse2;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
/**
*
* @author dell
*
*/
public class ItemTable {
LRClosure lrClosure;// 初始的I0集合
Map<String, LRClosure> map;
int key = 0;
Map<GoTo, String> gotoMap;
public ItemTable(ProductionList productionList) {
lrClosure = new LRClosure(productionList);// 初始的I0集合
map = new HashMap<>();
gotoMap = new HashMap<>();
}
/**
*
* 完成goto表的构建,
* 这个函数负责从初始开始构建一个第一层closure,也就是从I0到后面的一级推导,
* 然后它把得到的map传到一个新的函数,这个map包含了第二层的闭包,
* 新的函数负责从一个map的闭包集合求解下一层闭包,如果这个闭包集合已经存在,就直接建立goto表,
* 如果不存在,就新建一个map存下一层的闭包,然后迭代自身求解,直到闭包集合不再增加为止。
*
* @param closure
* @param setName
* @return
*/
public Map<String, LRClosure> setItemSet(LRClosure closure, String setName) {
Map<String, LRClosure> lrClosure = new HashMap<>();
map.put(setName, closure);
key++;
closure.setClosureItem(closure.productions.get(0));// 初始第一个闭包
// System.out.println(closure.getNextClosure("c"));
// System.out.println(
// closure.getNextClosure("c").equals(closure.getNextClosure("c")));
// System.out.println("555555555555555555555");
for (Iterator<String> iterator = closure.gotoPath().iterator(); iterator
.hasNext();) {
String path = (String) iterator.next();
// closure.getNextClosure(type);
LRClosure tmp = closure.getNextClosure(path);
if (!map.containsValue(tmp)) {
String name = new String("I" + key);
map.put(name, tmp);
lrClosure.put(name, tmp);
gotoMap.put(new GoTo(setName, path), name);
key++;
/*
boolean isEnd = true;
for (Iterator<Item> iterator2 = tmp.items.iterator(); iterator2
.hasNext();) {
Item item = iterator2.next();
if (!item.getB().equals("")) {
isEnd = false;
}
}
System.out.println(tmp.items);
if (!isEnd) {
System.out.println("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
System.out.println(tmp.items);
System.out.println(name);
setItemSetItem(tmp, name);
}*/
} else {
System.out
.println("[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]");
gotoMap.put(new GoTo(setName, path), getOutClosure(map, tmp));
}
}
setItemSetItem(lrClosure);// 新的函数负责从一个map的闭包集合求解下一层闭包
System.out.println(map);
System.out.println(gotoMap);
return map;
}
/**
* 以一个输入闭包集合为起始,求下一个闭包,一直到-----无法往map里面加闭包集了,
* 也就是
* 1.需要加的闭包集在map里面,
* 2.·已经在最后面的位置了,没有下一个B符号了。
* @param closure
* @param setName
* @param lrMap
* @return
*/
public Map<String, LRClosure> setItemSetItem(Map<String, LRClosure> lrMap) {
Map<String, LRClosure> tmMap = new HashMap<>();
boolean ischanged = false;// 是否增加了新的Ii集合
for (Iterator<String> iterator = lrMap.keySet().iterator(); iterator
.hasNext();) {
String setName = (String) iterator.next();// 项名
// 对这个集合里面的每一个closure求闭包
for (Iterator<String> iterator2 =
lrMap.get(setName).gotoPath().iterator(); iterator2.hasNext();) {
String path = (String) iterator2.next();
LRClosure tmp = lrMap.get(setName).getNextClosure(path);
if (!map.containsValue(tmp)) {
String name = new String("I" + key);
map.put(name, tmp);
tmMap.put(name, tmp);
gotoMap.put(new GoTo(setName, path), name);
key++;
ischanged = true;
} else {
System.out.println("------------------------------------");
gotoMap.put(new GoTo(setName, path), getOutClosure(map, tmp));
}
// LRClosure tmp = lrMap.get(type).getNextClosure(path);
}
}
if (ischanged) {
setItemSetItem(tmMap);
}
return map;
}
public boolean setItemSetItem(LRClosure closure, String setName) {
boolean isChanged = false;
// System.out.println(closure.getNextClosure("c"));
// System.out.println(
// closure.getNextClosure("c").equals(closure.getNextClosure("c")));
// System.out.println("555555555555555555555");
for (Iterator<String> iterator = closure.gotoPath().iterator(); iterator
.hasNext();) {
String type = (String) iterator.next();
LRClosure tmp = closure.getNextClosure(type);
if (!map.containsValue(tmp)) {
String name = new String("I" + key);
map.put(name, tmp);
gotoMap.put(new GoTo(setName, type), name);
key++;
isChanged = true;
} else {
System.out
.println("[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]");
gotoMap.put(new GoTo(setName, type), getOutClosure(map, tmp));
}
}
System.out.println(map);
System.out.println(gotoMap);
return isChanged;
}
/**
* 在closure图里面找对应值的键值名称,返回该键值
* @param lrMap
* @param lrClosure
* @return
*/
private String getOutClosure(Map<String, LRClosure> lrMap,
LRClosure lrClosure) {
for (Iterator<String> iterator = lrMap.keySet().iterator(); iterator
.hasNext();) {
String type = (String) iterator.next();
if (lrMap.get(type).equals(lrClosure)) {
return type;
}
}
return new String("");
}
public static void main(String[] args) {
ProductionList productionList = new ProductionList();
ItemTable itemTable = new ItemTable(productionList);
itemTable.setItemSet(itemTable.lrClosure, "I0");
}
}
goto.java
package parse2;
public class GoTo {
String closureID;// 闭包初始名称
String path;
public GoTo(String closureID, String path) {
super();
this.closureID = closureID;
this.path = path;
}// 路径
@Override
public String toString() {
// TODO Auto-generated method stub
return new String("(" + closureID + "," + path + ")");
}
}
结合上次博客的【编译原理】求first集合的代码实现java
以及LRClosure.java
package parse2;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class LRClosure {
List<Production> productions;
List<Item> items;
FirstFollow firstFollow;
List<String> used;
@Override
public int hashCode() {
StringBuffer stringBuffer2 = new StringBuffer();
for (Iterator<Item> iterator = this.items.iterator(); iterator.hasNext();) {
Item item = (Item) iterator.next();
stringBuffer2.append(item);
}
int hash = 7;
hash = 31 * hash + stringBuffer2.hashCode();
return hash;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (null == obj) {
return false;
}
if (this.getClass() != obj.getClass()) {
return false;
}
LRClosure user = (LRClosure) obj;
StringBuffer stringBuffer = new StringBuffer();
for (Iterator<Item> iterator = user.items.iterator(); iterator.hasNext();) {
Item item = (Item) iterator.next();
stringBuffer.append(item);
}
StringBuffer stringBuffer2 = new StringBuffer();
for (Iterator<Item> iterator = this.items.iterator(); iterator.hasNext();) {
Item item = (Item) iterator.next();
stringBuffer2.append(item);
}
System.out.println("LRClosure.equals()");
System.out.println(stringBuffer);
System.out.println(stringBuffer2);
if (stringBuffer.toString().equals(stringBuffer2.toString())) {
return true;
}
return false;
}
/**
* 初始化LR,输入产生式集合
* @param productionList
*/
public LRClosure(ProductionList productionList) {
productions = productionList.getProductions();
items = new ArrayList<>();
firstFollow = new FirstFollow(productionList);
used = new ArrayList<>();
}
public LRClosure(List<Production> productionList) {
productions = productionList;
items = new ArrayList<>();
firstFollow = new FirstFollow(productionList);
used = new ArrayList<>();
}
/**
* 查找指定左部的产生式集合
* @param B
* @return
*/
public List<Production> findProduction(String B) {
List<Production> pro = new ArrayList<>();
for (Iterator<Production> iterator = productions.iterator(); iterator
.hasNext();) {
Production production = (Production) iterator.next();
if (production.getLeft().equals(B)) {
pro.add(production);
}
}
return pro;
}
/**
* 从一个item出发,求他的闭包,嵌套求到全部的闭包
* @param item
*/
public void getNextClosureItem(Item item) {
for (Iterator<Production> iterator =
findProduction(item.getB()).iterator(); iterator.hasNext();) {
Production pro = (Production) iterator.next();
System.out.println(pro);
List<String> beta_a = new ArrayList<>();
for (int i = 0; i < item.getBeta().length; i++) {
beta_a.add(item.getBeta()[i]);
System.out.println(item.getBeta()[i] + "---------");
}
beta_a = firstFollow.getFirst(beta_a);
// System.out.println(beta_a);
if (beta_a.contains("null") || beta_a.isEmpty()) {
// beta_a求first集合得到空,或者beta_a是空
System.out.println("beta_a求first集合得到空,或者beta_a是空");
// 如果求得的first集合包含了空,就把a加到beta里面
for (int i = 0; i < item.getA().length; i++) {
beta_a.add(item.getA()[i]);
}
}
System.out.println("*************************");
System.out.println(beta_a);
Item tmp = new Item(pro, beta_a);
items.add(tmp);
used.add(tmp.getLeft());
if (!used.contains(tmp.getB())) {
System.out.println(tmp.getB());
getNextClosureItem(tmp);
}
}
System.out.println(items);
}
/**
* 构造闭包项目
* @param production 产生式构造闭包
*/
public void setClosureItem(Production production) {
Item item = new Item(production);// 用产生式构造项
items.add(item);
System.out.println(item);
used.add(item.getLeft());
getNextClosureItem(item);
}
/**
* 返回它跳到下一条路径的转移符号
* @return
*/
public List<String> gotoPath() {
List<String> list = new ArrayList<>();
for (Iterator<Item> iterator = items.iterator(); iterator.hasNext();) {
Item string = (Item) iterator.next();
list.add(string.getB());
}
return list;
}
/**
* 给定路径path,就这个产生式的下一个闭包集合
* @param path
* @return
*/
public LRClosure getNextClosure(String path) {
LRClosure lrClosure = new LRClosure(productions);
System.out.println(lrClosure);
// List<Item> items = new ArrayList<>();
for (Iterator<Item> iterator = items.iterator(); iterator.hasNext();) {
Item item = (Item) iterator.next();
System.out.println("LRClosure.getNextClosure()");
System.out.println(item);
if (path.equals(item.getB())) {
Item tmp = item.move();
System.out.println("^^^^^^^^^");
System.out.println(tmp);
lrClosure.items.add(tmp);
lrClosure.getNextClosureItem(tmp);
}
}
return lrClosure;
}
@Override
public String toString() {
return items.toString();
}
public static void main(String[] args) {
ProductionList productionList = new ProductionList();
LRClosure lrClosure = new LRClosure(productionList);
lrClosure.setClosureItem(productionList.getProductions().get(0));
System.out.println(lrClosure.gotoPath());
}
}