/* spec-compiler.jj Grammer definition for the specification */ /* SPEC constructs: Each construct should be embraced by /DOUBLE_STAR ... STAR/ annotation. Within there, any line beginning with a "#" is a comment of the annotation. Each constrcut should begin with @Begin and end with @End. Otherwise, the annotation would be considered as normal comments of the source. a) Global construct @Begin @Options: # If LANG is not define, it's C++ by default. C does not support class # and template, so if it's defined as C, we should also have a explicit # entry point. LANG = C; @Global_define: @DeclareStruct: @DeclareVar: @InitVar: @DefineFunc: ... @DefineFunc: @Interface_cluster: ... @Happens-before: ... @End b) Interface construct @Begin @Interface_decl: ... @Commit_point_set: IDENTIFIER | IDENTIFIER ... @Condition: ... (Optional) @HB_Condition: IDENTIFIER :: @HB_Condition: ... @ID: ... (Optional, use default ID) @Check: (Optional) ... @Action: (Optional) ... @Post_action: (Optional) @Post_check: (Optional) @End c) Potential commit construct @Begin @Potential_commit_point_define: ... @Label: ... @End OR @Begin @Potential_additional_ordering_point_define: ... @Label: ... @End d) Commit point define construct @Begin @Commit_point_define_check: ... @Label: ... @End OR # Addition ordering point is used to order operations when there are "equal" # commit point operations on the same location and that we cannot decide # which operation goes first, we will use additional ordering point to order # them (it's just similar to commit points). In implementation, we can just # treat them as commit points with a special flag. @Begin @Additional_ordering_point_define: ... @Potential_additional_ordering_point_label: ... @Label: ... @End OR @Begin @Additional_ordering_point_define: ... @Label: ... @End OR @Begin @Additional_ordering_point_define_check: ... @Label: ... @End // Commit point clear (just as a normal commit point, but it is used to // clear all commit points) @Begin @Commit_point_clear: ... @Label: ... @End e) Entry point construct @Begin @Entry_point @End f) Interface define construct @Begin @Interface_define: @End g) Interface declare & define construct @Begin @Interface_decl_define: @Commit_point_set: IDENTIFIER | IDENTIFIER ... @Condition: ... (Optional) @HB_Condition: IDENTIFIER :: @HB_Condition: ... @ID: ... (Optional, use default ID) @Check: (Optional) ... @Action: (Optional) ... @Post_action: (Optional) @Post_check: (Optional) @End */ options { STATIC = false; JAVA_UNICODE_ESCAPE = true; } PARSER_BEGIN(SpecParser) package edu.uci.eecs.specCompiler.grammerParser; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.InputStream; import java.io.ByteArrayInputStream; import java.io.File; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.Arrays; import edu.uci.eecs.specCompiler.specExtraction.Construct; import edu.uci.eecs.specCompiler.specExtraction.GlobalConstruct; import edu.uci.eecs.specCompiler.specExtraction.InterfaceConstruct; import edu.uci.eecs.specCompiler.specExtraction.PotentialCPDefineConstruct; import edu.uci.eecs.specCompiler.specExtraction.CPDefineConstruct; import edu.uci.eecs.specCompiler.specExtraction.CPDefineCheckConstruct; import edu.uci.eecs.specCompiler.specExtraction.CPClearConstruct; import edu.uci.eecs.specCompiler.specExtraction.ConditionalInterface; import edu.uci.eecs.specCompiler.specExtraction.SequentialDefineSubConstruct; import edu.uci.eecs.specCompiler.specExtraction.InterfaceDefineConstruct; import edu.uci.eecs.specCompiler.specExtraction.EntryPointConstruct; import edu.uci.eecs.specCompiler.specExtraction.ClassBeginConstruct; import edu.uci.eecs.specCompiler.specExtraction.ClassEndConstruct; import edu.uci.eecs.specCompiler.specExtraction.FunctionHeader; import edu.uci.eecs.specCompiler.specExtraction.QualifiedName; import edu.uci.eecs.specCompiler.specExtraction.SourceFileInfo; import edu.uci.eecs.specCompiler.specExtraction.VariableDeclaration; public class SpecParser { private static ArrayList _content; private static File _file; private static ArrayList _constructs; public static void main(String[] argvs) throws ParseException, TokenMgrError { try { File f = new File("./grammer/spec1.txt"); FileInputStream fis = new FileInputStream(f); SpecParser parser = new SpecParser(fis); ArrayList content = new ArrayList(); ArrayList constructs = new ArrayList(); ArrayList headers = new ArrayList(); parser.Parse(f, content, constructs, headers); for (int i = 0; i < content.size(); i++) { System.out.println(content.get(i)); } for (int i = 0; i < constructs.size(); i++) { System.out.println(constructs.get(i)); } //parser.Test(); System.out.println("Parsing finished!"); } catch (FileNotFoundException e) { e.printStackTrace(); } } public static SourceFileInfo ParseFile(File f) throws ParseException, TokenMgrError { try { InputStream input = new FileInputStream(f); SpecParser parser = new SpecParser(input); ArrayList content = new ArrayList(), headers = new ArrayList(); ArrayList constructs = new ArrayList(); parser.Parse(f, content, constructs, headers); return new SourceFileInfo(f, content, headers, constructs); } catch (FileNotFoundException e) { e.printStackTrace(); } return null; } private static ArrayList breakLines(String all) { String lines[] = all.split("[\\r\\n]+"); return new ArrayList(Arrays.asList(lines)); } public static ArrayList getTemplateArg(String line) throws ParseException { InputStream input = new ByteArrayInputStream(line.getBytes()); SpecParser parser = new SpecParser(input); return parser.TemplateParamList(); } public static FunctionHeader parseFuncHeader(String line) throws ParseException { InputStream input = new ByteArrayInputStream(line.getBytes()); SpecParser parser = new SpecParser(input); return parser.FuncDecl(); } public static String stringArray2String(ArrayList content) { StringBuilder sb = new StringBuilder(); if (content.size() == 1) return content.get(0); for (int i = 0; i < content.size(); i++) { sb.append(content.get(i) + "\n"); } return sb.toString(); } /** boolean spaceSeparator(Token t) { switch (t.image) { case "[": case "]": case "=": case "(": case ")": case ",": case ".": case "*": case "~": case "!": case "&": case "|": case "%": case "+": case "-": case "/": case "<": case ">": case "<=": case ">=": case "==": case "!=": case "&&": case "||": case "^": case "?": case ":": case "::": case "<<": case ">>": case ">>>": case "+=": case "-=": case "*=": case "/=": case "%=": case "^=": case "&=": case ";": return false; default: return true; } } */ } PARSER_END(SpecParser) SKIP : { " " | "\n" | "\r" | "\r\n" | "\t" } SKIP : { "/**" : IN_POTENTIAL_SPEC } TOKEN : { : IN_SPEC } SKIP : { "*/" : DEFAULT } SKIP : { "/*": IN_COMMENT } TOKEN: { } <*> SKIP : { // "//" comment for the specification <"//" (~["\n", "\r"])* (["\n", "\r"])> } SKIP : { "*/": DEFAULT } SKIP : { < ~[] > } SKIP : { // "#" comment for the specification <"#" (~["\n", "\r"])* (["\n", "\r"])> } TOKEN : { | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | } TOKEN : { /* Specification & C/C++ shared tokens */ // Reserved keywords | | | | | | | | <#DIGIT: ["0"-"9"]> | <#LETTER: ["a"-"z", "A"-"Z"]> | | "_") ( | | "_")*> | | | | | | | | "> | | /* C/C++ only token*/ | | | | | | | | | | | | | | | "> | ="> | | | | | | | | >"> | >>"> | | | | | < INTEGER_LITERAL: (["l","L"])? | (["l","L"])? | (["l","L"])?> | < #DECIMAL_LITERAL: ["1"-"9"] (["0"-"9"])* > | < #HEX_LITERAL: "0" ["x","X"] (["0"-"9","a"-"f","A"-"F"])+ > | < #OCTAL_LITERAL: "0" (["0"-"7"])* > | < FLOATING_POINT_LITERAL: | > | < #DECIMAL_FLOATING_POINT_LITERAL: (["0"-"9"])+ "." (["0"-"9"])* ()? (["f","F","d","D"])? | "." (["0"-"9"])+ ()? (["f","F","d","D"])? | (["0"-"9"])+ (["f","F","d","D"])? | (["0"-"9"])+ ()? ["f","F","d","D"]> | < #DECIMAL_EXPONENT: ["e","E"] (["+","-"])? (["0"-"9"])+ > | < #HEXADECIMAL_FLOATING_POINT_LITERAL: "0" ["x", "X"] (["0"-"9","a"-"f","A"-"F"])+ (".")? (["f","F","d","D"])? | "0" ["x", "X"] (["0"-"9","a"-"f","A"-"F"])* "." (["0"-"9","a"-"f","A"-"F"])+ (["f","F","d","D"])?> | < #HEXADECIMAL_EXPONENT: ["p","P"] (["+","-"])? (["0"-"9"])+ > | < #SPACE: (" " | "\t")+> | < #TO_END_OF_LINE: (~["\n"])+> | /* Macro token */ )? "include" ( | "<" ( | )+ ">")> | )? > } String Type() : { String type; String str; QualifiedName name; } { { type = ""; } ( { type = "const"; } )? (((str = .image | str = .image | str = .image) { type = type + " " + str; })? ( name = ParseQualifiedName() { if (!type.equals("")) type = type + " " + name.fullName; else type = name.fullName; }) ) ((str = .image { if (!type.equals("")) type = type + " " + str; else type = str; }) | (str = .image { if (!type.equals("")) type = type + " " + str; else type = str; }) | (str = .image { if (!type.equals("")) type = type + " " + str; else type = str; }) )* { return type; } } String ParameterizedName() : { String res = ""; String str; } { (str = .image {res = str;}) ( str = Type() { res = res + "<" + str; } ( str = Type() { res = res + ", " + str; })* { res = res + ">"; } )? { return res; } } FunctionHeader FuncDecl() : { String ret; QualifiedName funcName; ArrayList args; } { ( | )* ret = Type() funcName = ParseQualifiedName() args = FormalParamList() { FunctionHeader res = new FunctionHeader(ret, funcName, args); //System.out.println(res); return res; } } QualifiedName ParseQualifiedName() : { String qualifiedName, str; } { { qualifiedName = ""; } (str = ParameterizedName() { qualifiedName = qualifiedName + str; } ) ( (str = ParameterizedName() { qualifiedName = qualifiedName + "::" + str; } ))* { QualifiedName res = new QualifiedName(qualifiedName); //System.out.println(res); return res; } } ArrayList TemplateParamList() : { ArrayList params; String type; String name; } { { params = new ArrayList(); }