/** * Print maudified program to standard output. * * <p>Save it in kompiled cache under pgm.maude. */ public static Term processPgm( String content, String filename, Definition def, String startSymbol, Context context, GlobalSettings.ParserType whatParser) throws TransformerException { Stopwatch.sw.printIntermediate("Importing Files"); assert context.definedSorts.contains(startSymbol) : "The start symbol must be declared in the definition. Found: " + startSymbol; try { ASTNode out; if (whatParser == GlobalSettings.ParserType.GROUND) { org.kframework.parser.concrete.KParser.ImportTblGround( context.kompiled.getCanonicalPath() + "/ground/Concrete.tbl"); out = DefinitionLoader.parseCmdString(content, filename, startSymbol, context); out = out.accept(new RemoveBrackets(context)); out = out.accept(new AddEmptyLists(context)); out = out.accept(new RemoveSyntacticCasts(context)); out = out.accept(new FlattenSyntax(context)); } else if (whatParser == GlobalSettings.ParserType.RULES) { org.kframework.parser.concrete.KParser.ImportTbl( context.kompiled.getCanonicalPath() + "/def/Concrete.tbl"); out = DefinitionLoader.parsePattern(content, filename, startSymbol, context); out = out.accept(new RemoveBrackets(context)); out = out.accept(new AddEmptyLists(context)); out = out.accept(new RemoveSyntacticCasts(context)); try { out = new RuleCompilerSteps(def, context).compile(new Rule((Sentence) out), null); } catch (CompilerStepDone e) { out = (ASTNode) e.getResult(); } out = ((Rule) out).getBody(); } else if (whatParser == GlobalSettings.ParserType.BINARY) { out = (org.kframework.kil.Cell) BinaryLoader.load(filename); } else { out = loadPgmAst(content, filename, startSymbol, context); out = out.accept(new ResolveVariableAttribute(context)); } Stopwatch.sw.printIntermediate("Parsing Program"); return (Term) out; } catch (IOException e) { String msg = "Cannot parse program: " + e.getLocalizedMessage(); throw new TransformerException( new KException( ExceptionType.ERROR, KExceptionGroup.CRITICAL, msg, filename, "File system.")); } }
/** @param cmds represents the arguments/options given to krun command.. */ public static void execute_Krun(String cmds[]) { Context context = new Context(); K.init(context); CommandlineOptions cmd_options = new CommandlineOptions(); CommandLine cmd = cmd_options.parse(cmds); if (cmd == null) { printKRunUsageS(cmd_options); /* printKRunUsageE(cmd_options); */ /* TODO: Switch to this when the user has tried to use an experimental option. */ System.exit(1); } if (!cmd.hasOption("debug-info")) { Runtime.getRuntime() .addShutdownHook( new Thread() { public void run() { try { deleteDirectory(new File(K.krunTempDir)); } catch (IOException e) { e.printStackTrace(); } } }); } // set verbose if (cmd.hasOption("verbose")) { GlobalSettings.verbose = true; } // set fast-kast if (cmd.hasOption("fast-kast")) { GlobalSettings.fastKast = !GlobalSettings.fastKast; } if (GlobalSettings.verbose) sw.printIntermediate("Deleting temporary krun directory"); try { // Parse the program arguments if (cmd.hasOption("search") || cmd.hasOption("search-final") || cmd.hasOption("search-all") || cmd.hasOption("search-one-step") || cmd.hasOption("search-one-or-more-steps")) { K.maude_cmd = "search"; K.io = false; K.do_search = true; if (cmd.hasOption("search") && cmd.hasOption("depth")) { K.searchType = SearchType.STAR; } } if (cmd.hasOption("search-final")) { K.searchType = SearchType.FINAL; } if (cmd.hasOption("search-all")) { K.searchType = SearchType.STAR; } if (cmd.hasOption("search-one-step")) { K.searchType = SearchType.ONE; } if (cmd.hasOption("search-one-or-more-steps")) { K.searchType = SearchType.PLUS; } if (cmd.hasOption("help")) { K.help = true; } if (cmd.hasOption("help-experimental")) { K.helpExperimental = true; } if (cmd.hasOption("version")) { K.version = true; } // CLEANUP_OPTIONS: The option --directory was added, replacing --k-definition and // --compiled-def. if (cmd.hasOption("directory")) { K.directory = new File(cmd.getOptionValue("directory")).getCanonicalPath(); org.kframework.utils.Error.checkIfInputDirectory(K.directory); } if (cmd.hasOption("main-module")) { K.main_module = cmd.getOptionValue("main-module"); } if (cmd.hasOption("syntax-module")) { K.syntax_module = cmd.getOptionValue("syntax-module"); } if (cmd.hasOption("parser")) { K.customParser = cmd.getOptionValue("parser"); } if (cmd.hasOption("term")) { K.term = cmd.getOptionValue("term"); } if (cmd.hasOption("io")) { String v = cmd.getOptionValue("io"); if (v.equals("on")) K.io = true; else if (v.equals("off")) K.io = false; else Error.report("Unrecognized option: --io " + v + "\nUsage: krun --io [on|off]"); } if (cmd.hasOption("statistics")) { String v = cmd.getOptionValue("statistics"); if (v.equals("on")) K.statistics = true; else if (v.equals("off")) K.statistics = false; else Error.report( "Unrecognized option: --statistics " + v + "\nUsage: krun --statistics [on|off]"); } if (cmd.hasOption("color")) { String v = cmd.getOptionValue("color"); if (v.equals("on")) K.color = ColorSetting.ON; else if (v.equals("off")) K.color = ColorSetting.OFF; else if (v.equals("extended")) K.color = ColorSetting.EXTENDED; else Error.report( "Unrecognized option: --color " + v + "\nUsage: krun --color [on|off|extended]"); } if (cmd.hasOption("terminal-color")) { String v = cmd.getOptionValue("terminal-color"); Color terminalColor = ColorUtil.getColorByName(v); if (terminalColor != null) { K.terminalColor = terminalColor; } else { Error.report("Invalid terminal color: " + v); } } if (cmd.hasOption("parens")) { String v = cmd.getOptionValue("parens"); if (v.equals("greedy")) { K.parens = true; } else if (v.equals("smart")) { K.parens = false; } else { Error.report( "Unrecognized option: --parens " + v + "\nUsage: krun --parens [greedy|smart]"); } } // testcase generation if (cmd.hasOption("generate-tests")) { K.do_testgen = true; K.io = false; K.do_search = true; } if (cmd.hasOption("maude-cmd")) { K.maude_cmd = cmd.getOptionValue("maude-cmd"); } /* * if (cmd.hasOption("xsearch-pattern")) { K.maude_cmd = "search"; * K.do_search = true; K.xsearch_pattern = * cmd.getOptionValue("xsearch-pattern"); // * System.out.println("xsearch-pattern:" + K.xsearch_pattern); } */ if (cmd.hasOption("pattern")) { K.pattern = cmd.getOptionValue("pattern"); } if (cmd.hasOption("bound")) { K.bound = cmd.getOptionValue("bound"); } if (cmd.hasOption("depth")) { K.depth = cmd.getOptionValue("depth"); } if (cmd.hasOption("graph")) { K.showSearchGraph = true; } if (cmd.hasOption("output-mode")) { K.output_mode = cmd.getOptionValue("output-mode"); } if (cmd.hasOption("log-io")) { String v = cmd.getOptionValue("log-io"); if (v.equals("on")) K.log_io = true; else if (v.equals("off")) K.log_io = false; else Error.report("Unrecognized option: --log-io " + v + "\nUsage: krun --log-io [on|off]"); } if (cmd.hasOption("debug")) { K.debug = true; } if (cmd.hasOption("debug-gui")) { K.guidebug = true; } if (cmd.hasOption("trace")) { K.trace = true; } if (cmd.hasOption("profile")) { K.profile = true; } if (cmd.hasOption("ltlmc")) { K.model_checking = cmd.getOptionValue("ltlmc"); } if (cmd.hasOption("prove")) { K.prove = cmd.getOptionValue("prove"); } if (cmd.hasOption("smt")) { K.smt = cmd.getOptionValue("smt"); } if (cmd.hasOption("output")) { if (!cmd.hasOption("color")) { K.color = ColorSetting.OFF; } K.output = new File(cmd.getOptionValue("output")).getCanonicalPath(); } if (cmd.hasOption("c")) { if (K.term != null) { Error.report("You cannot specify both the term and the configuration\nvariables."); } K.configuration_variables = cmd.getOptionProperties("c"); String parser = null; for (Option opt : cmd.getOptions()) { if (opt.equals(cmd_options.getOptions().getOption("c")) && parser != null) { K.cfg_parsers.setProperty(opt.getValue(0), parser); } if (opt.equals(cmd_options.getOptions().getOption("cfg-parser"))) { parser = opt.getValue(); } } } if (cmd.hasOption("backend")) { K.backend = cmd.getOptionValue("backend"); } // printing the output according to the given options if (K.help) { printKRunUsageS(cmd_options); System.exit(0); } if (K.helpExperimental) { printKRunUsageE(cmd_options); System.exit(0); } if (K.version) { String msg = FileUtil.getFileContent(KPaths.getKBase(false) + KPaths.VERSION_FILE); System.out.println(msg); System.exit(0); } String[] remainingArguments = null; if (cmd_options.getCommandLine().getOptions().length > 0) { remainingArguments = cmd.getArgs(); } else { remainingArguments = cmds; } String programArg = new String(); if (remainingArguments.length > 0) { programArg = remainingArguments[0]; K.pgm = programArg; } String lang = null; if (K.pgm != null) { File pgmFile = new File(K.pgm); if (pgmFile.exists()) { lang = FileUtil.getExtension(K.pgm, ".", K.fileSeparator); } } if (GlobalSettings.verbose) sw.printIntermediate("Parsing command line options"); /* CLEANUP_OPTIONS */ if (!cmd.hasOption("directory")) { K.directory = new File(K.userdir).getCanonicalPath(); } { // search for the definition File[] dirs = new File(K.directory) .listFiles( new FilenameFilter() { @Override public boolean accept(File current, String name) { return new File(current, name).isDirectory(); } }); K.compiled_def = null; for (int i = 0; i < dirs.length; i++) { if (dirs[i].getAbsolutePath().endsWith("-kompiled")) { if (K.compiled_def != null) { String msg = "Multiple compiled definitions found."; GlobalSettings.kem.register( new KException( ExceptionType.ERROR, KExceptionGroup.CRITICAL, msg, "command line", new File(".").getAbsolutePath())); } else { K.compiled_def = dirs[i].getAbsolutePath(); } } } if (K.compiled_def == null) { String msg = "Could not find a compiled definition."; GlobalSettings.kem.register( new KException( ExceptionType.ERROR, KExceptionGroup.CRITICAL, msg, "command line", new File(".").getAbsolutePath())); } } if (K.compiled_def == null) { Error.report( "Could not find a compiled K definition. Please ensure that\neither a compiled K definition exists in the current directory with its default\nname, or that --directory has been specified."); } File compiledFile = new File(K.compiled_def); if (!compiledFile.exists()) { Error.report( "\nCould not find compiled definition: " + K.compiled_def + "\nPlease compile the definition by using `kompile'."); } context.dotk = new File(new File(K.compiled_def).getParent() + File.separator + ".k"); if (!context.dotk.exists()) { context.dotk.mkdirs(); } context.kompiled = new File(K.compiled_def); K.kdir = context.dotk.getCanonicalPath(); K.setKDir(); /* * System.out.println("K.k_definition=" + K.k_definition); * System.out.println("K.syntax_module=" + K.syntax_module); * System.out.println("K.main_module=" + K.main_module); * System.out.println("K.compiled_def=" + K.compiled_def); */ if (GlobalSettings.verbose) sw.printIntermediate("Checking compiled definition"); // in KAST variable we obtain the output from running kast process // on a program defined in K Term KAST = null; RunProcess rp = new RunProcess(); if (!context.initialized) { String path = K.compiled_def + "/defx-" + K.backend + ".bin"; Definition javaDef; if (new File(path).exists()) { javaDef = (Definition) BinaryLoader.load(K.compiled_def + "/defx-" + K.backend + ".bin"); } else { GlobalSettings.kem.register( new KException( ExceptionType.ERROR, KExceptionGroup.CRITICAL, "Could not find compiled definition for backend '" + K.backend + "'.\n" + "Please ensure this backend has been kompiled.")); throw new AssertionError("unreachable"); } if (GlobalSettings.verbose) sw.printIntermediate("Reading definition from binary"); // This is essential for generating maude javaDef = new FlattenModules(context).compile(javaDef, null); if (GlobalSettings.verbose) sw.printIntermediate("Flattening modules"); try { javaDef = (Definition) javaDef.accept(new AddTopCellConfig(context)); } catch (TransformerException e) { e.report(); } if (GlobalSettings.verbose) sw.printIntermediate("Adding top cell to configuration"); javaDef.preprocess(context); if (GlobalSettings.verbose) sw.printIntermediate("Preprocessing definition"); K.definition = javaDef; if (GlobalSettings.verbose) sw.printIntermediate("Importing tables"); K.kompiled_cfg = (org.kframework.kil.Configuration) BinaryLoader.load(K.compiled_def + "/configuration.bin"); CommandLine compileOptions = (CommandLine) BinaryLoader.load(K.compiled_def + "/compile-options.bin"); if (compileOptions.hasOption("sortCells")) GlobalSettings.sortedCells = true; if (GlobalSettings.verbose) sw.printIntermediate("Reading configuration from binary"); } if (!cmd.hasOption("main-module")) { K.main_module = K.definition.getMainModule(); } if (!cmd.hasOption("syntax-module")) { K.syntax_module = K.definition.getMainSyntaxModule(); } if (GlobalSettings.verbose) sw.printIntermediate("Resolving main and syntax modules"); if (K.pgm != null) { KAST = rp.runParserOrDie(K.getProgramParser(), K.pgm, false, null, context); } else { KAST = null; } if (GlobalSettings.verbose) sw.printIntermediate("Kast process"); if (K.term != null) { if (K.parser.equals("kast") && !cmd.hasOption("parser")) { if (K.backend.equals("java")) { K.parser = "kast -ruleParser"; } else { K.parser = "kast -groundParser"; } } } GlobalSettings.kem.print(); if (!K.debug && !K.guidebug) { normalExecution(KAST, lang, rp, cmd_options, context); } else { if (K.do_search) { Error.report( "Cannot specify --search with --debug. In order to search\nnside the debugger, use the step-all command."); } if (K.guidebug) guiDebugExecution(KAST, lang, null, context); else debugExecution(KAST, lang, null, context); } } catch (IOException e) { e.printStackTrace(); System.exit(1); } }
// execute krun in debug mode (i.e. step by step execution) // isSwitch variable is true if we enter in debug execution from normal // execution (we use the search command with --graph option) @SuppressWarnings("unchecked") public static void debugExecution( Term kast, String lang, KRunResult<SearchResults> state, org.kframework.kil.loader.Context context) { try { // adding autocompletion and history feature to the stepper internal // commandline by using the JLine library ConsoleReader reader = new ConsoleReader(); reader.setBellEnabled(false); List<Completor> argCompletor = new LinkedList<Completor>(); argCompletor.add( new SimpleCompletor( new String[] { "help", "abort", "resume", "step", "step-all", "select", "show-search-graph", "show-node", "show-edge", "save", "load", "read" })); argCompletor.add(new FileNameCompletor()); List<Completor> completors = new LinkedList<Completor>(); completors.add(new ArgumentCompletor(argCompletor)); reader.addCompletor(new MultiCompletor(completors)); new File(K.compiled_def + K.fileSeparator + "main.maude").getCanonicalPath(); RunProcess rp = new RunProcess(); KRun krun = obtainKRun(context); krun.setBackendOption("io", false); KRunDebugger debugger; try { if (state == null) { Term t = makeConfiguration(kast, "", rp, (K.term != null), context); debugger = krun.debug(t); System.out.println("After running one step of execution the result is:"); AnsiConsole.out.println(debugger.printState(debugger.getCurrentState())); } else { debugger = krun.debug(state.getResult().getGraph()); } } catch (UnsupportedBackendOptionException e) { Error.report("Backend \"" + K.backend + "\" does not support option " + e.getMessage()); throw e; // unreachable } while (true) { System.out.println(); String input = reader.readLine("Command > "); if (input == null) { // probably pressed ^D System.out.println(); System.exit(0); } // construct the right command line input when we specify the // "step" option with an argument (i.e. step=3) input = input.trim(); String[] tokens = input.split(" "); // store the tokens that are not a blank space List<String> items = new ArrayList<String>(); for (int i = 0; i < tokens.length; i++) { if ((!(tokens[i].equals(" ")) && (!tokens[i].equals("")))) { items.add(tokens[i]); } } StringBuilder aux = new StringBuilder(); // excepting the case of a command like: help if (items.size() > 1) { for (int i = 0; i < items.size(); i++) { if (i > 0) { aux.append("="); aux.append(items.get(i)); } else if (i == 0) { aux.append(items.get(i)); } } input = aux.toString(); } // apply trim to remove possible blank spaces from the inserted // command String[] cmds = new String[] {"--" + input}; CommandlineOptions cmd_options = new CommandlineOptions(); CommandLine cmd = cmd_options.parse(cmds); // when an error occurred during parsing the commandline // continue the execution of the stepper if (cmd == null) { continue; } else { if (cmd.hasOption("help")) { printDebugUsage(cmd_options); } if (cmd.hasOption("abort")) { System.exit(0); } if (cmd.hasOption("resume")) { try { debugger.resume(); AnsiConsole.out.println(debugger.printState(debugger.getCurrentState())); } catch (IllegalStateException e) { Error.silentReport( "Wrong command: If you previously used the step-all command you must" + K.lineSeparator + "seletc first a solution with step command before executing steps of rewrites!"); } } // one step execution (by default) or more if you specify an // argument if (cmd.hasOption("step")) { // by default execute only one step at a time String arg = new String("1"); String[] remainingArguments = null; remainingArguments = cmd.getArgs(); if (remainingArguments.length > 0) { arg = remainingArguments[0]; } try { int steps = Integer.parseInt(arg); debugger.step(steps); AnsiConsole.out.println(debugger.printState(debugger.getCurrentState())); } catch (NumberFormatException e) { Error.silentReport("Argument to step must be an integer."); } catch (IllegalStateException e) { Error.silentReport( "Wrong command: If you previously used the step-all command you must" + K.lineSeparator + "select first a solution with step command before executing steps of rewrites!"); } } if (cmd.hasOption("step-all")) { // by default compute all successors in one transition String arg = new String("1"); String[] remainingArguments = null; remainingArguments = cmd.getArgs(); if (remainingArguments.length > 0) { arg = remainingArguments[0]; } try { int steps = Integer.parseInt(arg); SearchResults states = debugger.stepAll(steps); AnsiConsole.out.println(states); } catch (NumberFormatException e) { Error.silentReport("Argument to step-all must be an integer."); } catch (IllegalStateException e) { Error.silentReport( "Wrong command: If you previously used the step-all command you must" + K.lineSeparator + "select first a solution with step command before executing steps of rewrites!"); } } // "select n7" or "select 3" are both valid commands if (cmd.hasOption("select")) { String arg = new String(); arg = cmd.getOptionValue("select").trim(); try { int stateNum = Integer.parseInt(arg); debugger.setCurrentState(stateNum); AnsiConsole.out.println(debugger.printState(debugger.getCurrentState())); } catch (NumberFormatException e) { Error.silentReport("Argument to select must bean integer."); } catch (IllegalArgumentException e) { System.out.println( "A node with the specified state number could not be found in the" + K.lineSeparator + "search graph"); } } if (cmd.hasOption("show-search-graph")) { System.out.println(K.lineSeparator + "The search graph is:" + K.lineSeparator); System.out.println(debugger.getGraph()); } if (cmd.hasOption("show-node")) { String nodeId = cmd.getOptionValue("show-node").trim(); try { int stateNum = Integer.parseInt(nodeId); AnsiConsole.out.println(debugger.printState(stateNum)); } catch (NumberFormatException e) { Error.silentReport("Argument to select node to show must be an integer."); } catch (IllegalArgumentException e) { System.out.println( "A node with the specified state number could not be found in the" + K.lineSeparator + "search graph"); } } if (cmd.hasOption("show-edge")) { String[] vals = cmd.getOptionValues("show-edge"); vals = vals[0].split("=", 2); try { int state1 = Integer.parseInt(vals[0].trim()); int state2 = Integer.parseInt(vals[1].trim()); AnsiConsole.out.println(debugger.printEdge(state1, state2)); } catch (ArrayIndexOutOfBoundsException e) { Error.silentReport("Must specify two nodes with an edge between them."); } catch (NumberFormatException e) { Error.silentReport("Arguments to select edge to show must be integers."); } catch (IllegalArgumentException e) { System.out.println( "An edge with the specified endpoints could not be found in the" + K.lineSeparator + "search graph"); } } DirectedGraph<KRunState, Transition> savedGraph = null; if (cmd.hasOption("save")) { BinaryLoader.save( new File(cmd.getOptionValue("save")).getCanonicalPath(), debugger.getGraph()); System.out.println("File successfully saved."); } if (cmd.hasOption("load")) { savedGraph = (DirectedGraph<KRunState, Transition>) BinaryLoader.load(cmd.getOptionValue("load")); krun = new MaudeKRun(context); debugger = krun.debug(savedGraph); debugger.setCurrentState(1); System.out.println("File successfully loaded."); } if (cmd.hasOption("read")) { try { debugger.readFromStdin( StringBuiltin.valueOf("\"" + cmd.getOptionValue("read") + "\"").stringValue()); AnsiConsole.out.println(debugger.printState(debugger.getCurrentState())); } catch (IllegalStateException e) { Error.silentReport(e.getMessage()); } } } } } catch (Exception e) { e.printStackTrace(); System.exit(1); } }