package de.skuzzle.polly.console; import java.io.BufferedReader; import java.io.File; import java.io.FileFilter; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintStream; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.List; import de.skuzzle.polly.core.parser.Evaluator; import de.skuzzle.polly.core.parser.Position; import de.skuzzle.polly.core.parser.ast.declarations.DeclarationReader; import de.skuzzle.polly.core.parser.ast.declarations.Namespace; import de.skuzzle.polly.core.parser.ast.visitor.ASTTraversalException; import de.skuzzle.polly.core.parser.ast.visitor.ExpASTVisualizer; import de.skuzzle.polly.core.parser.problems.MultipleProblemReporter; import de.skuzzle.polly.core.parser.problems.ProblemReporter; import de.skuzzle.polly.core.parser.problems.ProblemReporter.Problem; import de.skuzzle.polly.process.KillingProcessWatcher; import de.skuzzle.polly.process.ProcessExecutor; import de.skuzzle.polly.tools.strings.StringUtils; public class PPC { private final static String DOT_PATH = "C:\\Program Files (x86)\\Graphviz 2.28\\bin\\dot.exe"; private final static File DECLARATION_FOLDER = new File("decls"); private final static FileFilter DECLARATION_FILTER = new FileFilter() { @Override public boolean accept(File pathname) { return pathname.getName().toLowerCase().endsWith(".decl"); } }; private final static Comparator<Problem> PROBLEM_COMP = new Comparator<ProblemReporter.Problem>() { @Override public int compare(Problem o1, Problem o2) { int r = o1.getType() - o2.getType(); if (r == 0) { r = o1.getPosition().compareTo(o2.getPosition()); } return r; } }; private static void readDeclarations() throws IOException { for (final File file : DECLARATION_FOLDER.listFiles(DECLARATION_FILTER)) { DeclarationReader dr = null; try { final String nsName = file.getName().substring( 0, file.getName().length() - 5); Namespace ns = Namespace.forName(nsName); dr = new DeclarationReader(file, "ISO-8859-1", ns); dr.readAll(); } catch (IOException e) { e.printStackTrace(); } finally { if (dr != null) { dr.close(); } } } } public static void main(String[] args) throws IOException, ASTTraversalException { final File declFolder = new File("decls"); if (!declFolder.exists()) { declFolder.mkdirs(); } Namespace.setDeclarationFolder(declFolder); readDeclarations(); final BufferedReader r = new BufferedReader(new InputStreamReader(System.in)); String nsName = "default"; System.out.println("Welcome to PPC - Polly Parser Console"); System.out.println("Just enter any valid polly expression, or type :q to exit."); System.out.println("Type :ns <name> to switch namespaces."); System.out.println(); while (true) { Namespace ns = Namespace.forName(nsName); System.out.print(nsName + " > "); final String cmd = r.readLine(); if (cmd == null) { continue; } if (cmd.equals(":q")) { return; } else if (cmd.startsWith(":ns")) { final String[] parts = cmd.split(" "); if (parts.length != 2) { System.out.println("Invalid parameters for ':ns'"); } else { nsName = parts[1]; } continue; } else if (cmd.equals(":cns")) { //System.out.println(); continue; } else if (cmd.equals(":vns")) { System.out.println("Namespace: " + nsName); System.out.println(ns.toString()); continue; } final MultipleProblemReporter mpr = new MultipleProblemReporter(); final Evaluator eval = new Evaluator(":result \">\" " + cmd, "ISO-8859-1", mpr); try { eval.evaluate(ns, ns); } catch (Exception ad) { ad.printStackTrace(); } if (eval.errorOccurred()) { System.out.println(" " + cmd); for (String indi : Position.indicatorStrings(mpr.problemPositions(), -12)) { System.out.println(" " + indi); } formatProblems(mpr.getProblems(), -12); } else { System.out.println(eval.getRoot().toString()); } if (eval.getRoot() != null){ final ExpASTVisualizer av = new ExpASTVisualizer(); av.visualize(eval.getRoot(), new PrintStream("lastAst.dot"), ns); ProcessExecutor pe = ProcessExecutor.getOsInstance(false); pe.addCommand(DOT_PATH); pe.addCommandsFromString("-Tpdf -o lastAst.pdf"); pe.addCommand("lastAST.dot"); pe.setProcessWatcher(new KillingProcessWatcher(10000, true)); pe.start(); } } } private static void formatProblems(Collection<Problem> problems, int offset) { final String[] types = new String[4]; types[ProblemReporter.LEXICAL] = "Lexical"; types[ProblemReporter.SYNTACTICAL] = "Syntactical"; types[ProblemReporter.SEMATICAL] = "Semantical"; types[ProblemReporter.RUNTIME] = "Runtime"; int longestType = "Syntactical".length(); final int longestMsg = problems.stream() .map(Problem::getMessage) .mapToInt(String::length) .max().getAsInt(); StringBuilder header = new StringBuilder(); header.append("Type"); StringUtils.padSpaces(longestType, header.length(), header); header.append(" | Message"); StringUtils.padSpaces(6 + longestType + longestMsg, header.length(), header); header.append(" | Position"); System.out.println(header.toString()); for (int i = 0; i < header.length(); ++i) { System.out.print("-"); } System.out.println(); List<Problem> probs = new ArrayList<ProblemReporter.Problem>(problems); Collections.sort(probs, PROBLEM_COMP); for (final Problem problem : probs) { final StringBuilder b = new StringBuilder(); b.append(types[problem.getType()]); StringUtils.padSpaces(longestType, b.length(), b); b.append(" | "); b.append(problem.getMessage()); StringUtils.padSpaces(6 + longestType + longestMsg, b.length(), b); b.append(" | "); b.append(problem.getPosition().offset(offset).toString()); System.out.println(b.toString()); } } }