/* 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: @DeclareVar: @InitVar: @DefineFunc: ... @Interface_cluster: ... @Happens-before: ... @End b) Interface construct @Begin @Interface: ... @Commit_point_set: IDENTIFIER | IDENTIFIER ... @Condition: ... (Optional) @HB_Condition: IDENTIFIER :: @HB_Condition: ... @ID: ... (Optional, use default ID) @Check: (Optional) ... @Action: (Optional) # Type here must be a pointer @DefineVar: Type var1 = SomeExpression (Optional) @Code (Optional) ... @Post_action: (Optional) @Post_check: (Optional) @End c) Potential commit construct @Begin @Potential_commit_point_define: ... @Label: ... @End d) Commit point define construct @Begin @Commit_point_define_check: ... @Label: ... @End OR @Begin @Commit_point_define: ... @Potential_commit_point_label: ... @Label: ... @End e) Entry point construct @Begin @Entry_point @End f) Interface define construct @Begin @Interface_define: @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 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.ConditionalInterface; import edu.uci.eecs.specCompiler.specExtraction.ActionSubConstruct; import edu.uci.eecs.specCompiler.specExtraction.ActionSubConstruct.DefineVar; import edu.uci.eecs.specCompiler.specExtraction.SequentialDefineSubConstruct; import edu.uci.eecs.specCompiler.specExtraction.InterfaceDefineConstruct; import edu.uci.eecs.specCompiler.specExtraction.EntryPointConstruct; 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/spec.txt"); FileInputStream fis = new FileInputStream(f); SpecParser parser = new SpecParser(fis); ArrayList content = new ArrayList(); ArrayList constructs = new ArrayList(); parser.Parse(f, content, constructs); System.out.println("Parsing finished!"); } catch (FileNotFoundException e) { e.printStackTrace(); } } public static void ParseFile(File f, ArrayList content, ArrayList constructs) throws ParseException, TokenMgrError { try { InputStream input = new FileInputStream(f); SpecParser parser = new SpecParser(input); parser.Parse(f, content, constructs); } catch (FileNotFoundException e) { e.printStackTrace(); } } public static String stringArray2String(ArrayList content) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < content.size(); i++) { sb.append(content.get(i) + "\n"); } return sb.toString(); } } PARSER_END(SpecParser) <*> SKIP : { " " | "\n" | "\r" | "\r\n" | "\t" } SKIP : { "/**" : IN_POTENTIAL_SPEC } TOKEN : { : IN_SPEC } SKIP : { "*/" : DEFAULT } SKIP : { "/*": IN_COMMENT } <*> 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; } { { type = ""; } ("const" { type = "const"; } )? (("struct" { type = type + " struct"; })? (str = .image { if (!type.equals("")) type = type + " " + str; else type = str; })) ((str = "const".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; } } ArrayList FormalParamList() : { ArrayList typeParams; } { { typeParams = new ArrayList(); } (TypeParam(typeParams) ( TypeParam(typeParams))*)? { System.out.println(typeParams); return typeParams; } } void TypeParam(ArrayList typeParams) : { String type, param; } { (type = Type()) (param = .image) { typeParams.add(type); typeParams.add(param); } } ArrayList C_CPP_CODE() : { String text; Token t; boolean newLine = false; ArrayList content; } { { text = ""; t = new Token(); content = new ArrayList(); } ( LOOKAHEAD(2) ( t = | t = | t = | t = | t = | (t = { newLine = true; } ) | (t = { newLine = true; } ) | t = | t = | t = | t = | t = | t = | t = | t = | t = | t = | t = | t = | t = | t = | t = | t = | t = | t = | t = | t = | t = | t = | t = | t = | t = | t = | t = | t = | t = | t = | t = | t = | (t = { newLine = true; } ) | t = | t = | t = | t = | (t = { newLine = true; } ) | (t = { newLine = true; } ) ) { text = text + " " + t.image; if (newLine) { content.add(text); text = ""; newLine = false; } } )+ { return content; } } void Parse(File f, ArrayList content, ArrayList constructs) : { Construct inst; ArrayList code; } { { _file = f; _content = content; _constructs = constructs; } ((inst = ParseSpec() { _constructs.add(inst); }) | ((code = C_CPP_CODE()) { _content.addAll(code); }) )* } Construct ParseSpec() : { Construct res; } { ( LOOKAHEAD(2) res = Global_construct() | LOOKAHEAD(2) res = Interface() | LOOKAHEAD(2) res = Potential_commit_point_define() | LOOKAHEAD(2) res = Commit_point_define() | LOOKAHEAD(2) res = Commit_point_define_check() | LOOKAHEAD(2) res = Entry_point() | LOOKAHEAD(2) res = Interface_define() ) { //System.out.println(res); return res; } } GlobalConstruct Global_construct() : { GlobalConstruct res; SequentialDefineSubConstruct code; HashMap options; String key, value; } { { res = null; options = new HashMap(); } ( ((key = .image) (value = .image) { if (options.containsKey(key)) { throw new ParseException("Duplicate options!"); } options.put(key, value); } )* )? (code = Global_define()) { res = new GlobalConstruct(_file, _content.size(), code, options); } (Interface_clusters(res))? (Happens_before(res))? { res.unfoldInterfaceCluster(); return res; } } SequentialDefineSubConstruct Global_define() : { String declareVar, initVar, defineFunc; ArrayList code; } { { declareVar = ""; initVar = ""; defineFunc = ""; } ( (code = C_CPP_CODE() { declareVar = stringArray2String(code); } ))? ( (code = C_CPP_CODE() { initVar = stringArray2String(code); } ))? ( (code = C_CPP_CODE() { defineFunc = stringArray2String(code); }))? { SequentialDefineSubConstruct res = new SequentialDefineSubConstruct(declareVar, initVar, defineFunc); //System.out.println(res); return res; } } ConditionalInterface Conditional_interface() : { String interfaceName, hbConditionLabel; } { { hbConditionLabel = ""; } interfaceName = .image ( hbConditionLabel = .image )? { return new ConditionalInterface(interfaceName, hbConditionLabel); } } void Interface_cluster(GlobalConstruct inst) : { String clusterName; ConditionalInterface condInterface; } { (clusterName= .image) (condInterface = Conditional_interface() { inst.addInterface2Cluster(clusterName, condInterface); } ) ( condInterface = Conditional_interface() { inst.addInterface2Cluster(clusterName, condInterface); } )* } void Interface_clusters(GlobalConstruct inst) : {} { (Interface_cluster(inst))+ } void Happens_before(GlobalConstruct inst) : { ConditionalInterface left, right; } { ( left = Conditional_interface() right = Conditional_interface() { inst.addHBCondition(left, right); } )+ } InterfaceConstruct Interface() : { InterfaceConstruct res; String interfaceName, condition, idCode, check, postAction, postCheck, commitPoint, hbLabel, hbCondition; ActionSubConstruct action; ArrayList commitPointSet; HashMap hbConditions; ArrayList content; } { { res = null; action = null; condition = ""; idCode = ""; check = ""; postAction = ""; postCheck = ""; commitPointSet = new ArrayList(); hbConditions = new HashMap(); } (interfaceName = .image) (commitPoint = .image { commitPointSet.add(commitPoint); } ) ( (commitPoint = .image) { if (commitPointSet.contains(commitPoint)) { throw new ParseException(interfaceName + " has" + "duplicate commit point labels"); } commitPointSet.add(commitPoint); } )* ( (content = C_CPP_CODE() { condition = stringArray2String(content); }))? ( (hbLabel = .image) (content = C_CPP_CODE() { hbCondition = stringArray2String(content); }) { if (hbConditions.containsKey(hbLabel)) { throw new ParseException(interfaceName + " has" + "duplicate happens-before condtion labels"); } hbConditions.put(hbLabel, hbCondition); } )* ( (content = C_CPP_CODE() { idCode = stringArray2String(content); }))? ( (content = C_CPP_CODE() { check = stringArray2String(content); }))? (action = Action())? ( (content = C_CPP_CODE() { postAction = stringArray2String(content); }))? ( (content = C_CPP_CODE() { postCheck = stringArray2String(content); }))? { res = new InterfaceConstruct(_file, _content.size(), interfaceName, commitPointSet, condition, hbConditions, idCode, check, action, postAction, postCheck); return res; } } ActionSubConstruct Action() : { String type, name, expr, defineVarStr, code; ArrayList defineVars; ArrayList content; } { { defineVars = new ArrayList(); code = ""; } ( ( ( (content = C_CPP_CODE() { defineVarStr = stringArray2String(content); }) { int eqIdx = defineVarStr.indexOf('='); int typeEnd = defineVarStr.lastIndexOf(' ', eqIdx - 2); type = defineVarStr.substring(0, typeEnd); name = defineVarStr.substring(typeEnd + 1, eqIdx - 1); expr = defineVarStr.substring(eqIdx + 2); DefineVar defineVar = new DefineVar(type, name, expr); defineVars.add(defineVar); })* ( (content = C_CPP_CODE() { code = stringArray2String(content); }))? ) ) { ActionSubConstruct res = new ActionSubConstruct(defineVars, code); return res; } } PotentialCPDefineConstruct Potential_commit_point_define() : { PotentialCPDefineConstruct res; String label, condition; ArrayList content; } { { res = null; } (content = C_CPP_CODE() { condition = stringArray2String(content); })