// checks for undefined elements // // Collaboration // role System played by Grammar // role UsedElementHolder played by Expression // role Element played by NonTerminal // System = List(Element) List(UsedElementHolder). // UsedElementHolder = List(Element). // Element = Ident. Grammar{ {{ // where we want to go String si = "from NonTerminal to edu.neu.ccs.demeter.Ident"; String getDef = "from Grammar bypassing Expression to NonTerminal"; String getUsed = "from Grammar through Expression to NonTerminal"; int errors = 0; int isDefinedExactlyOnce(ClassGraph cg){ checkDefined(cg, getDefinedThings(cg)); return errors; } HashSet getDefinedThings(final ClassGraph cg){ return (HashSet)cg.traverse(this, getDef, new Visitor(){ HashSet rv = new HashSet(); void before(NonTerminal v){ Ident i = (Ident) cg.fetch(v,si); if (rv.contains(i)) { errors++; System.out.println("The element "+ i + " is defined more than once.");} else rv.add(i); } public Object getReturnValue(){ return rv; } }); } void checkDefined(final ClassGraph cg, final HashSet definedSet){ cg.traverse(this, getUsed, new Visitor(){ void before(NonTerminal v){ Ident i = (Ident) cg.fetch(v,si); if(!definedSet.contains(i)) { System.out.println("The element "+ i + " is undefined."); errors++; } } }); } }} }