package freeboogie; import java.io.FileNotFoundException; import java.io.IOException; import java.io.PrintWriter; import java.util.logging.FileHandler; import java.util.logging.Level; import java.util.logging.Logger; import java.util.logging.SimpleFormatter; import org.antlr.runtime.ANTLRFileStream; import org.antlr.runtime.CommonTokenStream; import freeboogie.ast.*; import freeboogie.ast.utils.PrettyPrinter; import freeboogie.dumpers.FlowGraphDumper; import freeboogie.parser.FbLexer; import freeboogie.parser.FbParser; import freeboogie.tc.SymbolTable; import freeboogie.tc.TypeChecker; import freeboogie.tc.UsageToDefMap; import freeboogie.util.Closure; import freeboogie.util.ClosureR; import freeboogie.util.Err; /** * Used to print information in the symbol table. * (Java is incredibly verbose for this kind of stuff.) * * @author rgrig * @author reviewed by TODO * @param <U> the usage type * @param <D> the definition type */ class Printer<U extends Ast, D extends Ast> extends Closure<D> { private String name; private UsageToDefMap<U, D> map; private ClosureR<D, String> nameGetter; /** * Constructs a printer. * @param n the type of element that is printed * @param m the usage-def map * @param g a function that gets a user readable name from a definition */ public Printer(String n, UsageToDefMap<U, D> m, ClosureR<D, String> g) { name = n; map = m; nameGetter = g; } @Override public void go(D t) { System.out.println(name + " " + nameGetter.go(t)); System.out.println(" definition at " + t.loc()); System.out.print(" usages at"); for (U u : map.usages(t)) System.out.print(" " + u.loc()); System.out.println(); } } /** * The main entry point of the application. * * @author rgrig * @author reviewed by TODO */ public class Main { private static Logger log = Logger.getLogger("freeboogie"); /** * The main entry point of the application. * @param args the command line arguments */ public static void main(String[] args) { try { FileHandler logh = new FileHandler("freeboogie.log"); logh.setFormatter(new SimpleFormatter()); log.addHandler(logh); log.setLevel(Level.ALL); } catch (IOException e) { Err.warning("Can't create log file. Nevermind."); log.setLevel(Level.OFF); } // parse command line arguments Options opt = new Options(); opt.regBool("-pp", "pretty print"); opt.regBool("-pst", "print symbol table"); opt.regBool("-pfg", "print flow graphs"); //opt.regBool("-ppi", "print implementations per procedure"); opt.regInt("-v", 4, "verbosity level: 0, 1, 2, 3, 4"); opt.parse(args); Err.setVerbosity(opt.intVal("-v")); // process files one by one PrintWriter pw = new PrintWriter(System.out); PrettyPrinter pp = new PrettyPrinter(pw); FlowGraphDumper fgd = new FlowGraphDumper(); TypeChecker tc = new TypeChecker(); for (String file : opt.otherArgs()) { try { FbLexer lexer = new FbLexer(new ANTLRFileStream(file)); CommonTokenStream tokens = new CommonTokenStream(lexer); FbParser parser = new FbParser(tokens); parser.fileName = file; Declaration d = parser.program(); if (d == null) continue; // errors while parsing or empty file // pretty print? if (opt.boolVal("-pp")) { d.eval(pp); pw.flush(); } // typecheck tc.process(d); // print symbol table? if (opt.boolVal("-pst")) { SymbolTable st = tc.getST(); st.funcs.iterDef(new Printer<AtomFun, Function>("function", st.funcs, new ClosureR<Function, String>() { @Override public String go(Function p) { return p.getSig().getName(); }})); st.ids.iterDef(new Printer<AtomId, Declaration>("identifier", st.ids, new ClosureR<Declaration, String>() { @Override public String go(Declaration p) { if (p instanceof VariableDecl) return ((VariableDecl)p).getName(); else if (p instanceof ConstDecl) return ((ConstDecl)p).getId(); assert false; return null; // dumb compiler }})); st.procs.iterDef(new Printer<CallCmd, Procedure>("procedure", st.procs, new ClosureR<Procedure, String>() { @Override public String go(Procedure p) { return p.getSig().getName(); }})); st.types.iterDef(new Printer<UserType, TypeDecl>("type", st.types, new ClosureR<TypeDecl, String>() { @Override public String go(TypeDecl p) { return p.getName(); }})); } // print flow graph? if (opt.boolVal("-pfg")) fgd.process(d, tc); // print implementations per proc? } catch (FileNotFoundException e) { Err.error("I couldn't read from " + file + ". Nevermind."); } catch (Exception e) { Err.error("Unexpected error while processing " + file); } } } }