From: droy Date: Mon, 7 Jul 2003 16:13:33 +0000 (+0000) Subject: MCC files X-Git-Url: http://plrg.eecs.uci.edu/git/?p=repair.git;a=commitdiff_plain;h=6eb0d44a90242a5a01db9b8c5c0acebf2bd42347 MCC files --- diff --git a/Repair/RepairCompiler/MCC/CDL.cup b/Repair/RepairCompiler/MCC/CDL.cup new file mode 100755 index 0000000..37a93bc --- /dev/null +++ b/Repair/RepairCompiler/MCC/CDL.cup @@ -0,0 +1,589 @@ +package MCC; +import MCC.IR.ParseNode; +import MCC.IR.ParseNodeVector; +import java.util.*; + +action code {: + + public static boolean errors; + public static boolean debug; + + // debugMessage: writes debug production message only if debug = true + + void debugMessage (String production) { + if (debug) { + System.out.println("Applying production: " + production); + } + } + + String unescape (String str) { + StringBuffer sb = new StringBuffer(); + int i; + // Note that we skip the first and last characters (they're "'s) + for (i = 1; i < str.length() - 1; i++) { + if (str.charAt(i) == '\\') { + i++; + switch (str.charAt(i)) { + case '\"': + sb.append('\"'); + break; + case '\'': + sb.append('\''); + break; + case '\\': + sb.append('\\'); + break; + case 't': + sb.append('\t'); + break; + case 'n': + sb.append('\n'); + break; + default: + System.err.print("Error in string literal: "); + System.err.println(str.charAt(i)); + System.err.println("Aborting..."); + break; + } + } else { + sb.append(str.charAt(i)); + } + } + return sb.toString(); + } +:} + +init with {: :} + +parser code {: + + public void syntax_error (java_cup.runtime.Symbol current) { + + CUP$CDLParser$actions.errors = true; + Symbol symbol = (Symbol) current; + report_error("CDL: Syntax error at line " + (symbol.line + 1) + + ", column " + LineCount.getColumn(symbol.left) + ": " + current.value, current); + } + + public void report_fatal_error (String message, Object info) { + + done_parsing(); + report_error(message, info); + CUP$CDLParser$actions.errors = true; + } + + public int curPos () { + return cur_token.left; + } + + public int curLine (int back) { + Stack st = new Stack(); + int i; + + for (i = 0; i < back; i++) { + st.push(stack.pop()); + } + + java_cup.runtime.Symbol s; + s = (java_cup.runtime.Symbol) st.peek(); + + for (i = 0; i < back; i++) { + stack.push(st.pop()); + } + + return LineCount.getLine(s.left); + } + +:} + +// TERMINALS ///////////////////////////////////////////////////////////// + + terminal BAD; + + terminal String ID; + terminal String DECIMAL; + terminal String CHAR; + terminal String STRING; + + terminal OPENBRACE; + terminal CLOSEBRACE; + terminal OPENPAREN; + terminal CLOSEPAREN; + terminal OPENBRACKET; + terminal CLOSEBRACKET; + + terminal ADD; + terminal SUB; + terminal MULT; + terminal DIV; + + terminal NOT; + terminal LT; + terminal GT; + terminal LE; + terminal GE; + terminal EQ; + terminal NE; + + + terminal FORALL; + terminal IN; + terminal INTEST; + + terminal COMMA; + terminal SIZEOF; + + terminal DOT; + terminal DOTINV; + + terminal AND; + terminal OR; + + terminal LITERAL; + + terminal IMPLIES; + terminal TRUE; + terminal ISVALID; + terminal FOR; + terminal TO; + terminal CAST; + + terminal PARAM; + terminal STRUCTURE; + terminal RESERVED; + terminal BIT; + terminal BYTE; + terminal SHORT; + + terminal LABEL; + terminal INT; + terminal SUBTYPE; + terminal OF; + + terminal SEMICOLON; + terminal COLON; + + terminal SET; + terminal ARROW; + terminal MANY; + terminal BAR; + + terminal PARTITION; + terminal ELEMENT; + terminal DELAY; + terminal STATIC; + + terminal NULL; + terminal CRASH; + +// NON-TERMINALS ///////////////////////////////////////////////////////// + +/* + TYPE NAME +------------------------------------------------------------------------*/ +nonterminal ParseNode constraints; +nonterminal ParseNode constraint; +nonterminal ParseNode optcrash; +nonterminal ParseNode quantifiers; +nonterminal ParseNode quantifier; +nonterminal ParseNode set; +nonterminal ParseNode listofliterals; +nonterminal ParseNode literal; +nonterminal ParseNode body; +nonterminal ParseNode predicate; +nonterminal ParseNode setexpr; +//nonterminal ParseNode limitedcompare; +nonterminal ParseNode compare; +nonterminal ParseNode expr; +nonterminal ParseNode operator; +nonterminal ParseNode relations; +//nonterminal ParseNode type; + +precedence left OR; +precedence left AND; +precedence right EQ, NE; +precedence right LT, LE, GE, GT; +precedence left ADD, SUB; +precedence left MULT, DIV; +precedence left NOT; +precedence left DOT, DOTINV; + +// PRODUCTION RULES ///////////////////////////////////////////////////// + +constraints ::= + constraints:constraints constraint:constraint + {: + debugMessage(PRODSTRING); + constraints.addChild(constraint); + RESULT = constraints; + :} + | constraint:constraint + {: + debugMessage(PRODSTRING); + ParseNode constraints = new ParseNode("constraints", parser.curLine(1)); + constraints.addChild(constraint); + RESULT = constraints; + :} + ; + +constraint ::= + optcrash:crash OPENBRACKET quantifiers:quantifiers CLOSEBRACKET COMMA body:body SEMICOLON + {: + debugMessage(PRODSTRING); + ParseNode constraint = new ParseNode("constraint", parser.curLine(7)); + if (crash != null) { + constraint.addChild(crash); + } + if (quantifiers != null) { + constraint.addChild(quantifiers); + } + constraint.addChild(body); + RESULT = constraint; + :} + ; + +optcrash ::= + CRASH + {: + debugMessage(PRODSTRING); + RESULT = new ParseNode("crash", parser.curLine(1)); + :} + | /* nothing */ + {: + debugMessage(PRODSTRING); + RESULT = null; + :} + ; + +quantifiers ::= + quantifiers:quantifiers COMMA quantifier:quantifier + {: + debugMessage(PRODSTRING); + quantifiers.addChild(quantifier); + RESULT = quantifiers; + :} + + | quantifier:quantifier + {: + debugMessage(PRODSTRING); + ParseNode quantifiers = new ParseNode("quantifiers", parser.curLine(1)); + quantifiers.addChild(quantifier); + RESULT = quantifiers; + :} + + | + {: + debugMessage(PRODSTRING); + RESULT = null; + :} + ; + +quantifier ::= + FORALL ID:var IN set:set + {: + debugMessage(PRODSTRING); + ParseNode q = new ParseNode("quantifier", parser.curLine(4)); + q.addChild("forall", parser.curLine(4)); + q.addChild("var", parser.curLine(3)).addChild(var); + q.addChild(set); + RESULT = q; + :} + ; + +set ::= + ID:setname + {: + debugMessage(PRODSTRING); + ParseNode set = new ParseNode("set", parser.curLine(1)); + set.addChild("name").addChild(setname); + RESULT = set; + :} + | OPENBRACE listofliterals:list CLOSEBRACE + {: + debugMessage(PRODSTRING); + ParseNode set = new ParseNode("set", parser.curLine(3)); + set.addChild(list); + RESULT = set; + :} + ; + + +listofliterals ::= + listofliterals:list COMMA literal:literal + {: + debugMessage(PRODSTRING); + list.addChild(literal); + RESULT = list; + :} + | literal:literal + {: + debugMessage(PRODSTRING); + ParseNode list = new ParseNode("listofliterals", parser.curLine(1)); + list.addChild(literal); + RESULT = list; + :} + ; + +body ::= + body:body1 AND body:body2 + {: + debugMessage(PRODSTRING); + ParseNode body = new ParseNode("body", parser.curLine(3)); + body.addChild("and").addChild("left", parser.curLine(3)).addChild(body1); + body.getChild("and").addChild("right", parser.curLine(1)).addChild(body2); + RESULT = body; + :} + | body:body1 OR body:body2 + {: + debugMessage(PRODSTRING); + ParseNode body = new ParseNode("body", parser.curLine(3)); + body.addChild("or").addChild("left", parser.curLine(3)).addChild(body1); + body.getChild("or").addChild("right", parser.curLine(1)).addChild(body2); + RESULT = body; + :} + | NOT body:body1 + {: + debugMessage(PRODSTRING); + ParseNode body = new ParseNode("body", parser.curLine(2)); + body.addChild("not").addChild(body1); + RESULT = body; + :} + | OPENPAREN body:body CLOSEPAREN + {: + debugMessage(PRODSTRING); + RESULT = body; + :} + | predicate:predicate + {: + debugMessage(PRODSTRING); + ParseNode body = new ParseNode("body", parser.curLine(1)); + body.addChild(predicate); + RESULT = body; + :} + ; + +predicate ::= + + ID:var IN setexpr:setexpr + {: + debugMessage(PRODSTRING); + ParseNode inclusion = (new ParseNode("predicate", parser.curLine(3))).addChild("inclusion"); + inclusion.addChild("quantifiervar", parser.curLine(3)).addChild(var); + inclusion.addChild(setexpr); + RESULT = inclusion.getRoot(); + :} + + | SIZEOF OPENPAREN setexpr:setexpr CLOSEPAREN + {: + ParseNode expr = new ParseNode("expr", parser.curLine(4)); + expr.addChild("sizeof").addChild(setexpr); + RESULT = expr; + :} + + | + {: + debugMessage(PRODSTRING); + ParseNode comparison = (new ParseNode("predicate", parser.curLine(3))).addChild("comparison"); + comparison.addChild("compare", parser.curLine(2)).addChild(compare); + comparison.addChild("left", parser.curLine(3)).addChild(leftexpr); + comparison.addChild("right", parser.curLine(1)).addChild(rightexpr); + RESULT = comparison.getRoot(); + :} + ; + +setexpr ::= + ID:setname + {: + debugMessage(PRODSTRING); + ParseNode set = new ParseNode("setexpr", parser.curLine(1)); + set.addChild("set").addChild(setname); + RESULT = set; + :} + | ID:var DOT ID:relation + {: + debugMessage(PRODSTRING); + ParseNode set = new ParseNode("setexpr", parser.curLine(3)); + set.addChild("dot").addChild("quantifiervar", parser.curLine(3)).addChild(var); + set.getChild("dot").addChild("relation", parser.curLine(1)).addChild(relation); + RESULT = set; + :} + | ID:var DOTINV ID:relation + {: + debugMessage(PRODSTRING); + ParseNode set = new ParseNode("setexpr", parser.curLine(3)); + set.addChild("dotinv").addChild("quantifiervar", parser.curLine(3)).addChild(var); + set.getChild("dotinv").addChild("relation", parser.curLine(1)).addChild(relation); + RESULT = set; + :} + ; + + + +relations ::= + + relations:relations DOT ID:relation + {: + debugMessage(PRODSTRING); + relations.insertChild(relation); + RESULT = relations; + :} + + | relations:relations DOTINV ID:relation + {: + debugMessage(PRODSTRING); + relations.insertChild(relation).addChild("inv"); + RESULT = relations; + :} + + | ID:relation + {: + debugMessage(PRODSTRING); + ParseNode relations = new ParseNode("relations", parser.curLine(1)); + relations.addChild(relation); + RESULT = relations; + :} + ; + +expr ::= + + ID:var + {: + debugMessage(PRODSTRING); + ParseNode expr = new ParseNode("expr", parser.curLine(1)); + expr.addChild("var").addChild(var); + RESULT = expr; + :} + + | OPENPAREN expr:expr CLOSEPAREN + {: + debugMessage(PRODSTRING); + RESULT = expr; + :} + + | LITERAL OPENPAREN literal:literal CLOSEPAREN + {: + debugMessage(PRODSTRING); + ParseNode expr = new ParseNode("expr", parser.curLine(4)); + expr.addChild(literal); + RESULT = expr; + :} + + | ID:var DOT relations:relations + {: + debugMessage(PRODSTRING); + ParseNode expr = new ParseNode("expr", parser.curLine(3)); + ParseNode relation = new ParseNode("relation"); + expr.addChild(relation); + relation.addChild("quantifiervar", parser.curLine(3)).addChild(var); + relation.addChild(relations); + RESULT = expr; + :} + + | ID:var DOTINV relations:relations + {: + debugMessage(PRODSTRING); + ParseNode expr = new ParseNode("expr", parser.curLine(3)); + ParseNode relation = new ParseNode("relation"); + expr.addChild(relation); + relation.addChild("quantifiervar", parser.curLine(3)).addChild(var); + relation.addChild(relations); + relations.getChildren().elementAt(0).addChild("inv"); + RESULT = expr; + :} + + | expr:expr1 operator:operator expr:expr2 + {: + debugMessage(PRODSTRING); + ParseNode op = (new ParseNode("expr", parser.curLine(3))).addChild("operator"); + op.addChild("op").addChild(operator); + op.addChild("left", parser.curLine(3)).addChild(expr1); + op.addChild("right", parser.curLine(1)).addChild(expr2); + RESULT = op.getRoot(); + :} + + + ; + +operator ::= + ADD + {: + debugMessage(PRODSTRING); + RESULT = new ParseNode("add", parser.curLine(1)); + :} + | SUB + {: + debugMessage(PRODSTRING); + RESULT = new ParseNode("sub", parser.curLine(1)); + :} + | MULT + {: + debugMessage(PRODSTRING); + RESULT = new ParseNode("mult", parser.curLine(1)); + :} + | DIV + {: + debugMessage(PRODSTRING); + RESULT = new ParseNode("div", parser.curLine(1)); + :} + ; + +compare ::= + LT + {: + debugMessage(PRODSTRING); + RESULT = new ParseNode("lt", parser.curLine(1)); + :} + | GT + {: + debugMessage(PRODSTRING); + RESULT = new ParseNode("gt", parser.curLine(1)); + :} + | LE + {: + debugMessage(PRODSTRING); + RESULT = new ParseNode("le", parser.curLine(1)); + :} + | GE + {: + debugMessage(PRODSTRING); + RESULT = new ParseNode("ge", parser.curLine(1)); + :} + | EQ + {: + debugMessage(PRODSTRING); + RESULT = new ParseNode("eq", parser.curLine(1)); + :} + | NE + {: + debugMessage(PRODSTRING); + RESULT = new ParseNode("ne", parser.curLine(1)); + :} + ; + +literal ::= + TRUE + {: + debugMessage(PRODSTRING); + RESULT = (new ParseNode("literal", parser.curLine(1))).addChild("boolean").addChild("true").getRoot(); + :} + | DECIMAL:dec + {: + debugMessage(PRODSTRING); + RESULT = (new ParseNode("literal", parser.curLine(1))).addChild("decimal").addChild(dec).getRoot(); + :} + | STRING:str + {: + debugMessage(PRODSTRING); + RESULT = (new ParseNode("literal", parser.curLine(1))).addChild("string").addChild(str).getRoot(); + :} + | CHAR:chr + {: + debugMessage(PRODSTRING); + RESULT = (new ParseNode("literal", parser.curLine(1))).addChild("char").addChild(chr).getRoot(); + :} + | ID:literal + {: + debugMessage(PRODSTRING); + RESULT = (new ParseNode("literal", parser.curLine(1))).addChild("token").addChild(literal).getRoot(); + :} + ; diff --git a/Repair/RepairCompiler/MCC/CLI.java b/Repair/RepairCompiler/MCC/CLI.java new file mode 100755 index 0000000..9669077 --- /dev/null +++ b/Repair/RepairCompiler/MCC/CLI.java @@ -0,0 +1,312 @@ +package MCC; + +import java.util.Vector; +import java.util.StringTokenizer; + +/** + * A generic command-line interface for 6.035 compilers. This class + * provides command-line parsing for student projects. It recognizes + * the required -target, -debug, -opt, and + * -o switches, and generates a name for input and output + * files. + * + * @author le01, 6.035 Staff (6.035-staff@mit.edu) + * @version $Id: CLI.java,v 1.1 2003/07/07 16:13:33 droy Exp $ + */ +public class CLI { + /** + * Target value indicating that the compiler should produce its + * default output. + */ + public static final int DEFAULT = 0; + + /** + * Target value indicating that the compiler should scan the input + * and stop. + */ + public static final int SCAN = 1; + + /** + * Target value indicating that the compiler should scan and parse + * its input, and stop. + */ + public static final int PARSE = 2; + + /** + * Target value indicating that the compiler should produce a + * high-level intermediate representation from its input, and stop. + * This is not one of the segment targets for Fall 2000, but you + * may wish to use it for your own purposes. + */ + public static final int INTER = 3; + + /** + * Target value indicating that the compiler should produce a + * low-level intermediate representation from its input, and stop. + */ + public static final int LOWIR = 4; + + /** + * Target value indicating that the compiler should produce + * assembly from its input. + */ + public static final int ASSEMBLY = 5; + + /** + * Array indicating which optimizations should be performed. If + * a particular element is true, it indicates that the optimization + * named in the optnames[] parameter to parse with the same index + * should be performed. + */ + public boolean opts[]; + + /** + * Vector of String containing the command-line arguments which could + * not otherwise be parsed. + */ + public Vector extras; + + /** + * Vector of String containing the optimizations which could not be + * parsed. It is okay to complain about anything in this list, even + * without the -debug flag. + */ + public Vector extraopts; + + /** + * Name of the file to put the output in. + */ + public String outfile; + + /** + * Name of the file to get input from. This is null if the user didn't + * provide a file name. + */ + public String infile; + + /** + * The target stage. This should be one of the integer constants + * defined elsewhere in this package. + */ + public int target; + + /** + * The debug flag. This is true if -debug was passed on + * the command line, requesting debugging output. + */ + public boolean debug; + + /** + * Native MIPS architecture is specified by "-native". The default + * is SPIM. + */ + public boolean fNative; + + /** + * Runs IRVis on final node tree. + */ + public boolean fVis; + public String visClass; + public String visMethod; + + /** + * Dumps the before and after Node structure to two files that can be diffed. + */ + public boolean fDiff; + public String diffFile; + + /** + * Maximum optimization iterations. + */ + public int numIterations = 5; + + /** + * Verbose output + */ + public int verbose; + + /** + * Public constructor. Sets up default values for all of the + * result fields. Specifically, sets the input and output files + * to null, the target to DEFAULT, and the extras and extraopts + * arrays to new empty Vectors. + */ + public CLI() { + outfile = null; + infile = null; + target = DEFAULT; + extras = new Vector(); + extraopts = new Vector(); + fNative = false; + fVis = false; + verbose = 0; + visClass = ""; + visMethod = ""; + fDiff = false; + diffFile = ""; + } + + /** + * Parse the command-line arguments. Sets all of the result fields + * accordingly.
+ * + * The boolean array opts[] indicates which, if any, of the + * optimizations in optnames[] should be performed; these arrays + * are in the same order. + * + * @param args Array of arguments passed in to the program's Main + * function. + * @param optnames Ordered array of recognized optimization names. */ + public void parse(String args[]) { + + String optnames[] = {}; + int context = 0; + String ext = ".out"; + + opts = new boolean[optnames.length]; + + for (int i = 0; i < args.length; i++) { + if (args[i].equals("-debug")) { + context = 0; + debug = true; + } else if (args[i].equals("-native")) { + context = 0; + fNative = true; + } else if (args[i].equals("-vis")) { + context = 4; + fVis = true; + } else if (args[i].equals("-diff")) { + context = 5; + fDiff = true; + } else if (args[i].equals("-i")) { + context = 6; + } else if (args[i].equals("-verbose") || args[i].equals("-v")) { + context = 0; + verbose++; + } else if (args[i].equals("-opt")) + context = 1; + else if (args[i].equals("-o")) + context = 2; + else if (args[i].equals("-target")) + context = 3; + else if (context == 1) { + boolean hit = false; + for (int j = 0; j < optnames.length; j++) { + if (args[i].equals("all") || + (args[i].equals(optnames[j]))) { + hit = true; + opts[j] = true; + } + if (args[i].equals("-" + optnames[j])) { + hit = true; + opts[j] = false; + } + } + if (!hit) + extraopts.addElement(args[i]); + } + else if (context == 2) { + outfile = args[i]; + context = 0; + } + else if (context == 3) { + // Process case insensitive. + String argSansCase = args[i].toLowerCase(); + // accept "scan" and "scanner" due to handout mistake + if (argSansCase.equals("scan") || + argSansCase.equals("scanner")) + target = SCAN; + else if (argSansCase.equals("parse")) + target = PARSE; + else if (argSansCase.equals("inter")) + target = INTER; + else if (argSansCase.equals("lowir")) + target = LOWIR; + else if (argSansCase.equals("assembly") || + argSansCase.equals("codegen")) + target = ASSEMBLY; + else + target = DEFAULT; // Anything else is just default + context = 0; + } else if (context == 4) { // -vis + StringTokenizer st = new StringTokenizer(args[i], "."); + visClass = st.nextToken(); + visMethod = st.nextToken(); + context = 0; + } else if (context == 5) { // -diff + diffFile = args[i]; // argument following is filename + context = 0; + } else if (context == 6) { // -i + numIterations = Integer.parseInt(args[i]); + context = 0; + } else { + boolean hit = false; + for (int j = 0; j < optnames.length; j++) { + if (args[i].equals("-" + optnames[j])) { + hit = true; + opts[j] = true; + } + } + if (!hit) { + extras.addElement(args[i]); + } + } + } + + // grab infile and lose extra args + int i = 0; + while (infile == null && i < extras.size()) { + String fn = (String) extras.elementAt(i); + + if (fn.charAt(0) != '-') + { + infile = fn; + extras.removeElementAt(i); + } + i++; + } + + // create outfile name + switch (target) { + case SCAN: + ext = ".scan"; + break; + case PARSE: + ext = ".parse"; + break; + case INTER: + ext = ".ir"; + break; + case LOWIR: + ext = ".lowir"; + break; + case ASSEMBLY: + ext = ".s"; + break; + case DEFAULT: + default: + ext = ".out"; + break; + } + + if (outfile == null && infile != null) { + int dot = infile.lastIndexOf('.'); + int slash = infile.lastIndexOf('/'); + // Last dot comes after last slash means that the file + // has an extention. Note that the base case where dot + // or slash are -1 also work. + if (dot <= slash) + outfile = infile + ext; + else + outfile = infile.substring(0, dot) + ext; + } + } +} diff --git a/Repair/RepairCompiler/MCC/Compiler.java b/Repair/RepairCompiler/MCC/Compiler.java new file mode 100755 index 0000000..7ea9362 --- /dev/null +++ b/Repair/RepairCompiler/MCC/Compiler.java @@ -0,0 +1,376 @@ +package MCC; + +import java.io.*; +import java.util.*; +import MCC.IR.*; + +/** + * The main compiler module, which does the following: + *