Program: 5219
Project: 5219
Buggy source:
/** 
 * Generates the parse table for the set of rules passed into this parser generator. The parse table can be obtained from the getStartState() function.
 */
public void generate(){
  Rule startRule=rules.getStartRule();
  LALRItemSet initialSet=new LALRItemSet();
  int productionCount=startRule.getProductions().length;
  for (int i=0; i < productionCount; i++) {
    LALRItem startItem=new LALRItem(startRule,i,0);
    startItem.addLookahead(null);
    initialSet.addKernelItem(startItem);
  }
  initialSet.calculateClosureItems(rules);
  Map<LALRItemSet,LALRItemSet> itemSets=new HashMap<LALRItemSet,LALRItemSet>();
  itemSets.put(initialSet,initialSet);
  Deque<LALRItemSet> stack=new LinkedList<LALRItemSet>();
  stack.add(initialSet);
  Map<LALRItemSet,Map<Object,LALRItemSet>> transitions=new HashMap<LALRItemSet,Map<Object,LALRItemSet>>();
  while (!stack.isEmpty()) {
    LALRItemSet set=stack.pop();
    Map<Object,LALRItemSet> setTransitions=findTransitions(set);
    for (    Entry<Object,LALRItemSet> transition : setTransitions.entrySet()) {
      LALRItemSet transitionSet=transition.getValue();
      transitionSet.calculateClosureItems(rules);
      LALRItemSet existingSet=itemSets.get(transitionSet);
      if (existingSet == null) {
        itemSets.put(transitionSet,transitionSet);
        stack.add(transitionSet);
        continue;
      }
      if (existingSet.containsLookaheads(transitionSet)) {
        continue;
      }
      existingSet.combineLookaheads(transitionSet);
      existingSet.calculateClosureItems(rules);
      transition.setValue(existingSet);
      stack.add(existingSet);
    }
    transitions.put(set,setTransitions);
  }
  startState=generateStates(initialSet,transitions,itemSets.keySet());
}

Fixed version (ground truth):
/** 
 * Generates the parse table for the set of rules passed into this parser generator. The parse table can be obtained from the getStartState() function.
 */
public void generate(){
  final Rule startRule=rules.getStartRule();
  Object generatedStartRuleType=new Object(){
    @Override public String toString(){
      return "String_Node_Str";
    }
  }
;
  Rule newStartRule=new Rule(generatedStartRuleType,new Object[]{startRule.getType()}){
    @Override public Object match(    Object[] types,    Object[] args){
      if (types.length == 1 && types[0] == startRule.getType()) {
        return args[0];
      }
      throw badTypeList();
    }
  }
;
  rules.addStartRule(newStartRule);
  LALRItemSet initialSet=new LALRItemSet();
  LALRItem startItem=new LALRItem(newStartRule,0,0);
  startItem.addLookahead(null);
  initialSet.addKernelItem(startItem);
  initialSet.calculateClosureItems(rules);
  Map<LALRItemSet,LALRItemSet> itemSets=new HashMap<LALRItemSet,LALRItemSet>();
  itemSets.put(initialSet,initialSet);
  Deque<LALRItemSet> stack=new LinkedList<LALRItemSet>();
  stack.add(initialSet);
  Map<LALRItemSet,Map<Object,LALRItemSet>> transitions=new HashMap<LALRItemSet,Map<Object,LALRItemSet>>();
  while (!stack.isEmpty()) {
    LALRItemSet set=stack.pop();
    Map<Object,LALRItemSet> setTransitions=findTransitions(set);
    for (    Entry<Object,LALRItemSet> transition : setTransitions.entrySet()) {
      LALRItemSet transitionSet=transition.getValue();
      transitionSet.calculateClosureItems(rules);
      LALRItemSet existingSet=itemSets.get(transitionSet);
      if (existingSet == null) {
        itemSets.put(transitionSet,transitionSet);
        stack.add(transitionSet);
        continue;
      }
      if (existingSet.containsLookaheads(transitionSet)) {
        continue;
      }
      existingSet.combineLookaheads(transitionSet);
      existingSet.calculateClosureItems(rules);
      transition.setValue(existingSet);
      stack.add(existingSet);
    }
    transitions.put(set,setTransitions);
  }
  startState=generateStates(initialSet,transitions,itemSets.keySet());
}