【编译原理】求first集合的代码实现java

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

哈哈,经历了千辛万苦,我!终于!写出来了!
其实总体说来也不难,但是我比较傻,想来想去都想不通,现在终于写出来了,请大家分享一下我的快乐~~~~~~哈哈哈!!
下面是这部分的代码,我贴一部分,剩下的等我把求follow集实现再写一篇博文来给大家看!
请给我点赞谢谢~!!!
实现得非常简洁明了(自夸)
你可以看下注释,写的非常清楚啦!!!

package parse2;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import parse2.Production;

public class FirstFollow {
  List<Production> proList = new ArrayList<Production>();



  public FirstFollow(ProductionList productionList) {
    proList = productionList.getProductions();
  }

  /**
   * 判断是不是终结符,如果左边没这个作为开头的,那就是终结符了。
   * @param str
   * @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 str
   * @return
   */
  public boolean isEmpty(String str) {
    for (Iterator<Production> iterator = proList.iterator(); iterator
        .hasNext();) {
      Production production = (Production) iterator.next();
      if (production.getLeft().equals(str)) {
        for (int i = 0; i < production.getRight().length; i++) {
          // System.out.println(production.getRight()[i]);
          if (production.getRight()[i].equals("null")) {
            return true;
          }
        }
      }
    }
    return false;
  }

  /**
   * 返回包含这个左部的产生式集合,
   * @param B
   * @param productions
   * @return
   */
  public List<Production> findLeft(String B) {
    List<Production> list = new ArrayList<>();
    for (Iterator<Production> iterator = proList.iterator(); iterator
        .hasNext();) {
      Production production = (Production) iterator.next();
      // System.out.println(production.getLeft());
      if (production.getLeft().equals(B)) {
        list.add(production);
      }
    }
    return list;
  }

  /**
   * 获取非终结符号的产生式的first集合X->Y1Y2Y3Y4Y5……这样的,
   * @param str X
   * @return
   */
  public List<String> getFirstItem(Production production) {
    List<String> list = new ArrayList<>();// 获取包含这个str左部的产生式
    // 遍历这个产生式的每一项,其中每个产生式的每一项也需要遍历。
    for (int i = 0; i < production.getRight().length; i++) {
      if (!production.getLeft().equals(production.getRight()[i])) {
        list.addAll(getFirst(production.getRight()[i]));
        System.out.println(production.getRight()[i]);
      } // 没有左递归
      if (!isEmpty(production.getRight()[i])) {
        // 这个项里没有包含空产生式的话,就继续求解,否则结束。
        return list;
      }

    }
    /* List<Production> findList = findLeft(str);
    
    for (Iterator<Production> iterator = findList.iterator(); iterator
        .hasNext();) {
      Production production = (Production) iterator.next();
      for (int i = 0; i < production.getRight().length; i++) {
        System.out.println(production.getRight()[i]);
        list.addAll(getFirst(production.getRight()[i]));
        if (!isEmpty(production.getRight()[i])) {
          return list;
        }
      }
    }*/
    return list;
  }

  /**
   * 判断是不是空产生式集
   * @param strings
   * @return
   */
  public boolean isEmpty(String[] strings) {
    for (int i = 0; i < strings.length; i++) {
      if (strings[i].equals("null")) {
        return true;
      }
    }
    return false;
  }


  /**
   * 获取first集合
   * @param str
   * @return
   */
  public List<String> getFirst(String str) {
    List<String> list = new ArrayList<>();
    List<Production> productions = findLeft(str);
    System.out.println(productions);
    for (Iterator<Production> iterator = productions.iterator(); iterator
        .hasNext();) {
      Production production = (Production) iterator.next();
      if (isEmpty(production.getRight())) {
        System.out.println("-------------------null------------------");
        // 检查X->null是否成立
        list.add("null");
      } else if (!isVariable(production.getRight()[0])
          && !isEmpty(production.getRight())) {
        // 是终结符的话就直接加入。
        System.out.println("-------------------vict------------------");
        list.add(production.getRight()[0]);
      } else {
        System.out.println("-------------------set------------------");
        list.addAll(getFirstItem(production));
      }
    }
    return list;
  }

  public static void main(String[] args) {
    ProductionList productionSet = new ProductionList();
    System.out.println(productionSet.toString());
    FirstFollow firstFollow = new FirstFollow(productionSet);
    System.out.println(firstFollow.getFirst("T'"));;
  }
}

效果示意:
我用的产生式如下:
龙书(紫色第二版)P140的例子文法,当然其他的文法也不在话下~~
另外注意,左递归不消除的话可能会导致循环哦!!!

E -> T E'
E' -> + T E'|null
T -> F T'
T' -> * F T'|null
F -> ( E )|id

代码运行结果:这里的null表示空~!
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

现在的心情非常激动~~!

猜你喜欢

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