private void removeDead()

in jflex/src/main/java/jflex/core/NFA.java [708:779]


  private void removeDead(int start, int end) {
    if (Build.DEBUG) {
      Out.debug("removeDead (" + start + "," + end + ") " + Out.NL + this);
    }

    StateSet notvisited = tempStateSet;
    StateSet reachable = new StateSet(numStates, start);

    notvisited.clear();
    notvisited.addState(start);

    while (notvisited.containsElements()) {
      int state = notvisited.getAndRemoveElement();
      notvisited.add(reachable.complement(epsilon[state]));
      reachable.add(epsilon[state]);
      for (int i = 0; i < numInput; i++) {
        notvisited.add(reachable.complement(table[state][i]));
        reachable.add(table[state][i]);
      }
    }

    if (Build.DEBUG) {
      Out.debug("reachable states " + reachable);
    }

    StateSet live = new StateSet(numStates, end);
    boolean changed = true;

    // compute all live states
    while (changed) {
      changed = false;
      Out.debug("live: " + live);
      StateSet complement = live.complement(reachable);
      if (complement == null) throw new GeneratorException(new NullPointerException(), true);
      for (int s : complement) {
        for (int i = 0; i < numInput; i++) {
          if (table[s][i] != null) {
            for (int state : table[s][i]) {
              if (live.hasElement(state)) {
                changed = true;
                live.addState(s);
              }
            }
          }
        }
        if (epsilon[s] != null) {
          for (int state : epsilon[s]) {
            if (live.hasElement(state)) {
              changed = true;
              live.addState(s);
            }
          }
        }
      }
    }

    if (Build.DEBUG) {
      Out.debug("live states: " + live);
    }

    // now remove all transitions to non-live states (unless everything is live)
    if (!reachable.equals(live)) {
      for (int s : reachable) {
        for (int i = 0; i < numInput; i++) if (table[s][i] != null) table[s][i].intersect(live);
        if (epsilon[s] != null) epsilon[s].intersect(live);
      }
    }

    if (Build.DEBUG) {
      Out.debug("Removed dead states " + Out.NL + this);
    }
  }