parser checked
[cdsspec-compiler.git] / grammer / spec-compiler.jj
index 9627a89eb92534aebd95313c4cc4adaf977a8ed6..2238268a43ac644a62e490703ea226c6d3060f2f 100644 (file)
@@ -1,5 +1,66 @@
 /* spec-compiler.jj Grammer definition for the specification */
 
 /* 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 :: <C_CPP_Condition>
+       @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;
 options {
        STATIC = false;
        JAVA_UNICODE_ESCAPE = true;
@@ -8,24 +69,70 @@ options {
 PARSER_BEGIN(SpecParser)
 package edu.uci.eecs.specCompiler.grammerParser;
 
 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 {
                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)
 
        }
 PARSER_END(SpecParser)
 
-SKIP : {" " | "\n" | "\r" | "\r\n" | <COMMENT>}
-
-TOKEN :
+SKIP :
 {
 {
-       <SPACE: (" " | "\t")+>
+       " "
+|
+       "\n"
+|
+       "\r"
+|
+       "\r\n"
+|
+       "\t"
 |
 |
-       <COMMENT: <SPACE> "#" (~["\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   */
        <HEAD: "/**">
 |
        <TAIL: "*/">
        <HEAD: "/**">
 |
        <TAIL: "*/">
@@ -34,30 +141,472 @@ TOKEN :
 |
        <END: "@End">
 |
 |
        <END: "@End">
 |
-       <ID: "@ID:">
+       <GLOBAL_DEFINE: "@Global_define:">
+|
+       <INTERFACE_CLUSTER: "@Interface_cluster:">
+|
+       <HAPPENS_BEFORE: "@Happens_before:">
+|
+       <INTERFACE: "@Interface:">
+|
+       <COMMIT_POINT_SET: "@Commit_point_set:">
 |
        <CONDITION: "@Condition:">
 |
        <CONDITION: "@Condition:">
+|
+       <HB_CONDITION: "@HB_condition:">
+|
+       <ID: "@ID:">
 |
        <CHECK: "@Check:">
 |
        <ACTION: "@Action:">
 |
        <CHECK: "@Check:">
 |
        <ACTION: "@Action:">
+|
+       <DEFINEVAR: "@DefineVar:">
+|
+       <CODE: "@Code:">
 |
        <POST_ACTION: "@Post_action:">
 |
        <POST_CHECK: "@Post_check:">
 |
 |
        <POST_ACTION: "@Post_action:">
 |
        <POST_CHECK: "@Post_check:">
 |
-       <GLOBAL_DEFINE: "@Global_define:">
+       <POTENTIAL_COMMIT_POINT_DEFINE: "@Potential_commit_point_define:">
 |
 |
-       <HAPPENS_BEFORE: "@Happens_before:">
+       <LABEL: "@Label:">
 |
 |
-       <INTERFACE_CLUSTER: "@Interface_cluster:">
+       <COMMIT_POINT_DEFINE_CHECK: "@Commit_point_define_check:">
 |
 |
-       <POTENTIAL_COMMIT_POINT: "@Potential_commit_point:">
-       
+       <COMMIT_POINT_DEFINE: "@Commit_point_define:">
+|
+       <POTENTIAL_COMMIT_POINT_LABEL: "@Potential_commit_point_label:">
+
+
+/*   Specification & C/C++ shared tokens   */
+|
+       <#DIGIT: ["0"-"9"]>
+|
+       <#LETTER: ["a"-"z", "A"-"Z"]>
+|
+       <IDENTIFIER: (<LETTER> | "_") (<LETTER> | <DIGIT> | "_")*>
+|
+       <EQUALS: "=">
+|
+       <OPEN_PAREN: "{">
+|
+       <CLOSE_PAREN: "}">
+|
+       <OPEN_BRACKET: "(">
+|
+       <CLOSE_BRACKET: ")">
+|
+       <HB_SYMBOL: "->">
+|
+       <COMMA: ",">
+
+|
+/*   C/C++ only token*/
+       <DOT: ".">
+|
+       <STAR: "*">
+|
+       <NEGATE: "~">
+|
+       <EXCLAMATION: "!">
+|
+       <AND: "&">
+|
+       <OR: "|">
+|
+       <MOD: "%">
+|
+       <PLUS: "+">
+|
+       <PLUSPLUS: "++">
+|
+       <MINUS: "-">
+|
+       <MINUSMINUS: "--">
+|
+       <DIVIDE: "/">
+|
+       <BACKSLASH: "\\">
+|
+       <LESS_THAN: "<">
+|
+       <GREATER_THAN: ">">
+|
+       <GREATER_EQUALS: ">=">
+|
+       <LESS_EQUALS: "<=">
+|
+       <LOGICAL_EQUALS: "==">
+|
+       <NOT_EQUALS: "!=">
+|
+       <LOGICAL_AND: "&&">
+|
+       <LOGICAL_OR: "||">
+|
+       <XOR: "^">
+|
+       <QUESTION_MARK: "?">
+|
+       <COLON: ":">
+|
+       <DOUBLECOLON: "::">
+|
+       <SEMI_COLON: ";">
+|
+       <STRING_LITERAL:
+       "\""
+       ((~["\"","\\","\n","\r"])
+       | ("\\"
+               ( ["n","t","b","r","f","\\","'","\""]
+               | ["0"-"7"] ( ["0"-"7"] )?
+               | ["0"-"3"] ["0"-"7"]
+                       ["0"-"7"]
+               )
+               )
+       )*
+       "\"">
+|
+       <CHARACTER_LITERAL:
+       "'"
+       ((~["'","\\","\n","\r"])
+       | ("\\"
+               (["n","t","b","r","f","\\","'","\""]
+               | ["0"-"7"] ( ["0"-"7"] )?
+               | ["0"-"3"] ["0"-"7"]
+               ["0"-"7"]
+               )
+               )
+       )
+       "'">
+|
+       < INTEGER_LITERAL:
+        <DECIMAL_LITERAL> (["l","L"])?
+      | <HEX_LITERAL> (["l","L"])?
+      | <OCTAL_LITERAL> (["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>
+      | <HEXADECIMAL_FLOATING_POINT_LITERAL> >
+|
+       < #DECIMAL_FLOATING_POINT_LITERAL:
+        (["0"-"9"])+ "." (["0"-"9"])* (<DECIMAL_EXPONENT>)? (["f","F","d","D"])?
+      | "." (["0"-"9"])+ (<DECIMAL_EXPONENT>)? (["f","F","d","D"])?
+      | (["0"-"9"])+ <DECIMAL_EXPONENT> (["f","F","d","D"])?
+      | (["0"-"9"])+ (<DECIMAL_EXPONENT>)? ["f","F","d","D"]>
+|
+       < #DECIMAL_EXPONENT: ["e","E"] (["+","-"])? (["0"-"9"])+ >
+|
+       < #HEXADECIMAL_FLOATING_POINT_LITERAL:
+        "0" ["x", "X"] (["0"-"9","a"-"f","A"-"F"])+ (".")? <HEXADECIMAL_EXPONENT> (["f","F","d","D"])?
+      | "0" ["x", "X"] (["0"-"9","a"-"f","A"-"F"])* "." (["0"-"9","a"-"f","A"-"F"])+ <HEXADECIMAL_EXPONENT> (["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()
+       )
+       <EOF>
+       {
+               //System.out.println(res);
+               return res;
+       }
+}
+
+GlobalConstruct Global_construct() :
+{
+       GlobalConstruct res;
+       String code;
+}
+{
+       { res = null; }
+       <HEAD>
+               <BEGIN> 
+                       (code = Global_define())
+                       { res = new GlobalConstruct(code); }
+                       (Interface_clusters(res))?
+                       (Happens_before(res))?
+               <END>
+       <TAIL>
+       {
+               res.unfoldInterfaceCluster();
+               return res;
+       }
+}
+
+String C_CPP_CODE() :
+{
+       StringBuilder text;
+       Token t;
+}
+{
+       {
+               text = new StringBuilder();
+               t = new Token();
+       }
+       (
+       //LOOKAHEAD(2)
+       (
+       t = <IDENTIFIER> | t = <EQUALS> | t = <OPEN_PAREN> | t = <CLOSE_PAREN> |
+       t = <OPEN_BRACKET> | t = <CLOSE_BRACKET> | t = <HB_SYMBOL> | t = <COMMA> |
+       t = <DOT> | t = <STAR> | t = <NEGATE> | t = <EXCLAMATION> | t = <AND> | t = <OR> | t = <MOD> | t = <PLUS> |
+       t = <PLUSPLUS> | t = <MINUS> | t = <MINUSMINUS> | t = <DIVIDE> | t = <BACKSLASH> |
+       t = <LESS_THAN> | t = <GREATER_THAN> | t = <GREATER_EQUALS>     | t = <LESS_EQUALS> |
+       t = <LOGICAL_EQUALS> | t = <NOT_EQUALS> | t = <LOGICAL_AND> | t = <LOGICAL_OR> | t = <XOR> |
+       t = <QUESTION_MARK> | t = <COLON> | t = <DOUBLECOLON> |
+       t = <SEMI_COLON> | t = <STRING_LITERAL> | t = <CHARACTER_LITERAL> |
+       t = <INTEGER_LITERAL> | t = <FLOATING_POINT_LITERAL>
+       )
+       {
+               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;    
+}
+{
+       <GLOBAL_DEFINE> (code = C_CPP_CODE())
+       {
+               return code;
+       }
+}
+
+ConditionalInterface Conditional_interface() :
+{
+       String interfaceName, hbConditionLabel;
+}
+{
+       {
+               hbConditionLabel = "";
+       }
+       interfaceName = <IDENTIFIER>.image (<OPEN_BRACKET> hbConditionLabel =
+       <IDENTIFIER>.image <CLOSE_BRACKET>)?
+       {
+               return new ConditionalInterface(interfaceName, hbConditionLabel);
+       }
+}
+
+void Interface_cluster(GlobalConstruct inst) :
+{
+       String clusterName;
+       ConditionalInterface condInterface;
+}
+{
+       (clusterName= <IDENTIFIER>.image)
+       <EQUALS> <OPEN_PAREN>
+               (condInterface = Conditional_interface()
+               { inst.addInterface2Cluster(clusterName, condInterface); } 
+               )
+               (<COMMA> condInterface = Conditional_interface()
+               { inst.addInterface2Cluster(clusterName, condInterface); } 
+               )*
+       <CLOSE_PAREN>
 }
 
 }
 
-void Start() :
+void Interface_clusters(GlobalConstruct inst) :
 {}
 {
 {}
 {
-       <HEAD> <BEGIN> <END> <TAIL> <EOF>
+       <INTERFACE_CLUSTER> (Interface_cluster(inst))+
+}
+
+void Happens_before(GlobalConstruct inst) :
+{
+       ConditionalInterface left, right;       
+}
+{
+       <HAPPENS_BEFORE> 
+       (
+       left = Conditional_interface() <HB_SYMBOL> right = Conditional_interface()
+       { inst.addHBCondition(left, right); }
+       )+
+}
+
+InterfaceConstruct Interface() :
+{
+       InterfaceConstruct res;
+       String interfaceName, condition, idCode, check, postAction,
+               postCheck, commitPoint, hbLabel, hbCondition;
+       ActionSubConstruct action;
+       ArrayList<String> commitPointSet;
+       HashMap<String, String> hbConditions;
+}
+{
+       {
+               res = null;
+               action = null;
+               condition = "";
+               idCode = "";
+               check = "";
+               postAction = "";
+               postCheck = "";
+               commitPointSet = new ArrayList<String>();
+               hbConditions = new HashMap<String, String>();
+       }
+       <HEAD> 
+               <BEGIN>
+                       <INTERFACE> (interfaceName = <IDENTIFIER>.image)
+                       <COMMIT_POINT_SET>
+                               (commitPoint = <IDENTIFIER>.image
+                               { commitPointSet.add(commitPoint); }
+                               )
+                               (<OR>
+                                       (commitPoint = <IDENTIFIER>.image)
+                                       {
+                                               if (commitPointSet.contains(commitPoint)) {
+                                                       throw new ParseException(interfaceName + " has" +
+                                                               "duplicate commit point labels");
+                                               }
+                                               commitPointSet.add(commitPoint);
+                                       }
+                               )*
+
+                       (<CONDITION> (condition = C_CPP_CODE()))?
+                       (
+                               <HB_CONDITION>
+                               (hbLabel = <IDENTIFIER>.image)
+                               (hbCondition = C_CPP_CODE())
+                               {
+                                       if (hbConditions.containsKey(hbLabel)) {
+                                               throw new ParseException(interfaceName + " has" +
+                                                       "duplicate happens-before condtion labels");
+                                       }
+                                       hbConditions.put(hbLabel, hbCondition);
+                               }
+                       )*
+                       (<ID> (idCode = C_CPP_CODE()))?
+                       (<CHECK> (check = C_CPP_CODE()))?
+                       (action = Action())?
+                       (<POST_ACTION> (postAction = C_CPP_CODE()))?
+                       (<POST_CHECK> (postCheck = C_CPP_CODE()))?
+               <END>
+       <TAIL>
+       {
+               res = new InterfaceConstruct(interfaceName, commitPointSet, condition,
+                       hbConditions, idCode, check, action, postAction, postCheck);
+               return res;
+       }
+}
+
+ActionSubConstruct Action() :
+{
+       String type, name, expr, defineVarStr, code;
+       ArrayList<DefineVar> defineVars;
+}
+{
+       {
+               defineVars = new ArrayList<DefineVar>();
+               code = "";
+       }
+       <ACTION>
+       (
+               (
+               (<DEFINEVAR> (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> (code = C_CPP_CODE()))? ) 
+       )
+       
+       {
+               ActionSubConstruct res = new ActionSubConstruct(defineVars, code);
+               return res;
+       }
+}
+
+PotentialCPDefineConstruct Potential_commit_point_define() :
+{
+       PotentialCPDefineConstruct res;
+       String label, condition;
+}
+{
+
+       { res = null; }
+       <HEAD> 
+               <BEGIN>
+                       <POTENTIAL_COMMIT_POINT_DEFINE> (condition = C_CPP_CODE())
+                       <LABEL> (label = <IDENTIFIER>.image)
+               <END>
+       <TAIL>
+       {
+               res = new PotentialCPDefineConstruct(label, condition); 
+               return res;
+       }
+}
+
+
+CPDefineConstruct Commit_point_define() :
+{
+       CPDefineConstruct res;
+       String label, potentialCPLabel, condition;
+}
+{
+
+       { res = null; }
+       <HEAD> 
+               <BEGIN>
+                       <COMMIT_POINT_DEFINE> (condition = C_CPP_CODE())
+                       <POTENTIAL_COMMIT_POINT_LABEL> (potentialCPLabel = <IDENTIFIER>.image)
+                       <LABEL> (label = <IDENTIFIER>.image)
+               <END>
+       <TAIL>
+       {
+               res = new CPDefineConstruct(label, potentialCPLabel, condition);
+               return res;
+       }
+}
+
+
+CPDefineCheckConstruct Commit_point_define_check() :
+{
+       CPDefineCheckConstruct res;     
+       String label, condition;
+}
+{
+
+       { res = null; }
+       <HEAD> 
+               <BEGIN> 
+                       <COMMIT_POINT_DEFINE_CHECK> (condition = C_CPP_CODE())
+                       <LABEL> (label = <IDENTIFIER>.image)
+               <END>
+       <TAIL>
+       {
+               res = new CPDefineCheckConstruct(label, condition);
+               return res;
+       }
 }
 }