【编译原理】构造LR语法分析表的代码实现java

版权声明:本文为博主原创文章,未经博主允许不得转载。如果你非要转载,麻烦加上我的原网址,谢谢。http://blog.csdn.net/qinglingLS https://blog.csdn.net/qinglingLS/article/details/89819958

接上面的几篇博文:
【HIT哈工大编译原理实验】词法分析程序java
【编译原理】求first集合的代码实现java
【编译原理】求GOTO图的代码实现java
【编译原理】LL(1)分析法代码

以及一些关于编译的说明博客……自己按照日期找一下把~!
接下来就要做一些比较激动的事情了~!
目标文法:

S' -> S
S -> C C
C -> c C|d

在这里插入图片描述
为了构造一个如图中4-40的表,代码实现如下:
先展示一下效果:
action表
在这里插入图片描述
goto表:
在这里插入图片描述
构造完这两个表之后,就只需要读字符,然后解析就可以了,读取词流已经在词法分析器里面做好了:

【HIT哈工大编译原理实验】词法分析程序java

算法如下:
在这里插入图片描述

代码如下:

ActionTable.java

package parse2;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

public class ActionTable {
  int line;// 列
  int row;// 行
  String[][] aStrings;
  List<Production> proList;
  Map<GoTo, String> gotoMap;
  Map<String, LRClosure> lrMap;
  List<String> victs;

  public ActionTable(List<Production> productionList, Map<GoTo, String> gotoMap,
      Map<String, LRClosure> lrMap) {
    proList = productionList;
    this.gotoMap = gotoMap;
    this.lrMap = lrMap;
    row = lrMap.size() + 1;
    victs = getVicts();
    line = victs.size() + 1;
    aStrings = new String[row][line];
    for (int i = 0; i < row; i++) {
      for (int j = 0; j < line; j++) {
        aStrings[i][j] = ".";
      }
    }
    for (int i = 1; i < victs.size() + 1; i++) {
      aStrings[0][i] = victs.get(i - 1);
    }
    int i = 1;
    for (Iterator<String> iterator = lrMap.keySet().iterator(); iterator
        .hasNext();) {
      String setName = (String) iterator.next();
      aStrings[i][0] = setName;
      i++;
    }
  }

  /**
   * 获取全部终结符
   * @return
   */
  public List<String> getVicts() {
    List<String> victs = new ArrayList<>();
    victs.add("$");
    for (Iterator<Production> iterator = proList.iterator(); iterator
        .hasNext();) {
      Production production = (Production) iterator.next();
      for (int i = 0; i < production.getRight().length; i++) {
        if (!isVariable(production.getRight()[i])
            && !victs.contains(production.getRight()[i])) {
          victs.add(production.getRight()[i]);
        }
      }
    }
    return victs;
  }


  /**
  * 判断是不是终结符,如果左边没这个作为开头的,那就是终结符了。
  * @param str
  * @param proList
  * @return
  */
  public boolean isVariable(String str) {
    for (Iterator<Production> iterator = proList.iterator(); iterator
        .hasNext();) {
      Production production = (Production) iterator.next();
      if (production.getLeft().equals(str)) {
        // 一旦找到左边有等于str的字符,就说明str不算终结符,返回真:是变量
        return true;
      }
    }
    return false;
  }

  /**
   * 设置动作表
   * @param gotoMap
   * @param lrMap
   */
  public void setActionTable() {
    System.out.println(gotoMap);
    System.out.println(lrMap);
    for (Iterator<String> iterator = lrMap.keySet().iterator(); iterator
        .hasNext();) {
      String setName = (String) iterator.next();
      LRClosure tmp = lrMap.get(setName);
      System.out.println(setName);
      for (Iterator<Item> iterator2 = tmp.items.iterator(); iterator2
          .hasNext();) {
        System.out.println("ActionTable.setActionTable()");
        Item item = (Item) iterator2.next();
        System.out.println(item);
        System.out.println("----------------------------------------");
        System.out.println(item.getB());
        if (item.getB().equals("") && !item.getLeft().equals("S'")) {
          // 如果[A->alpha·,a]在Ii里,而且A!=S’,那么将Action[i,a]设置为规约A->alpha
          StringBuffer stringBuffer = new StringBuffer();
          for (int i = 0; i < item.getAlpha().length; i++) {
            stringBuffer.append(item.getAlpha()[i]);
          }
          for (int i = 0; i < item.getA().length; i++) {
            if (!setTable(setName, item.getA()[i],
                "r" + item.getLeft() + "->" + stringBuffer.toString())) {
              throw new Error("规约表设置出现了错误!!产生了语义冲突!!!!");
            }
          }
        } else if (item.getLeft().equals("S'") && item.getB().equals("")
            && item.setCheckAcc()) {
          setTable(setName, "$", "ACC");
        } else if (victs.contains(item.getB())) {// 如果不是变量,就去找goto表
          // 查找有没有GoTo(Ii,a)=Ij,有的话就把action[i,a]设置为移入j,sj
          String result = findGotoTable(setName, item.getB());
          System.out.println("????????????????????");
          System.out.println(result);
          if (!result.equals("")) {
            // 把action[i,a]设置为移入j,sj
            if (!setTable(setName, item.getB(), "s" + result)) {
              throw new Error("移入表设置出现了错误!!产生了语义冲突!!!!");
            }
          }
        }
      }
    }
  }



  /**
   * 选定i,a对table进行赋值
   * @param i
   * @param a
   * @param sj
   * @return
   */
  public boolean setTable(String i, String a, String sj) {
    // System.out.println(i);
    // System.out.println(a);
    // System.out.println(sj);
    int y = 0;
    int x = 0;
    for (int j = 0; j < line; j++) {
      if (a.equals(aStrings[0][j])) {
        y = j;
      }
    }
    for (int j = 0; j < row; j++) {
      if (i.equals(aStrings[j][0])) {
        x = j;
      }
    }
    // System.out.println(y);
    // System.out.println(x);
    if (aStrings[x][y].equals(".")) {
      aStrings[x][y] = sj;
      return true;
    }
    return false;

  }

  /**
   * 查找goto表有没有这个关系,有返回true,没有返回false;
   * @param Ii
   * @param a
   * @param Ij
   * @return
   */
  public String findGotoTable(String Ii, String a) {
    for (Iterator<GoTo> iterator = gotoMap.keySet().iterator(); iterator
        .hasNext();) {
      GoTo goto_tmp = (GoTo) iterator.next();
      if (goto_tmp.closureID.equals(Ii) && goto_tmp.path.equals(a)) {
        return new String(gotoMap.get(goto_tmp));
      }
    }
    return "";
  }


  @Override
  public String toString() {
    StringBuffer stringBuffer = new StringBuffer();
    for (int i = 0; i < row; i++) {
      for (int j = 0; j < line; j++) {
        stringBuffer.append(aStrings[i][j] + " ");
      }
      stringBuffer.append("\n");
    }
    return stringBuffer.toString();
  }


  public static void main(String[] args) {
    ProductionList productionList = new ProductionList();
    ItemTable itemTable = new ItemTable(productionList);
    itemTable.setItemSet(itemTable.lrClosure, "I0");
    ActionTable actionTable = new ActionTable(productionList.getProductions(),
        itemTable.gotoMap, itemTable.map);
    System.out.println(actionTable.toString());
    actionTable.setActionTable();
    System.out.println(actionTable.toString());

  }



}

GoToTable.java

package parse2;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

public class GoToTable {
  int line;// 列
  int row;// 行
  String[][] aStrings;
  List<Production> proList;
  Map<GoTo, String> gotoMap;
  Map<String, LRClosure> lrMap;
  List<String> variables;


  public GoToTable(List<Production> productionList, Map<GoTo, String> gotoMap,
      Map<String, LRClosure> lrMap) {
    proList = productionList;
    this.gotoMap = gotoMap;
    this.lrMap = lrMap;
    row = lrMap.size() + 1;
    variables = getVariables();
    line = variables.size() + 1;
    aStrings = new String[row][line];
    for (int i = 0; i < row; i++) {
      for (int j = 0; j < line; j++) {
        aStrings[i][j] = ".";
      }
    }
    for (int i = 1; i < variables.size() + 1; i++) {
      aStrings[0][i] = variables.get(i - 1);
    }
    int i = 1;
    for (Iterator<String> iterator = lrMap.keySet().iterator(); iterator
        .hasNext();) {
      String setName = (String) iterator.next();
      aStrings[i][0] = setName;
      i++;
    }
  }


  @Override
  public String toString() {
    StringBuffer stringBuffer = new StringBuffer();
    for (int i = 0; i < row; i++) {
      for (int j = 0; j < line; j++) {
        stringBuffer.append(aStrings[i][j] + " ");
      }
      stringBuffer.append("\n");
    }
    return stringBuffer.toString();
  }

  /**
   * 获取全部变量
   * @return
   */
  public List<String> getVariables() {
    List<String> victs = new ArrayList<>();
    for (Iterator<Production> iterator = proList.iterator(); iterator
        .hasNext();) {
      Production production = (Production) iterator.next();
      for (int i = 0; i < production.getRight().length; i++) {
        if (isVariable(production.getRight()[i])
            && !victs.contains(production.getRight()[i])) {
          victs.add(production.getRight()[i]);
        }
      }
    }
    return victs;
  }


  /**
   * 判断是不是终结符,如果左边没这个作为开头的,那就是终结符了。
   * @param str
   * @param proList
   * @return
   */
  public boolean isVariable(String str) {
    for (Iterator<Production> iterator = proList.iterator(); iterator
        .hasNext();) {
      Production production = (Production) iterator.next();
      if (production.getLeft().equals(str)) {
        // 一旦找到左边有等于str的字符,就说明str不算终结符,返回真:是变量
        return true;
      }
    }
    return false;
  }

  /**
   * 如果GOTO(Ii,A)=Ij,那么GOTO[i,A]=j
   */
  public void setGotoTable() {
    for (Iterator<GoTo> iterator = gotoMap.keySet().iterator(); iterator
        .hasNext();) {
      GoTo goTo = (GoTo) iterator.next();
      if (variables.contains(goTo.getPath())) {
        // 如果是变量的话
        if (!setTable(goTo.getClosureID(), goTo.getPath(), gotoMap.get(goTo))) {
          throw new Error("goto设置出现了错误!!产生了冲突!!!!");
        } ;
      }
    }

  }


  /**
   * 选定i,a对table进行赋值
   * @param i
   * @param a
   * @param sj
   * @return
   */
  public boolean setTable(String i, String a, String sj) {
    // System.out.println(i);
    // System.out.println(a);
    // System.out.println(sj);
    int y = 0;
    int x = 0;
    for (int j = 0; j < line; j++) {
      if (a.equals(aStrings[0][j])) {
        y = j;
      }
    }
    for (int j = 0; j < row; j++) {
      if (i.equals(aStrings[j][0])) {
        x = j;
      }
    }
    // System.out.println(y);
    // System.out.println(x);
    if (aStrings[x][y].equals(".")) {
      aStrings[x][y] = sj;
      return true;
    }
    return false;

  }


  public static void main(String[] args) {
    ProductionList productionList = new ProductionList();
    ItemTable itemTable = new ItemTable(productionList);
    itemTable.setItemSet(itemTable.lrClosure, "I0");
    GoToTable goToTable = new GoToTable(productionList.getProductions(),
        itemTable.gotoMap, itemTable.map);
    System.out.println(goToTable.toString());
    goToTable.setGotoTable();

    System.out.println(goToTable.toString());

  }
}

猜你喜欢

转载自blog.csdn.net/qinglingLS/article/details/89819958