1 /* spec-compiler.jj Grammer definition for the specification */
6 Each construct should be embraced by /DOUBLE_STAR ... STAR/ annotation.
7 Within there, any line beginning with a "#" is a comment of the annotation.
8 Each constrcut should begin with @Begin and end with @End. Otherwise, the
9 annotation would be considered as normal comments of the source.
14 # If LANG is not define, it's C++ by default. C does not support class
15 # and template, so if it's defined as C, we should also have a explicit
31 b) Interface construct
35 IDENTIFIER | IDENTIFIER ...
36 @Condition: ... (Optional)
38 IDENTIFIER :: <C_CPP_Condition>
40 @ID: ... (Optional, use default ID)
45 @Post_action: (Optional)
46 @Post_check: (Optional)
49 c) Potential commit construct
51 @Potential_commit_point_define: ...
55 d) Commit point define construct
57 @Commit_point_define_check: ...
64 @Commit_point_define: ...
65 @Potential_commit_point_label: ...
69 e) Entry point construct
74 f) Interface define construct
76 @Interface_define: <Interface_Name>
84 JAVA_UNICODE_ESCAPE = true;
87 PARSER_BEGIN(SpecParser)
88 package edu.uci.eecs.specCompiler.grammerParser;
90 import java.io.FileInputStream;
91 import java.io.FileNotFoundException;
92 import java.io.InputStream;
93 import java.io.ByteArrayInputStream;
95 import java.util.ArrayList;
96 import java.util.HashMap;
97 import java.util.HashSet;
99 import edu.uci.eecs.specCompiler.specExtraction.Construct;
100 import edu.uci.eecs.specCompiler.specExtraction.GlobalConstruct;
101 import edu.uci.eecs.specCompiler.specExtraction.InterfaceConstruct;
102 import edu.uci.eecs.specCompiler.specExtraction.PotentialCPDefineConstruct;
103 import edu.uci.eecs.specCompiler.specExtraction.CPDefineConstruct;
104 import edu.uci.eecs.specCompiler.specExtraction.CPDefineCheckConstruct;
105 import edu.uci.eecs.specCompiler.specExtraction.ConditionalInterface;
106 import edu.uci.eecs.specCompiler.specExtraction.SequentialDefineSubConstruct;
107 import edu.uci.eecs.specCompiler.specExtraction.InterfaceDefineConstruct;
108 import edu.uci.eecs.specCompiler.specExtraction.EntryPointConstruct;
109 import edu.uci.eecs.specCompiler.specExtraction.ClassBeginConstruct;
110 import edu.uci.eecs.specCompiler.specExtraction.ClassEndConstruct;
111 import edu.uci.eecs.specCompiler.specExtraction.FunctionHeader;
112 import edu.uci.eecs.specCompiler.specExtraction.QualifiedName;
113 import edu.uci.eecs.specCompiler.specExtraction.SourceFileInfo;
114 import edu.uci.eecs.specCompiler.specExtraction.VariableDeclaration;
116 public class SpecParser {
117 private static ArrayList<String> _content;
118 private static File _file;
119 private static ArrayList<Construct> _constructs;
122 public static void main(String[] argvs)
123 throws ParseException, TokenMgrError {
125 File f = new File("./grammer/spec.txt");
126 FileInputStream fis = new FileInputStream(f);
127 SpecParser parser = new SpecParser(fis);
129 ArrayList<String> content = new ArrayList<String>();
130 ArrayList<Construct> constructs = new ArrayList<Construct>();
131 ArrayList<String> headers = new ArrayList<String>();
132 parser.Parse(f, content, constructs, headers);
133 for (int i = 0; i < content.size(); i++) {
134 System.out.println(content.get(i));
137 for (int i = 0; i < constructs.size(); i++) {
138 System.out.println(constructs.get(i));
143 System.out.println("Parsing finished!");
144 } catch (FileNotFoundException e) {
149 public static SourceFileInfo ParseFile(File f)
150 throws ParseException, TokenMgrError {
152 InputStream input = new FileInputStream(f);
153 SpecParser parser = new SpecParser(input);
154 ArrayList<String> content = new ArrayList<String>(),
155 headers = new ArrayList<String>();
156 ArrayList<Construct> constructs = new ArrayList<Construct>();
157 parser.Parse(f, content, constructs, headers);
158 return new SourceFileInfo(f, content, headers, constructs);
159 } catch (FileNotFoundException e) {
165 public static ArrayList<String> getTemplateArg(String line)
166 throws ParseException {
167 InputStream input = new ByteArrayInputStream(line.getBytes());
168 SpecParser parser = new SpecParser(input);
169 return parser.TemplateParamList();
172 public static FunctionHeader parseFuncHeader(String line)
173 throws ParseException {
174 InputStream input = new ByteArrayInputStream(line.getBytes());
175 SpecParser parser = new SpecParser(input);
176 return parser.FuncDecl();
180 public static String stringArray2String(ArrayList<String> content) {
181 StringBuilder sb = new StringBuilder();
182 if (content.size() == 1)
183 return content.get(0);
184 for (int i = 0; i < content.size(); i++) {
185 sb.append(content.get(i) + "\n");
187 return sb.toString();
191 PARSER_END(SpecParser)
209 "/**" : IN_POTENTIAL_SPEC
212 <IN_POTENTIAL_SPEC> TOKEN : {
213 <BEGIN: "@Begin"> : IN_SPEC
225 // "//" comment for the specification
226 <"//" (~["\n", "\r"])* (["\n", "\r"])>
229 <IN_COMMENT, IN_POTENTIAL_SPEC> SKIP : {
233 <IN_COMMENT, IN_POTENTIAL_SPEC> SKIP : { < ~[] > }
237 // "#" comment for the specification
238 <"#" (~["\n", "\r"])* (["\n", "\r"])>
245 <OPTIONS: "@Options:">
247 <GLOBAL_DEFINE: "@Global_define:">
249 <DECLARE_STRUCT: "@DeclareStruct:">
251 <DECLARE_VAR: "@DeclareVar:">
253 <INIT_VAR: "@InitVar:">
255 <DEFINE_FUNC: "@DefineFunc:">
257 <INTERFACE_CLUSTER: "@Interface_cluster:">
259 <HAPPENS_BEFORE: "@Happens_before:">
261 <INTERFACE: "@Interface:">
263 <COMMIT_POINT_SET: "@Commit_point_set:">
265 <ENTRY_POINT: "@Entry_point">
267 <CLASS_BEGIN: "@Class_begin">
269 <CLASS_END: "@Class_end">
271 <INTERFACE_DEFINE: "@Interface_define:">
273 <CONDITION: "@Condition:">
275 <HB_CONDITION: "@HB_condition:">
285 <POST_ACTION: "@Post_action:">
287 <POST_CHECK: "@Post_check:">
289 <POTENTIAL_COMMIT_POINT_DEFINE: "@Potential_commit_point_define:">
293 <COMMIT_POINT_DEFINE_CHECK: "@Commit_point_define_check:">
295 <COMMIT_POINT_DEFINE: "@Commit_point_define:">
297 <POTENTIAL_COMMIT_POINT_LABEL: "@Potential_commit_point_label:">
301 <IN_SPEC, DEFAULT> TOKEN :
303 /* Specification & C/C++ shared tokens */
311 <UNSIGNED: "unsigned">
313 <TEMPLATE: "template">
321 <#LETTER: ["a"-"z", "A"-"Z"]>
323 <IDENTIFIER: (<LETTER> | "_") (<LETTER> | <DIGIT> | "_")*>
345 /* C/C++ only token*/
376 <GREATER_EQUALS: ">=">
380 <LOGICAL_EQUALS: "==">
396 <DOUBLELESSTHAN: "<<">
398 <DOUBLEGREATERTHAN: ">>">
400 <TRIPLEGREATERTHAN: ">>>">
408 <DIVIDE_EQUALS: "/=">
423 ((~["\"","\\","\n","\r"])
425 ( ["n","t","b","r","f","\\","'","\""]
426 | ["0"-"7"] ( ["0"-"7"] )?
427 | ["0"-"3"] ["0"-"7"]
436 ((~["'","\\","\n","\r"])
438 (["n","t","b","r","f","\\","'","\""]
439 | ["0"-"7"] ( ["0"-"7"] )?
440 | ["0"-"3"] ["0"-"7"]
448 <DECIMAL_LITERAL> (["l","L"])?
449 | <HEX_LITERAL> (["l","L"])?
450 | <OCTAL_LITERAL> (["l","L"])?>
452 < #DECIMAL_LITERAL: ["1"-"9"] (["0"-"9"])* >
454 < #HEX_LITERAL: "0" ["x","X"] (["0"-"9","a"-"f","A"-"F"])+ >
456 < #OCTAL_LITERAL: "0" (["0"-"7"])* >
458 < FLOATING_POINT_LITERAL:
459 <DECIMAL_FLOATING_POINT_LITERAL>
460 | <HEXADECIMAL_FLOATING_POINT_LITERAL> >
462 < #DECIMAL_FLOATING_POINT_LITERAL:
463 (["0"-"9"])+ "." (["0"-"9"])* (<DECIMAL_EXPONENT>)? (["f","F","d","D"])?
464 | "." (["0"-"9"])+ (<DECIMAL_EXPONENT>)? (["f","F","d","D"])?
465 | (["0"-"9"])+ <DECIMAL_EXPONENT> (["f","F","d","D"])?
466 | (["0"-"9"])+ (<DECIMAL_EXPONENT>)? ["f","F","d","D"]>
468 < #DECIMAL_EXPONENT: ["e","E"] (["+","-"])? (["0"-"9"])+ >
470 < #HEXADECIMAL_FLOATING_POINT_LITERAL:
471 "0" ["x", "X"] (["0"-"9","a"-"f","A"-"F"])+ (".")? <HEXADECIMAL_EXPONENT> (["f","F","d","D"])?
472 | "0" ["x", "X"] (["0"-"9","a"-"f","A"-"F"])* "." (["0"-"9","a"-"f","A"-"F"])+ <HEXADECIMAL_EXPONENT> (["f","F","d","D"])?>
474 < #HEXADECIMAL_EXPONENT: ["p","P"] (["+","-"])? (["0"-"9"])+ >
476 < #SPACE: (" " | "\t")+>
478 < #TO_END_OF_LINE: (~["\n"])+>
481 <INCLUDE: "#" (<SPACE>)? "include" <SPACE> (<STRING_LITERAL> | "<" (<LETTER> | <DOT>)+ ">")>
483 <DEFINE: "#" (<SPACE>)? <TO_END_OF_LINE>>
497 (((str = <STRUCT>.image | str = <CLASS>.image | str = <UNSIGNED>.image) { type = type + " " + str; })?
499 name = ParseQualifiedName() {
500 if (!type.equals(""))
501 type = type + " " + name.fullName;
503 type = name.fullName;
506 ((str = "const".image {
507 if (!type.equals(""))
508 type = type + " " + str;
512 (str = <STAR>.image {
513 if (!type.equals(""))
514 type = type + " " + str;
519 if (!type.equals(""))
520 type = type + " " + str;
539 System.out.println(str);
544 System.out.println(func);
549 String ParameterizedName() :
555 (str = <IDENTIFIER>.image {res = str;})
556 ("<" str = Type() { res = res + "<" + str; }
557 ("," str = Type() { res = res + ", " + str; })* ">"
565 FunctionHeader FuncDecl() :
568 QualifiedName funcName;
569 ArrayList<VariableDeclaration> args;
572 (<STATIC> | <INLINE>)*
574 funcName = ParseQualifiedName()
575 args = FormalParamList()
577 FunctionHeader res = new FunctionHeader(ret, funcName, args);
578 //System.out.println(res);
583 QualifiedName ParseQualifiedName() :
585 String qualifiedName, str;
588 { qualifiedName = ""; }
589 (str = ParameterizedName() { qualifiedName = qualifiedName + str; } )
590 ( <DOUBLECOLON> (str = ParameterizedName() { qualifiedName = qualifiedName +
593 QualifiedName res = new QualifiedName(qualifiedName);
594 //System.out.println(res);
599 ArrayList<String> TemplateParamList() :
601 ArrayList<String> params;
606 params = new ArrayList<String>();
610 (str = <IDENTIFIER>.image
611 str = <IDENTIFIER>.image {params.add(str);})
613 ("," str = <IDENTIFIER>.image
614 str = <IDENTIFIER>.image {params.add(str);})*
617 //System.out.println(params);
622 ArrayList<VariableDeclaration > FormalParamList() :
624 ArrayList<VariableDeclaration > typeParams;
625 VariableDeclaration varDecl;
629 typeParams = new ArrayList<VariableDeclaration >();
632 ((varDecl = TypeParam() {typeParams.add(varDecl);})
633 ((<COMMA> varDecl = TypeParam() {typeParams.add(varDecl);}))*)?
640 VariableDeclaration TypeParam() :
645 (type = Type()) (param = <IDENTIFIER>.image)
647 return new VariableDeclaration(type, param);
651 ArrayList<String> C_CPP_CODE(ArrayList<String> headers) :
655 boolean newLine = false;
656 boolean inTemplate = false;
657 ArrayList<String> content;
664 content = new ArrayList<String>();
669 t = <CONST> | t = <STRUCT> | t = <CLASS> | t = <UNSIGNED> |
670 (t = <TEMPLATE> { inTemplate = true; })|
671 t = <STATIC> | t = <INLINE> |
676 if (headers != null) {
677 headers.add(header.substring(header.lastIndexOf(' ') + 1));
680 | t = <IDENTIFIER> | t = <POUND> |
681 (t = <OPEN_BRACE> { newLine = true; } ) |
682 (t = <CLOSE_BRACE> { newLine = true; } ) |
683 t = <EQUALS> | t = <OPEN_PAREN> | t = <CLOSE_PAREN> |
684 t = <OPEN_BRACKET> | t = <CLOSE_BRACKET>
685 | t = <HB_SYMBOL> | t = <COMMA> |
686 t = <DOT> | t = <STAR> | t = <NEGATE> | t = <EXCLAMATION> | t = <AND> | t = <OR> | t = <MOD> | t = <PLUS> |
687 t = <PLUSPLUS> | t = <MINUS> | t = <MINUSMINUS> | t = <DIVIDE> | t = <BACKSLASH> |
689 (t = <GREATER_THAN> { if (inTemplate) newLine = true; }) |
690 t = <GREATER_EQUALS> | t = <LESS_EQUALS> |
691 t = <LOGICAL_EQUALS> | t = <NOT_EQUALS> | t = <LOGICAL_AND> | t = <LOGICAL_OR> | t = <XOR> |
692 t = <QUESTION_MARK> | t = <COLON> | t = <DOUBLECOLON> |
693 t = <DOUBLELESSTHAN> |
694 t = <DOUBLEGREATERTHAN> |
695 t = <TRIPLEGREATERTHAN> |
700 t = <DIVIDE_EQUALS> |
706 (t = <SEMI_COLON> { newLine = true; } )
707 | t = <STRING_LITERAL> | t = <CHARACTER_LITERAL> |
708 t = <INTEGER_LITERAL> | t = <FLOATING_POINT_LITERAL> |
709 (t = <DEFINE> { newLine = true; } )
712 if (text.equals("")) {
715 text = text + " " + t.image;
727 if (content.size() == 0) {
735 void Parse(File f, ArrayList<String> content, ArrayList<Construct> constructs, ArrayList<String> headers) :
738 ArrayList<String> code;
744 _constructs = constructs;
746 ((inst = ParseSpec() { _constructs.add(inst); }) |
747 ((code = C_CPP_CODE(headers)) { _content.addAll(code); })
751 Construct ParseSpec() :
757 LOOKAHEAD(2) res = Global_construct() |
758 LOOKAHEAD(2) res = Interface() |
759 LOOKAHEAD(2) res = Potential_commit_point_define() |
760 LOOKAHEAD(2) res = Commit_point_define() |
761 LOOKAHEAD(2) res = Commit_point_define_check() |
762 LOOKAHEAD(2) res = Entry_point() |
763 LOOKAHEAD(2) res = Class_begin() |
764 LOOKAHEAD(2) res = Class_end() |
765 LOOKAHEAD(2) res = Interface_define()
768 //System.out.println(res);
773 GlobalConstruct Global_construct() :
776 SequentialDefineSubConstruct code;
777 HashMap<String, String> options;
783 options = new HashMap<String, String>();
787 ((key = <IDENTIFIER>.image)
789 (value = <IDENTIFIER>.image)
791 if (options.containsKey(key)) {
792 throw new ParseException("Duplicate options!");
794 options.put(key, value);
799 (code = Global_define())
800 { res = new GlobalConstruct(_file, _content.size(), code, options); }
801 (Interface_clusters(res))?
802 (Happens_before(res))?
805 res.unfoldInterfaceCluster();
810 SequentialDefineSubConstruct Global_define() :
812 ArrayList<String> initVar, defineFunc, code, declareStruct;
813 ArrayList<ArrayList<String>> defineFuncs;
814 ArrayList<VariableDeclaration> declareVars;
815 ArrayList<ArrayList<String>> declareStructs;
816 VariableDeclaration declareVar;
821 declareVars = new ArrayList<VariableDeclaration>();
823 defineFuncs = new ArrayList<ArrayList<String>>();
824 declareStructs = new ArrayList<ArrayList<String>>();
827 (<DECLARE_STRUCT> (declareStruct = C_CPP_CODE(null) {
828 declareStructs.add(declareStruct); }))*
829 (<DECLARE_VAR> ((declareVar = TypeParam() ";" {
830 declareVars.add(declareVar); } )*))?
831 (<INIT_VAR> (code = C_CPP_CODE(null) { initVar = code; } ))?
832 (<DEFINE_FUNC> (defineFunc = C_CPP_CODE(null) { defineFuncs.add(defineFunc); }))*
834 SequentialDefineSubConstruct res = new
835 SequentialDefineSubConstruct(declareStructs, declareVars, initVar, defineFuncs);
836 //System.out.println(res);
841 ConditionalInterface Conditional_interface() :
843 String interfaceName, hbConditionLabel;
847 hbConditionLabel = "";
849 interfaceName = <IDENTIFIER>.image (<OPEN_PAREN> hbConditionLabel =
850 <IDENTIFIER>.image <CLOSE_PAREN>)?
852 return new ConditionalInterface(interfaceName, hbConditionLabel);
856 void Interface_cluster(GlobalConstruct inst) :
859 ConditionalInterface condInterface;
862 (clusterName= <IDENTIFIER>.image)
863 <EQUALS> <OPEN_BRACE>
864 (condInterface = Conditional_interface()
865 { inst.addInterface2Cluster(clusterName, condInterface); }
867 (<COMMA> condInterface = Conditional_interface()
868 { inst.addInterface2Cluster(clusterName, condInterface); }
873 void Interface_clusters(GlobalConstruct inst) :
876 <INTERFACE_CLUSTER> (Interface_cluster(inst))+
879 void Happens_before(GlobalConstruct inst) :
881 ConditionalInterface left, right;
886 left = Conditional_interface() <HB_SYMBOL> right = Conditional_interface()
887 { inst.addHBCondition(left, right); }
891 InterfaceConstruct Interface() :
893 InterfaceConstruct res;
894 String interfaceName, condition, idCode, check,
895 postCheck, commitPoint, hbLabel, hbCondition;
896 ArrayList<String> commitPointSet;
897 ArrayList<String> action, postAction;
898 HashMap<String, String> hbConditions;
899 ArrayList<String> content;
904 action = new ArrayList<String>();
909 commitPointSet = new ArrayList<String>();
910 hbConditions = new HashMap<String, String>();
911 postAction = new ArrayList<String>();
914 <INTERFACE> (interfaceName = <IDENTIFIER>.image)
916 (commitPoint = <IDENTIFIER>.image
917 { commitPointSet.add(commitPoint); }
920 (commitPoint = <IDENTIFIER>.image)
922 if (commitPointSet.contains(commitPoint)) {
923 throw new ParseException(interfaceName + " has" +
924 "duplicate commit point labels");
926 commitPointSet.add(commitPoint);
930 (<CONDITION> (content = C_CPP_CODE(null) { condition = stringArray2String(content); }))?
933 (hbLabel = <IDENTIFIER>.image) <DOUBLECOLON>
934 (content = C_CPP_CODE(null) { hbCondition = stringArray2String(content); })
936 if (hbConditions.containsKey(hbLabel)) {
937 throw new ParseException(interfaceName + " has" +
938 "duplicate happens-before condtion labels");
940 hbConditions.put(hbLabel, hbCondition);
943 (<ID> (content = C_CPP_CODE(null) { idCode = stringArray2String(content); }))?
944 (<CHECK> (content = C_CPP_CODE(null) { check = stringArray2String(content); }))?
945 (<ACTION> action = C_CPP_CODE(null))?
946 (<POST_ACTION> (postAction = C_CPP_CODE(null) ))?
947 (<POST_CHECK> (content = C_CPP_CODE(null) { postCheck = stringArray2String(content); }))?
950 res = new InterfaceConstruct(_file, _content.size(), interfaceName, commitPointSet, condition,
951 hbConditions, idCode, check, action, postAction, postCheck);
957 PotentialCPDefineConstruct Potential_commit_point_define() :
959 PotentialCPDefineConstruct res;
960 String label, condition;
961 ArrayList<String> content;
967 <POTENTIAL_COMMIT_POINT_DEFINE> (content = C_CPP_CODE(null) { condition = stringArray2String(content); })
968 <LABEL> (label = <IDENTIFIER>.image)
971 res = new PotentialCPDefineConstruct(_file, _content.size(), label, condition);
977 CPDefineConstruct Commit_point_define() :
979 CPDefineConstruct res;
980 String label, potentialCPLabel, condition;
981 ArrayList<String> content;
987 <COMMIT_POINT_DEFINE> (content = C_CPP_CODE(null) { condition = stringArray2String(content); })
988 <POTENTIAL_COMMIT_POINT_LABEL> (potentialCPLabel = <IDENTIFIER>.image)
989 <LABEL> (label = <IDENTIFIER>.image)
992 res = new CPDefineConstruct(_file, _content.size(), label, potentialCPLabel, condition);
998 CPDefineCheckConstruct Commit_point_define_check() :
1000 CPDefineCheckConstruct res;
1001 String label, condition;
1002 ArrayList<String> content;
1008 <COMMIT_POINT_DEFINE_CHECK> (content = C_CPP_CODE(null) { condition = stringArray2String(content); })
1009 <LABEL> (label = <IDENTIFIER>.image)
1012 res = new CPDefineCheckConstruct(_file, _content.size(), label, condition);
1017 EntryPointConstruct Entry_point() :
1025 return new EntryPointConstruct(_file, _content.size());
1029 ClassBeginConstruct Class_begin() :
1037 return new ClassBeginConstruct(_file, _content.size());
1041 ClassEndConstruct Class_end() :
1049 return new ClassEndConstruct(_file, _content.size());
1053 InterfaceDefineConstruct Interface_define() :
1059 <INTERFACE_DEFINE> (name = <IDENTIFIER>.image)
1062 return new InterfaceDefineConstruct(_file, _content.size(), name);