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>
79 g) Interface declare & define construct
81 @Interface_decl_define: <Interface_Name>
83 IDENTIFIER | IDENTIFIER ...
84 @Condition: ... (Optional)
86 IDENTIFIER :: <C_CPP_Condition>
88 @ID: ... (Optional, use default ID)
93 @Post_action: (Optional)
94 @Post_check: (Optional)
103 JAVA_UNICODE_ESCAPE = true;
106 PARSER_BEGIN(SpecParser)
107 package edu.uci.eecs.specCompiler.grammerParser;
109 import java.io.FileInputStream;
110 import java.io.FileNotFoundException;
111 import java.io.InputStream;
112 import java.io.ByteArrayInputStream;
114 import java.util.ArrayList;
115 import java.util.HashMap;
116 import java.util.HashSet;
118 import edu.uci.eecs.specCompiler.specExtraction.Construct;
119 import edu.uci.eecs.specCompiler.specExtraction.GlobalConstruct;
120 import edu.uci.eecs.specCompiler.specExtraction.InterfaceConstruct;
121 import edu.uci.eecs.specCompiler.specExtraction.PotentialCPDefineConstruct;
122 import edu.uci.eecs.specCompiler.specExtraction.CPDefineConstruct;
123 import edu.uci.eecs.specCompiler.specExtraction.CPDefineCheckConstruct;
124 import edu.uci.eecs.specCompiler.specExtraction.ConditionalInterface;
125 import edu.uci.eecs.specCompiler.specExtraction.SequentialDefineSubConstruct;
126 import edu.uci.eecs.specCompiler.specExtraction.InterfaceDefineConstruct;
127 import edu.uci.eecs.specCompiler.specExtraction.EntryPointConstruct;
128 import edu.uci.eecs.specCompiler.specExtraction.ClassBeginConstruct;
129 import edu.uci.eecs.specCompiler.specExtraction.ClassEndConstruct;
130 import edu.uci.eecs.specCompiler.specExtraction.FunctionHeader;
131 import edu.uci.eecs.specCompiler.specExtraction.QualifiedName;
132 import edu.uci.eecs.specCompiler.specExtraction.SourceFileInfo;
133 import edu.uci.eecs.specCompiler.specExtraction.VariableDeclaration;
135 public class SpecParser {
136 private static ArrayList<String> _content;
137 private static File _file;
138 private static ArrayList<Construct> _constructs;
141 public static void main(String[] argvs)
142 throws ParseException, TokenMgrError {
144 File f = new File("./grammer/spec.txt");
145 FileInputStream fis = new FileInputStream(f);
146 SpecParser parser = new SpecParser(fis);
148 ArrayList<String> content = new ArrayList<String>();
149 ArrayList<Construct> constructs = new ArrayList<Construct>();
150 ArrayList<String> headers = new ArrayList<String>();
151 parser.Parse(f, content, constructs, headers);
152 for (int i = 0; i < content.size(); i++) {
153 System.out.println(content.get(i));
156 for (int i = 0; i < constructs.size(); i++) {
157 System.out.println(constructs.get(i));
162 System.out.println("Parsing finished!");
163 } catch (FileNotFoundException e) {
168 public static SourceFileInfo ParseFile(File f)
169 throws ParseException, TokenMgrError {
171 InputStream input = new FileInputStream(f);
172 SpecParser parser = new SpecParser(input);
173 ArrayList<String> content = new ArrayList<String>(),
174 headers = new ArrayList<String>();
175 ArrayList<Construct> constructs = new ArrayList<Construct>();
176 parser.Parse(f, content, constructs, headers);
177 return new SourceFileInfo(f, content, headers, constructs);
178 } catch (FileNotFoundException e) {
184 public static ArrayList<VariableDeclaration> getTemplateArg(String line)
185 throws ParseException {
186 InputStream input = new ByteArrayInputStream(line.getBytes());
187 SpecParser parser = new SpecParser(input);
188 return parser.TemplateParamList();
191 public static FunctionHeader parseFuncHeader(String line)
192 throws ParseException {
193 InputStream input = new ByteArrayInputStream(line.getBytes());
194 SpecParser parser = new SpecParser(input);
195 return parser.FuncDecl();
199 public static String stringArray2String(ArrayList<String> content) {
200 StringBuilder sb = new StringBuilder();
201 if (content.size() == 1)
202 return content.get(0);
203 for (int i = 0; i < content.size(); i++) {
204 sb.append(content.get(i) + "\n");
206 return sb.toString();
210 boolean spaceSeparator(Token t) {
259 PARSER_END(SpecParser)
277 "/**" : IN_POTENTIAL_SPEC
280 <IN_POTENTIAL_SPEC> TOKEN : {
281 <BEGIN: "@Begin"> : IN_SPEC
293 // "//" comment for the specification
294 <"//" (~["\n", "\r"])* (["\n", "\r"])>
297 <IN_COMMENT, IN_POTENTIAL_SPEC> SKIP : {
301 <IN_COMMENT, IN_POTENTIAL_SPEC> SKIP : { < ~[] > }
305 // "#" comment for the specification
306 <"#" (~["\n", "\r"])* (["\n", "\r"])>
313 <OPTIONS: "@Options:">
315 <GLOBAL_DEFINE: "@Global_define:">
317 <DECLARE_STRUCT: "@DeclareStruct:">
319 <DECLARE_VAR: "@DeclareVar:">
321 <INIT_VAR: "@InitVar:">
323 <DEFINE_FUNC: "@DefineFunc:">
325 <INTERFACE_CLUSTER: "@Interface_cluster:">
327 <HAPPENS_BEFORE: "@Happens_before:">
329 <INTERFACE: "@Interface:">
331 <COMMIT_POINT_SET: "@Commit_point_set:">
333 <ENTRY_POINT: "@Entry_point">
335 <CLASS_BEGIN: "@Class_begin">
337 <CLASS_END: "@Class_end">
339 <INTERFACE_DEFINE: "@Interface_define:">
341 <CONDITION: "@Condition:">
343 <HB_CONDITION: "@HB_condition:">
353 <POST_ACTION: "@Post_action:">
355 <POST_CHECK: "@Post_check:">
357 <POTENTIAL_COMMIT_POINT_DEFINE: "@Potential_commit_point_define:">
361 <COMMIT_POINT_DEFINE_CHECK: "@Commit_point_define_check:">
363 <COMMIT_POINT_DEFINE: "@Commit_point_define:">
365 <POTENTIAL_COMMIT_POINT_LABEL: "@Potential_commit_point_label:">
369 <IN_SPEC, DEFAULT> TOKEN :
371 /* Specification & C/C++ shared tokens */
379 <UNSIGNED: "unsigned">
381 <TEMPLATE: "template">
391 <#LETTER: ["a"-"z", "A"-"Z"]>
393 <IDENTIFIER: (<LETTER> | "_") (<LETTER> | <DIGIT> | "_")*>
415 /* C/C++ only token*/
448 <GREATER_EQUALS: ">=">
452 <LOGICAL_EQUALS: "==">
468 <DOUBLELESSTHAN: "<<">
470 <DOUBLEGREATERTHAN: ">>">
472 <TRIPLEGREATERTHAN: ">>>">
480 <DIVIDE_EQUALS: "/=">
494 ((~["\"","\\","\n","\r"])
496 ( ["n","t","b","r","f","\\","'","\""]
497 | ["0"-"7"] ( ["0"-"7"] )?
498 | ["0"-"3"] ["0"-"7"]
507 ((~["'","\\","\n","\r"])
509 (["n","t","b","r","f","\\","'","\""]
510 | ["0"-"7"] ( ["0"-"7"] )?
511 | ["0"-"3"] ["0"-"7"]
519 <DECIMAL_LITERAL> (["l","L"])?
520 | <HEX_LITERAL> (["l","L"])?
521 | <OCTAL_LITERAL> (["l","L"])?>
523 < #DECIMAL_LITERAL: ["1"-"9"] (["0"-"9"])* >
525 < #HEX_LITERAL: "0" ["x","X"] (["0"-"9","a"-"f","A"-"F"])+ >
527 < #OCTAL_LITERAL: "0" (["0"-"7"])* >
529 < FLOATING_POINT_LITERAL:
530 <DECIMAL_FLOATING_POINT_LITERAL>
531 | <HEXADECIMAL_FLOATING_POINT_LITERAL> >
533 < #DECIMAL_FLOATING_POINT_LITERAL:
534 (["0"-"9"])+ "." (["0"-"9"])* (<DECIMAL_EXPONENT>)? (["f","F","d","D"])?
535 | "." (["0"-"9"])+ (<DECIMAL_EXPONENT>)? (["f","F","d","D"])?
536 | (["0"-"9"])+ <DECIMAL_EXPONENT> (["f","F","d","D"])?
537 | (["0"-"9"])+ (<DECIMAL_EXPONENT>)? ["f","F","d","D"]>
539 < #DECIMAL_EXPONENT: ["e","E"] (["+","-"])? (["0"-"9"])+ >
541 < #HEXADECIMAL_FLOATING_POINT_LITERAL:
542 "0" ["x", "X"] (["0"-"9","a"-"f","A"-"F"])+ (".")? <HEXADECIMAL_EXPONENT> (["f","F","d","D"])?
543 | "0" ["x", "X"] (["0"-"9","a"-"f","A"-"F"])* "." (["0"-"9","a"-"f","A"-"F"])+ <HEXADECIMAL_EXPONENT> (["f","F","d","D"])?>
545 < #HEXADECIMAL_EXPONENT: ["p","P"] (["+","-"])? (["0"-"9"])+ >
547 < #SPACE: (" " | "\t")+>
549 < #TO_END_OF_LINE: (~["\n"])+>
552 <INCLUDE: "#" (<SPACE>)? "include" <SPACE> (<STRING_LITERAL> | "<" (<LETTER> | <DOT>)+ ">")>
554 <DEFINE: "#" (<SPACE>)? <TO_END_OF_LINE>>
568 (((str = <STRUCT>.image | str = <CLASS>.image | str = <UNSIGNED>.image) { type = type + " " + str; })?
570 name = ParseQualifiedName() {
571 if (!type.equals(""))
572 type = type + " " + name.fullName;
574 type = name.fullName;
577 ((str = "const".image {
578 if (!type.equals(""))
579 type = type + " " + str;
583 (str = <STAR>.image {
584 if (!type.equals(""))
585 type = type + " " + str;
590 if (!type.equals(""))
591 type = type + " " + str;
610 System.out.println(str);
615 System.out.println(func);
620 String ParameterizedName() :
626 (str = <IDENTIFIER>.image {res = str;})
627 ("<" str = Type() { res = res + "<" + str; }
628 ("," str = Type() { res = res + ", " + str; })* ">"
636 FunctionHeader FuncDecl() :
639 QualifiedName funcName;
640 ArrayList<VariableDeclaration> args;
643 (<STATIC> | <INLINE>)*
645 funcName = ParseQualifiedName()
646 args = FormalParamList()
648 FunctionHeader res = new FunctionHeader(ret, funcName, args);
649 //System.out.println(res);
654 QualifiedName ParseQualifiedName() :
656 String qualifiedName, str;
659 { qualifiedName = ""; }
660 (str = ParameterizedName() { qualifiedName = qualifiedName + str; } )
661 ( <DOUBLECOLON> (str = ParameterizedName() { qualifiedName = qualifiedName +
664 QualifiedName res = new QualifiedName(qualifiedName);
665 //System.out.println(res);
670 ArrayList<VariableDeclaration> TemplateParamList() :
672 ArrayList<VariableDeclaration> params;
678 params = new ArrayList<VariableDeclaration>();
682 (type = <IDENTIFIER>.image
683 name = <IDENTIFIER>.image
685 params.add(new VariableDeclaration(type, name));
689 ("," type = <IDENTIFIER>.image
690 name = <IDENTIFIER>.image
692 params.add(new VariableDeclaration(type, name));
697 //System.out.println(params);
702 ArrayList<VariableDeclaration > FormalParamList() :
704 ArrayList<VariableDeclaration > typeParams;
705 VariableDeclaration varDecl;
709 typeParams = new ArrayList<VariableDeclaration >();
712 ((varDecl = TypeParam() {typeParams.add(varDecl);})
713 ((<COMMA> varDecl = TypeParam() {typeParams.add(varDecl);}))*)?
720 VariableDeclaration TypeParam() :
725 (type = Type()) (param = <IDENTIFIER>.image)
727 return new VariableDeclaration(type, param);
733 ArrayList<String> C_CPP_CODE(ArrayList<String> headers) :
737 boolean newLine = false;
738 boolean newSpace = true;
739 boolean inTemplate = false;
740 boolean inForLoop = false;
741 ArrayList<String> content;
748 content = new ArrayList<String>();
753 t = <CONST> | t = <STRUCT> | t = <CLASS> | t = <UNSIGNED> |
754 (t = <TEMPLATE> { inTemplate = true; })|
755 t = <STATIC> | t = <INLINE> |
756 (t = <FOR> { inForLoop = true; })|
761 if (headers != null) {
762 headers.add(header.substring(header.lastIndexOf(' ') + 1));
765 | t = <IDENTIFIER> | t = <POUND> |
766 (t = <OPEN_BRACE> { newLine = true; } ) |
767 (t = <CLOSE_BRACE> { newLine = true; inForLoop = false;} ) |
768 t = <EQUALS> | t = <OPEN_PAREN> | t = <CLOSE_PAREN> |
769 t = <OPEN_BRACKET> | t = <CLOSE_BRACKET>
770 | t = <HB_SYMBOL> | t = <COMMA> |
771 t = <DOT> | t = <STAR> | t = <DOLLAR> | t = <NEGATE> | t = <EXCLAMATION> | t = <AND> | t = <OR> | t = <MOD> | t = <PLUS> |
772 t = <PLUSPLUS> | t = <MINUS> | t = <MINUSMINUS> | t = <DIVIDE> | t = <BACKSLASH> |
774 (t = <GREATER_THAN> { if (inTemplate) newLine = true; }) |
775 t = <GREATER_EQUALS> | t = <LESS_EQUALS> |
776 t = <LOGICAL_EQUALS> | t = <NOT_EQUALS> | t = <LOGICAL_AND> | t = <LOGICAL_OR> | t = <XOR> |
777 t = <QUESTION_MARK> | t = <COLON> | t = <DOUBLECOLON> |
778 t = <DOUBLELESSTHAN> |
779 t = <DOUBLEGREATERTHAN> |
780 t = <TRIPLEGREATERTHAN> |
785 t = <DIVIDE_EQUALS> |
791 (t = <SEMI_COLON> { if (!inForLoop) newLine = true; } )
792 | t = <STRING_LITERAL> | t = <CHARACTER_LITERAL> |
793 t = <INTEGER_LITERAL> | t = <FLOATING_POINT_LITERAL> |
794 (t = <DEFINE> { newLine = true; } )
797 if (text.equals("")) {
801 text = text + " " + t.image;
803 if (newSpace && spaceSeparator(t)) {
804 text = text + " " + t.image;
806 text = text + t.image;
807 if (spaceSeparator(t))
821 if (content.size() == 0) {
829 void Parse(File f, ArrayList<String> content, ArrayList<Construct> constructs, ArrayList<String> headers) :
832 ArrayList<String> code;
838 _constructs = constructs;
840 ((inst = ParseSpec() { _constructs.add(inst); }) |
841 ((code = C_CPP_CODE(headers)) { _content.addAll(code); })
845 Construct ParseSpec() :
851 LOOKAHEAD(2) res = Global_construct() |
852 LOOKAHEAD(2) res = Interface() |
853 LOOKAHEAD(2) res = Potential_commit_point_define() |
854 LOOKAHEAD(2) res = Commit_point_define() |
855 LOOKAHEAD(2) res = Commit_point_define_check() |
856 LOOKAHEAD(2) res = Entry_point() |
857 LOOKAHEAD(2) res = Class_begin() |
858 LOOKAHEAD(2) res = Class_end() |
859 LOOKAHEAD(2) res = Interface_define()
862 //System.out.println(res);
867 GlobalConstruct Global_construct() :
870 SequentialDefineSubConstruct code;
871 HashMap<String, String> options;
877 options = new HashMap<String, String>();
881 ((key = <IDENTIFIER>.image)
883 (value = <IDENTIFIER>.image)
885 if (options.containsKey(key)) {
886 throw new ParseException("Duplicate options!");
888 options.put(key, value);
893 (code = Global_define())
894 { res = new GlobalConstruct(_file, _content.size(), code, options); }
895 (Interface_clusters(res))?
896 (Happens_before(res))?
899 res.unfoldInterfaceCluster();
904 SequentialDefineSubConstruct Global_define() :
906 ArrayList<String> initVar, defineFunc, code, declareStruct;
907 ArrayList<ArrayList<String>> defineFuncs;
908 ArrayList<VariableDeclaration> declareVars;
909 ArrayList<ArrayList<String>> declareStructs;
910 VariableDeclaration declareVar;
915 declareVars = new ArrayList<VariableDeclaration>();
917 defineFuncs = new ArrayList<ArrayList<String>>();
918 declareStructs = new ArrayList<ArrayList<String>>();
921 (<DECLARE_STRUCT> (declareStruct = C_CPP_CODE(null) {
922 declareStructs.add(declareStruct); }))*
923 (<DECLARE_VAR> ((declareVar = TypeParam() ";" {
924 declareVars.add(declareVar); } )*))?
925 (<INIT_VAR> (code = C_CPP_CODE(null) { initVar = code; } ))?
926 (<DEFINE_FUNC> (defineFunc = C_CPP_CODE(null) { defineFuncs.add(defineFunc); }))*
928 SequentialDefineSubConstruct res = new
929 SequentialDefineSubConstruct(declareStructs, declareVars, initVar, defineFuncs);
930 //System.out.println(res);
935 ConditionalInterface Conditional_interface() :
937 String interfaceName, hbConditionLabel;
941 hbConditionLabel = "";
943 interfaceName = <IDENTIFIER>.image (<OPEN_PAREN> hbConditionLabel =
944 <IDENTIFIER>.image <CLOSE_PAREN>)?
946 return new ConditionalInterface(interfaceName, hbConditionLabel);
950 void Interface_cluster(GlobalConstruct inst) :
953 ConditionalInterface condInterface;
956 (clusterName= <IDENTIFIER>.image)
957 <EQUALS> <OPEN_BRACE>
958 (condInterface = Conditional_interface()
959 { inst.addInterface2Cluster(clusterName, condInterface); }
961 (<COMMA> condInterface = Conditional_interface()
962 { inst.addInterface2Cluster(clusterName, condInterface); }
967 void Interface_clusters(GlobalConstruct inst) :
970 <INTERFACE_CLUSTER> (Interface_cluster(inst))+
973 void Happens_before(GlobalConstruct inst) :
975 ConditionalInterface left, right;
980 left = Conditional_interface() <HB_SYMBOL> right = Conditional_interface()
981 { inst.addHBCondition(left, right); }
985 InterfaceConstruct Interface() :
987 InterfaceConstruct res;
988 String interfaceName, condition, idCode, check,
989 postCheck, commitPoint, hbLabel, hbCondition;
990 ArrayList<String> commitPointSet;
991 ArrayList<String> action, postAction;
992 HashMap<String, String> hbConditions;
993 ArrayList<String> content;
998 action = new ArrayList<String>();
1003 commitPointSet = new ArrayList<String>();
1004 hbConditions = new HashMap<String, String>();
1005 postAction = new ArrayList<String>();
1008 <INTERFACE> (interfaceName = <IDENTIFIER>.image)
1010 (commitPoint = <IDENTIFIER>.image
1011 { commitPointSet.add(commitPoint); }
1014 (commitPoint = <IDENTIFIER>.image)
1016 if (commitPointSet.contains(commitPoint)) {
1017 throw new ParseException(interfaceName + " has" +
1018 "duplicate commit point labels");
1020 commitPointSet.add(commitPoint);
1024 (<CONDITION> (content = C_CPP_CODE(null) { condition = stringArray2String(content); }))?
1027 (hbLabel = <IDENTIFIER>.image) <DOUBLECOLON>
1028 (content = C_CPP_CODE(null) { hbCondition = stringArray2String(content); })
1030 if (hbConditions.containsKey(hbLabel)) {
1031 throw new ParseException(interfaceName + " has" +
1032 "duplicate happens-before condtion labels");
1034 hbConditions.put(hbLabel, hbCondition);
1037 (<ID> (content = C_CPP_CODE(null) { idCode = stringArray2String(content); }))?
1038 (<CHECK> (content = C_CPP_CODE(null) { check = stringArray2String(content); }))?
1039 (<ACTION> action = C_CPP_CODE(null))?
1040 (<POST_ACTION> (postAction = C_CPP_CODE(null) ))?
1041 (<POST_CHECK> (content = C_CPP_CODE(null) { postCheck = stringArray2String(content); }))?
1044 res = new InterfaceConstruct(_file, _content.size(), interfaceName, commitPointSet, condition,
1045 hbConditions, idCode, check, action, postAction, postCheck);
1051 PotentialCPDefineConstruct Potential_commit_point_define() :
1053 PotentialCPDefineConstruct res;
1054 String label, condition;
1055 ArrayList<String> content;
1061 <POTENTIAL_COMMIT_POINT_DEFINE> (content = C_CPP_CODE(null) { condition = stringArray2String(content); })
1062 <LABEL> (label = <IDENTIFIER>.image)
1065 res = new PotentialCPDefineConstruct(_file, _content.size(), label, condition);
1071 CPDefineConstruct Commit_point_define() :
1073 CPDefineConstruct res;
1074 String label, potentialCPLabel, condition;
1075 ArrayList<String> content;
1081 <COMMIT_POINT_DEFINE> (content = C_CPP_CODE(null) { condition = stringArray2String(content); })
1082 <POTENTIAL_COMMIT_POINT_LABEL> (potentialCPLabel = <IDENTIFIER>.image)
1083 <LABEL> (label = <IDENTIFIER>.image)
1086 res = new CPDefineConstruct(_file, _content.size(), label, potentialCPLabel, condition);
1092 CPDefineCheckConstruct Commit_point_define_check() :
1094 CPDefineCheckConstruct res;
1095 String label, condition;
1096 ArrayList<String> content;
1102 <COMMIT_POINT_DEFINE_CHECK> (content = C_CPP_CODE(null) { condition = stringArray2String(content); })
1103 <LABEL> (label = <IDENTIFIER>.image)
1106 res = new CPDefineCheckConstruct(_file, _content.size(), label, condition);
1111 EntryPointConstruct Entry_point() :
1119 return new EntryPointConstruct(_file, _content.size());
1123 ClassBeginConstruct Class_begin() :
1131 return new ClassBeginConstruct(_file, _content.size());
1135 ClassEndConstruct Class_end() :
1143 return new ClassEndConstruct(_file, _content.size());
1147 InterfaceDefineConstruct Interface_define() :
1153 <INTERFACE_DEFINE> (name = <IDENTIFIER>.image)
1156 return new InterfaceDefineConstruct(_file, _content.size(), name);