00001 package edu.mit.csail.sdg.squander.specfile.parser;
00002
00003 import static edu.mit.csail.sdg.squander.specfile.parser.SpecFileParser.FUNCFIELD;
00004 import static edu.mit.csail.sdg.squander.specfile.parser.SpecFileParser.INVARIANT;
00005 import static edu.mit.csail.sdg.squander.specfile.parser.SpecFileParser.PARAMS;
00006 import static edu.mit.csail.sdg.squander.specfile.parser.SpecFileParser.SPECFIELD;
00007 import static edu.mit.csail.sdg.squander.specfile.parser.SpecFileParser.SPECFILE;
00008
00009
00010 import java.util.LinkedList;
00011 import java.util.List;
00012
00013 import org.antlr.runtime.tree.Tree;
00014
00015 import edu.mit.csail.sdg.squander.specfile.parser.SpecFileParser.Node;
00016
00017
00018 public abstract class SpecFileVisitor<N> {
00019
00021 protected Node cast(Tree tree) {
00022 if (!(tree instanceof Node))
00023 throw new SpecFileParserException("malformed node in the AST");
00024 return (Node) tree;
00025 }
00026
00028 protected Node child(Node parent) {
00029 return cast(parent.getChild(0));
00030 }
00031
00032 protected String trimQuotes(String s) {
00033 return s.replaceAll("^\"", "").replaceAll("\"$", "");
00034 }
00035
00037 protected String asText(Tree node) {
00038 if (node.getChildCount() == 0)
00039 return node.getText();
00040 if (node.getChildCount() == 1)
00041 return node.getChild(0).getText();
00042 throw new SpecFileParserException("node cannot be viewed as a text");
00043 }
00044
00045 public final N visit(Tree tree) {
00046 try {
00047 final Node source = cast(tree);
00048
00049 if (source.token == null)
00050 throw new SpecFileParserException("missing token type in the AST node; failed to parse correctly");
00051
00052 switch (source.token.getType()) {
00053 case SPECFILE:
00054 assert source.getChildCount() >= 2;
00055 String mod = asText(source.getChild(0));
00056 String name = asText(source.getChild(1));
00057 List<String> paramTypes = new LinkedList<String>();
00058 int idxStart = 2;
00059 if (source.getChild(2).getType() == PARAMS) {
00060 paramTypes = visitParams(cast(source.getChild(2)));
00061 idxStart = 3;
00062 }
00063 List<N> children = new LinkedList<N>();
00064 for (int i = idxStart; i < source.getChildCount(); i++)
00065 children.add(visit(source.getChild(i)));
00066 return visitSpecFile(mod, name, paramTypes, children);
00067 case SPECFIELD:
00068 assert source.getChildCount() > 0;
00069 return visitSpecField(source);
00070 case FUNCFIELD:
00071 assert source.getChildCount() > 0;
00072 return visitSpecField(source);
00073 case INVARIANT:
00074 assert source.getChildCount() > 0;
00075 return visitInvariant(source);
00076 }
00077
00078 throw new SpecFileParserException("unknown AST type");
00079
00080 } catch (SpecFileParserException e) {
00081
00082 if (e.token() == null) e.setToken(tree);
00083 throw e;
00084 } catch (RuntimeException e) {
00085
00086 throw new SpecFileParserException(e, tree);
00087 }
00088 }
00089
00090 protected abstract N visitSpecFile(String modifiers, String name, List<String> paramTypes, List<N> children);
00091 protected abstract N visitSpecField(Node source);
00092 protected abstract N visitFuncField(Node n);
00093 protected abstract N visitInvariant(Node source);
00094 protected List<String> visitParams(Node paramsNode) {
00095 List<String> params = new LinkedList<String>();
00096 for (int i = 0; i < paramsNode.getChildCount(); i++)
00097 params.add(asText(paramsNode.getChild(i)));
00098 return params;
00099 }
00100
00101 }