1 8 9 package net.sourceforge.chaperon.model.grammar; 10 11 import java.io.Serializable ; 12 import java.util.Hashtable ; 13 import java.util.Enumeration ; 14 import java.util.Vector ; 15 16 import net.sourceforge.chaperon.common.IntegerList; 17 import net.sourceforge.chaperon.model.Violations; 18 import net.sourceforge.chaperon.model.symbol.Symbol; 19 import net.sourceforge.chaperon.model.symbol.SymbolList; 20 import net.sourceforge.chaperon.model.symbol.SymbolSet; 21 import net.sourceforge.chaperon.model.symbol.Nonterminal; 22 import net.sourceforge.chaperon.model.symbol.Terminal; 23 24 30 public class Grammar implements Serializable , Cloneable 31 { 32 private Nonterminal startsymbol = null; 34 35 private Vector productions = new Vector (); 37 38 private Hashtable priorities = new Hashtable (); 39 private Hashtable associativities = new Hashtable (); 40 41 private String location = null; 42 43 46 public Grammar() 47 { 48 } 49 50 57 public int addProduction(Production production) 58 { 59 if (production==null) 60 throw new NullPointerException (); 61 62 productions.addElement(production); 63 return productions.size() - 1; 64 } 65 66 71 public void addProduction(Production[] list) 72 { 73 for (int i = 0; i < list.length; i++) 74 { 75 try 76 { 77 addProduction((Production)list[i].clone()); 78 } catch (CloneNotSupportedException cnse) 79 { 80 throw new IllegalArgumentException ("Could not clone token:"+cnse.getMessage()); 81 } 82 } 83 } 84 85 90 public void removeProduction(int index) 91 { 92 productions.removeElementAt(index); 93 } 94 95 101 public void setProduction(int index, 102 Production production) 103 throws IndexOutOfBoundsException 104 { 105 if ((index < 0) || (index > productions.size())) 106 throw new IndexOutOfBoundsException (); 107 productions.setElementAt(production, index); 108 } 109 110 117 public Production getProduction(int index) throws IndexOutOfBoundsException 118 { 119 if ((index < 0) || (index > productions.size())) 120 throw new IndexOutOfBoundsException (); 121 122 return (Production) productions.elementAt(index); 123 } 124 125 132 public IntegerList getProductionList(Symbol ntsymbol) 133 { 134 IntegerList list = new IntegerList(); 135 int i; 136 137 for (i = 0; i < getProductionCount(); i++) 138 { 139 if (getProduction(i).getSymbol().equals(ntsymbol)) 140 list.add(i); 141 } 142 return list; 143 } 144 145 150 public int getProductionCount() 151 { 152 return productions.size(); 153 } 154 155 162 public int indexOf(Production production) 163 { 164 for (int i = 0; i < productions.size(); i++) 165 if (((Production) productions.elementAt(i)).equals(production)) 166 return i; 167 return -1; 168 } 169 170 178 public int indexOf(Symbol ntsymbol) 179 { 180 for (int i = 0; i < productions.size(); i++) 181 if (((Production) productions.elementAt(i)).getSymbol().equals(ntsymbol)) 182 return i; 183 return -1; 184 } 185 186 193 public boolean contains(Production production) 194 { 195 return (indexOf(production) != -1); 196 } 197 198 205 public boolean contains(Symbol ntsymbol) 206 { 207 return (indexOf(ntsymbol) != -1); 208 } 209 210 213 public void removeAllProduction() 214 { 215 productions.removeAllElements(); 216 } 217 218 224 public Enumeration enumerateProduction() 225 { 226 return productions.elements(); 227 } 228 229 234 public Production[] getProduction() 235 { 236 int size = productions.size(); 237 Production[] mArray = new Production[size]; 238 239 for (int index = 0; index < size; index++) 240 mArray[index] = (Production) productions.elementAt(index); 241 return mArray; 242 } 243 244 250 public void setProduction(Production[] productionArray) 251 { 252 productions.removeAllElements(); 253 for (int i = 0; i < productionArray.length; i++) 254 productions.addElement(productionArray[i]); 255 } 256 257 public void setPriority(Terminal terminal, int priority) 258 { 259 if (terminal==null) 260 throw new NullPointerException (); 261 262 priorities.put(terminal, new Integer (priority)); 263 } 264 265 public int getPriority(Terminal terminal) 266 { 267 Integer priority = (Integer )priorities.get(terminal); 268 if (priority==null) 269 return 0; 270 return priority.intValue(); 271 } 272 273 public int getPriority(Production production) 274 { 275 if (!contains(production)) 276 return 0; 277 278 if (production.getPrecedence() != null) 279 return getPriority(production.getPrecedence()); 280 281 SymbolList definition = production.getDefinition(); 282 for (int i = definition.getSymbolCount() - 1; i >= 0; i--) 283 if (definition.getSymbol(i) instanceof Terminal) 284 { 285 int priority = getPriority((Terminal)definition.getSymbol(i)); 286 if (priority==0) 287 return getProductionCount()-indexOf(production); 288 return priority; 289 } 290 291 return getProductionCount()-indexOf(production); 292 } 293 294 public void setAssociativity(Terminal terminal, Associativity assoc) 295 { 296 if (terminal==null) 297 throw new NullPointerException (); 298 299 associativities.put(terminal, assoc); 300 } 301 302 public Associativity getAssociativity(Terminal terminal) 303 { 304 Associativity assoc = (Associativity)associativities.get(terminal); 305 if (assoc==null) 306 return Associativity.NONASSOC; 307 return assoc; 308 } 309 310 public Associativity getAssociativity(Production production) 311 { 312 if (!contains(production)) 313 return Associativity.NONASSOC; 314 315 if (production.getPrecedence() != null) 316 return getAssociativity(production.getPrecedence()); 317 318 SymbolList definition = production.getDefinition(); 319 for (int i = definition.getSymbolCount() - 1; i >= 0; i--) 320 if (definition.getSymbol(i) instanceof Terminal) 321 return getAssociativity((Terminal)definition.getSymbol(i)); 322 323 return Associativity.NONASSOC; 324 } 325 326 331 public SymbolSet getSymbols() 332 { 333 SymbolSet set = new SymbolSet(); 334 335 for (int i = 0; i < getProductionCount(); i++) 336 set.addSymbol(getProduction(i).getSymbols()); 337 return set; 338 } 339 340 345 public void setStartSymbol(Nonterminal startsymbol) 346 { 347 this.startsymbol = startsymbol; 348 } 349 350 355 public Nonterminal getStartSymbol() 356 { 357 return startsymbol; 358 } 359 360 365 public void setLocation(String location) 366 { 367 this.location = location; 368 } 369 370 375 public String getLocation() 376 { 377 return location; 378 } 379 380 386 public Violations validate() 387 { 388 Violations violations = new Violations(); 389 if (startsymbol==null) 390 violations.addViolation("Start symbol is not defined", location); 391 392 if (getProductionCount() <= 0) 393 violations.addViolation("No productions are defined", location); 394 395 for (Enumeration e = productions.elements(); e.hasMoreElements() ;) 396 violations.addViolations(((Production)e.nextElement()).validate()); 397 398 SymbolSet ntsymbols = getSymbols().getNonterminals(); 399 for (int i = 0; i < ntsymbols.getSymbolCount(); i++) 400 if (!contains(ntsymbols.getSymbol(i))) 401 violations.addViolation("Nonterminal symbol \"" + ntsymbols.getSymbol(i) + "\"" + 402 "is not defined through a production", location); 403 404 return violations; 405 } 406 407 412 public String toString() 413 { 414 StringBuffer buffer = new StringBuffer (); 415 416 buffer.append(super.toString()); 417 buffer.append("\n"); 418 419 buffer.append("Terminal symbols:\n"); 420 SymbolSet tsymbols = getSymbols().getTerminals(); 421 for (int i = 0; i < tsymbols.getSymbolCount(); i++) 422 { 423 buffer.append(String.valueOf(i)); 424 buffer.append(".Terminal: "); 425 buffer.append(tsymbols.getSymbol(i)); 426 buffer.append(" Priority="); 427 buffer.append(String.valueOf(getPriority((Terminal)tsymbols.getSymbol(i)))); 428 buffer.append(" Associativity="); 429 buffer.append(String.valueOf(getAssociativity((Terminal)tsymbols.getSymbol(i)))); 430 buffer.append("\n"); 431 } 432 433 buffer.append("Produktions:\n"); 434 for (int i = 0; i < getProductionCount(); i++) 435 { 436 buffer.append(String.valueOf(i)); 437 buffer.append(".Production: "); 438 buffer.append(getProduction(i).toString()); 439 buffer.append("\n"); 440 } 441 442 buffer.append("\n"); 443 444 return buffer.toString(); 445 } 446 447 454 public Object clone() throws CloneNotSupportedException 455 { 456 Grammar clone = new Grammar(); 457 458 clone.startsymbol = startsymbol; 459 for (int i = 0; i < productions.size(); i++) 460 clone.addProduction((Production) ((Production) productions.elementAt(i)).clone()); 461 462 clone.location = location; 463 464 return clone; 465 } 466 } 467 | Popular Tags |