1 3 package ro.infoiasi.donald.compiler.cfg; 4 5 import java.util.*; 6 7 public class Productions { 8 private List prodByIndex = new ArrayList(); 9 10 private Map prodByLHS = new LinkedHashMap(); 11 private Map prodByRHS = new HashMap(); 12 13 private Production addToMaps(Production prod) { 14 NonTerminal lhs = prod.getLHS(); 15 Word rhs = prod.getRHS(); 16 17 LinkedList right; 18 if (prodByLHS.containsKey(lhs)) { 19 right = (LinkedList)prodByLHS.get(lhs); 20 } else { 21 right = new LinkedList(); 22 } 23 Iterator it = right.iterator(); 25 while (it.hasNext()) { 26 Production oldProd = (Production)it.next(); 27 if (lhs.equals(oldProd.getLHS()) && rhs.equals(oldProd.getRHS())) { 28 return oldProd; 29 } 30 } 31 right.add(prod); 32 prodByLHS.put(lhs, right); 33 34 35 LinkedList left; 36 if (prodByRHS.containsKey(rhs)) { 37 left = (LinkedList)prodByRHS.get(rhs); 38 } else { 39 left = new LinkedList(); 40 } 41 left.add(prod); 42 prodByRHS.put(rhs, left); 43 return prod; 44 } 45 46 private void clearMaps() { 47 prodByLHS.clear(); 48 prodByRHS.clear(); 49 } 50 51 public Production addNew(NonTerminal lhs, Word rhs, 52 int precedence, SemanticAction action) { 53 Production prod = new Production(lhs, rhs, precedence, action, count()); 54 prod = addToMaps(prod); 55 prodByIndex.add(prod); 56 return prod; 57 } 58 59 public Production addNew(NonTerminal lhs, Word rhs, int precedence) { 60 return addNew(lhs, rhs, precedence, null); 61 62 } 63 64 public Production addNew(NonTerminal lhs, Word rhs, SemanticAction action) { 65 return addNew(lhs, rhs, Production.LAST_TERMINAL_PRECEDENCE, action); 66 } 67 68 public Production addNew(NonTerminal lhs, Word rhs) { 69 return addNew(lhs, rhs, Production.LAST_TERMINAL_PRECEDENCE, null); 70 } 71 72 public void addNew(NonTerminal lhs, List rhsList, 73 int precedence, SemanticAction action) { 74 Iterator it = rhsList.iterator(); 75 while (it.hasNext()) { 76 Word rhs = (Word)it.next(); 77 addNew(lhs, rhs, precedence, action); 78 } 79 } 80 81 public void addNew(NonTerminal lhs, List rhsList, int precedence) { 82 addNew(lhs, rhsList, precedence, null); 83 } 84 85 public void addNew(NonTerminal lhs, List rhsList, SemanticAction action) { 86 addNew(lhs, rhsList, Production.LAST_TERMINAL_PRECEDENCE, action); 87 } 88 89 public void addNew(NonTerminal lhs, List rhsList) { 90 addNew(lhs, rhsList, Production.LAST_TERMINAL_PRECEDENCE, null); 91 } 92 93 public int count() { 94 return prodByIndex.size(); 95 } 96 97 public Iterator iterator() { 98 return Collections.unmodifiableList(prodByIndex).iterator(); 99 } 100 101 public Iterator iterator(NonTerminal a) { 102 List prodList = find(a); 103 if (prodList == null) { 104 return new Iterator() { 106 public boolean hasNext() { return false; } 107 public Object next() { throw new NoSuchElementException(); } 108 public void remove() { throw new UnsupportedOperationException (); } 109 }; 110 } else { 111 return Collections.unmodifiableList(prodList).iterator(); 112 } 113 } 114 115 public Production find(int index) { 116 if (index < 0 || index >= count()) { 117 return null; 118 } else { 119 return (Production)prodByIndex.get(index); 120 } 121 } 122 123 public LinkedList find(NonTerminal a) { 124 return (LinkedList)prodByLHS.get(a); 126 } 127 128 public LinkedList find(Word w) { 129 return (LinkedList)prodByRHS.get(w); 131 } 132 133 public void clear() { 134 prodByIndex.clear(); 135 clearMaps(); 136 } 137 138 139 void removeUseless(List s) { 140 clearMaps(); 141 List tmp = new ArrayList(); 142 for (int i = 0; i<prodByIndex.size(); i++) { 143 Production p = find(i); 144 boolean useful = true; 145 if (s.contains(p.getLHS())) { 146 useful = false; 147 } else { 148 Word w = p.getRHS(); 149 WordIterator itW = w.iterator(); 150 while (itW.hasNextNonTerminal()) { 151 NonTerminal a = itW.nextNonTerminal(); 152 if (s.contains(a)) { 153 useful = false; 154 break; 155 } 156 } 157 } 158 if (useful) { 159 p.setIndex(tmp.size()); 160 tmp.add(p); 161 addToMaps(p); 162 } 163 } 164 prodByIndex = tmp; 165 } 166 167 public boolean isInvertible() { 168 Iterator it = prodByRHS.keySet().iterator(); 169 while (it.hasNext()) { 170 List rhsList = find((Word)it.next()); 171 switch (rhsList.size()) { 172 case 0: throw new RuntimeException ("Null value in prodByRHS"); 173 case 1: break; 174 default: return false; 175 } 176 } 177 return true; 178 } 179 180 public String toString() { 181 StringBuffer sb = new StringBuffer (); 182 Set keySet = prodByLHS.keySet(); 183 Iterator it = keySet.iterator(); 184 while (it.hasNext()) { 185 NonTerminal var = (NonTerminal)it.next(); 186 sb.append(var+" ::= "); 187 List rhsList = (List)prodByLHS.get(var); 188 Iterator itL = rhsList.iterator(); 189 while (itL.hasNext()) { 190 sb.append(((Production)itL.next()).getRHS()); 191 if (itL.hasNext()) { 192 sb.append(" | "); 193 } 194 } 195 sb.append(";\n"); 196 } 197 return sb.toString(); 198 } 199 } 200 | Popular Tags |