【编译原理】求GOTO图的代码实现java

12 篇文章 2 订阅

经历了一些辛苦,终于把这个部分也写出来了!现在心情挺激动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());
  }

}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值