/* 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.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 { public static void main(String[] argvs) throws ParseException, TokenMgrError { try { FileInputStream fis = new FileInputStream("./grammer/spec.txt"); SpecParser parser = new SpecParser(fis); //parser.Parse(); System.out.println("Parsing finished!"); ArrayList typeParams = parser.FormalParamList(); } catch (FileNotFoundException e) { e.printStackTrace(); } } public static Construct parseSpec(String text) throws ParseException, TokenMgrError { InputStream input = new ByteArrayInputStream(text.getBytes()); SpecParser parser = new SpecParser(input); return parser.Parse(); } } PARSER_END(SpecParser) "/*"} < IN_COMMENT > SKIP : { < ~[] > } < IN_COMMENT > SKIP : { "*/": DEFAULT } TOKEN : { | } SKIP : { " " | "\n" | "\r" | "\r\n" | "\t" | // "#" comment for the specification <"#" (~["\n", "\r"])* (["\n", "\r"])> | // "//" comment for the specification <"//" (~["\n", "\r"])* (["\n", "\r"])> } TOKEN : { /* Above are specification-only tokens */ | | | | | | | | | | | | | | | | | | | | | | | | | | | | /* 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"])+ > } 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); } } Construct Parse() : { Construct res; } { ( LOOKAHEAD(3) res = Global_construct() | LOOKAHEAD(3) res = Interface() | LOOKAHEAD(3) res = Potential_commit_point_define() | LOOKAHEAD(3) res = Commit_point_define() | LOOKAHEAD(3) res = Commit_point_define_check() | LOOKAHEAD(3) res = Entry_point() | LOOKAHEAD(3) 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(code, options); } (Interface_clusters(res))? (Happens_before(res))? { res.unfoldInterfaceCluster(); return res; } } String C_CPP_CODE() : { StringBuilder text; Token t; } { { text = new StringBuilder(); t = new Token(); } ( //LOOKAHEAD(2) ( 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 = | t = | t = | t = | t = | t = | t = | t = ) { text.append(t.image); if (t.image.equals(";") || t.image.equals("\\") || t.image.equals("{") || t.image.equals("}")) text.append("\n"); else text.append(" "); } )+ { //System.out.println(text); return text.toString(); } } SequentialDefineSubConstruct Global_define() : { String declareVar, initVar, defineFunc; } { { declareVar = ""; initVar = ""; defineFunc = ""; } ( (declareVar = C_CPP_CODE()))? ( (initVar = C_CPP_CODE()))? ( (defineFunc = C_CPP_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; } { { 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); } )* ( (condition = C_CPP_CODE()))? ( (hbLabel = .image) (hbCondition = C_CPP_CODE()) { if (hbConditions.containsKey(hbLabel)) { throw new ParseException(interfaceName + " has" + "duplicate happens-before condtion labels"); } hbConditions.put(hbLabel, hbCondition); } )* ( (idCode = C_CPP_CODE()))? ( (check = C_CPP_CODE()))? (action = Action())? ( (postAction = C_CPP_CODE()))? ( (postCheck = C_CPP_CODE()))? { res = new InterfaceConstruct(interfaceName, commitPointSet, condition, hbConditions, idCode, check, action, postAction, postCheck); return res; } } ActionSubConstruct Action() : { String type, name, expr, defineVarStr, code; ArrayList defineVars; } { { defineVars = new ArrayList(); code = ""; } ( ( ( (defineVarStr = C_CPP_CODE()) { 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); })* ( (code = C_CPP_CODE()))? ) ) { ActionSubConstruct res = new ActionSubConstruct(defineVars, code); return res; } } PotentialCPDefineConstruct Potential_commit_point_define() : { PotentialCPDefineConstruct res; String label, condition; } { { res = null; } (condition = C_CPP_CODE())