import edu.neu.ccs.demeter.dj.*; import edu.neu.ccs.demeter.aplib.*; import java.util.*; import edu.neu.ccs.demeter.*; class SemanticChecker { public SemanticChecker() { super(); } public static SemanticChecker parse(java.io.Reader in) throws ParseException { return new Parser(in)._SemanticChecker(); } public static SemanticChecker parse(java.io.InputStream in) throws ParseException { return new Parser(in)._SemanticChecker(); } public static SemanticChecker parse(String s) { try { return parse(new java.io.StringReader(s)); } catch (ParseException e) { throw new RuntimeException(e.toString()); } } // the runtime class graph ClassGraph runtimeCg; // the class graph defined by the input class dictionary edu.neu.ccs.demeter.aplib.cd.ClassGraph inputCg; // a pointer to the traversal XAspects component TraversalAspect ta; public void generate(ClassDictionaryAspect cda, TraversalAspect travA) { // create the runtime class graph runtimeCg = new ClassGraph(true, false); // create the class graph for the input class dictionary inputCg = ClassGraph.fromString(cda.get_textcd().get_text().toString()); inputCg.normalize(); // assign the pointer to the provided traversal aspect component ta = travA; } public void check() { // make some Traversal XAspects specific checks // i.e., make sure that "nodes" and regular expression declarations // utilize other declarations that are defined check_trav_nodesAndRegExp(); // check in all places for undefined classes // i.e., check used classes in class dictionary, strategy expressions, // and class list declarations checkForUndefinedClasses(); // verify that strategies represent legal paths checkTraversalPaths(); } private void check_trav_nodesAndRegExp() { // check that all used Strategy names in "nodes" node set decls are defined List usedNames = runtimeCg.gather(ta, "from TraversalAspect via StrategyName to" + Main.FIdent); List defNames = runtimeCg.gather(ta, "from TraversalAspect via StrategyDeclName to" + Main.FIdent); subset_test(usedNames, defNames); // check that regular expressions reference defined node sets List defNodeSetDecls = runtimeCg.gather(ta, "from TraversalAspect via NodesetDeclName to" + Main.FIdent); List usedNodeSetDecls = runtimeCg.gather(ta, "from TraversalAspect via NodesetIdent to" + Main.FIdent); subset_test(usedNodeSetDecls, defNodeSetDecls); } private void checkForUndefinedClasses() { // get a list of all used classes in input cd, and make sure each used class // is defined by the cd java.util.Collection c = inputCg.getNodes(); checkDefinesClass(c.iterator()); // check that all classes used in strategy expressions are defined List usedClassNames = runtimeCg.gather(ta, "from TraversalAspect via ClassName to" + Main.FIdent); checkDefinesClass(usedClassNames.iterator()); // check classes are all defined in class list node sets List usedClasses = runtimeCg.gather(ta, "from TraversalAspect via ClassListName to" + Main.FIdent); checkDefinesClass(usedClasses.iterator()); } private void subset_test(List used, List defined) { ListIterator usedIterator = used.listIterator(); while (usedIterator.hasNext()) { Ident next = (Ident) usedIterator.next(); if (!defined.contains(next)) { System.out.println(next.toString() + " undefined."); } } } private void checkTraversalPaths() { List test = runtimeCg.gather(ta, "from TraversalAspect to Strategy"); Strategy strat = (Strategy) test.get(0); // We have been unable to implement this portion as of yet. // It seems the best way would be to create a Traversal object // using the Strategy and parsed class graph, and catch the // possible exceptions (TraversalException, ParseException), // but we have been unable to do this due to incompatibilities // between our Strategy defined in our cd, the Traversal object // and our parsed class graph. /* The following code is provided as an example of this semantic * checking process, if the Strategies were stored in String format: * * try { * // create a strategy from the string, * // syntax errors result in StrategyParseException * Strategy strategy = new Strategy(srategyAsString); * * // compute traversal, bad path results in TraversalException * Traversal.compute(strategy, inputCg); * } catch (StrategyParseException spe) { * // invalid strategy syntax * System.out.println("StrategyParseException: " + spe.getMessage()); * } catch (TraversalException te) { * // bad traversal path * System.out.println("TraversalException: " + te.getMessage()); * } catch (Exception e) { * System.out.println(e.getMessage()); * } */ } private void checkDefinesClass(Iterator iter) { while (iter.hasNext()) { Object next = iter.next(); if (!inputCg.definesClass(next.toString())) { System.out.println(next.toString() + " undefined."); } } } void universal_trv0_bef(UniversalVisitor _v_) { ((UniversalVisitor) _v_).before(this); } void universal_trv0_aft(UniversalVisitor _v_) { ((UniversalVisitor) _v_).after(this); } void universal_trv0(UniversalVisitor _v_) { universal_trv0_bef(_v_); universal_trv0_aft(_v_); } }