X-Git-Url: http://plrg.eecs.uci.edu/git/?p=cdsspec-compiler.git;a=blobdiff_plain;f=grammer%2Fspec-compiler.jj;h=2238268a43ac644a62e490703ea226c6d3060f2f;hp=9627a89eb92534aebd95313c4cc4adaf977a8ed6;hb=570d67c87af73f80a04e584ffacf2c395c570450;hpb=ee6ddc5f746aed2d554684557faad6733c3570af diff --git a/grammer/spec-compiler.jj b/grammer/spec-compiler.jj index 9627a89..2238268 100644 --- a/grammer/spec-compiler.jj +++ b/grammer/spec-compiler.jj @@ -1,5 +1,66 @@ /* 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 + @Global_define: + ... + @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) + @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 +*/ + + + options { STATIC = false; JAVA_UNICODE_ESCAPE = true; @@ -8,24 +69,70 @@ options { PARSER_BEGIN(SpecParser) package edu.uci.eecs.specCompiler.grammerParser; - class SpecParser { +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; + + public class SpecParser { public static void main(String[] argvs) throws ParseException, TokenMgrError { - SpecParser parser = new SpecParser(System.in); - parser.Start(); - System.out.println("Parsing finished!"); + try { + FileInputStream fis = new FileInputStream("./grammer/spec.txt"); + SpecParser parser = new SpecParser(fis); + parser.Parse(); + System.out.println("Parsing finished!"); + } 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) -SKIP : {" " | "\n" | "\r" | "\r\n" | } - -TOKEN : +SKIP : { - + " " +| + "\n" +| + "\r" +| + "\r\n" +| + "\t" | - "#" (~["\n", "\r"])* ["\n", "\r"]> + // "#" comment for the specification + <"#" (~["\n", "\r"])* (["\n", "\r"])> | + // "//" comment for the specification + <"//" (~["\n", "\r"])* (["\n", "\r"])> +} + +TOKEN : +{ +/* Above are specification-only tokens */ | @@ -34,30 +141,472 @@ TOKEN : | | - + +| + +| + +| + +| + | +| + +| + | | +| + +| + | | | - + | - + | - + | - - + +| + + + +/* Specification & C/C++ shared tokens */ +| + <#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"])+ > +} + +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() + ) + + { + //System.out.println(res); + return res; + } +} + +GlobalConstruct Global_construct() : +{ + GlobalConstruct res; + String code; +} +{ + { res = null; } + + + (code = Global_define()) + { res = new GlobalConstruct(code); } + (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 = + ) + { + 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(); + } +} + +String Global_define() : +{ + String code; +} +{ + (code = C_CPP_CODE()) + { + return code; + } +} + +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 Start() : +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()) +