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
29 b) Interface construct
33 IDENTIFIER | IDENTIFIER ...
34 @Condition: ... (Optional)
36 IDENTIFIER :: <C_CPP_Condition>
38 @ID: ... (Optional, use default ID)
43 @Post_action: (Optional)
44 @Post_check: (Optional)
47 c) Potential commit construct
49 @Potential_commit_point_define: ...
53 d) Commit point define construct
55 @Commit_point_define_check: ...
62 @Commit_point_define: ...
63 @Potential_commit_point_label: ...
67 e) Entry point construct
72 f) Interface define construct
74 @Interface_define: <Interface_Name>
82 JAVA_UNICODE_ESCAPE = true;
85 PARSER_BEGIN(SpecParser)
86 package edu.uci.eecs.specCompiler.grammerParser;
88 import java.io.FileInputStream;
89 import java.io.FileNotFoundException;
90 import java.io.InputStream;
91 import java.io.ByteArrayInputStream;
93 import java.util.ArrayList;
94 import java.util.HashMap;
95 import java.util.HashSet;
97 import edu.uci.eecs.specCompiler.specExtraction.Construct;
98 import edu.uci.eecs.specCompiler.specExtraction.GlobalConstruct;
99 import edu.uci.eecs.specCompiler.specExtraction.InterfaceConstruct;
100 import edu.uci.eecs.specCompiler.specExtraction.PotentialCPDefineConstruct;
101 import edu.uci.eecs.specCompiler.specExtraction.CPDefineConstruct;
102 import edu.uci.eecs.specCompiler.specExtraction.CPDefineCheckConstruct;
103 import edu.uci.eecs.specCompiler.specExtraction.ConditionalInterface;
104 import edu.uci.eecs.specCompiler.specExtraction.SequentialDefineSubConstruct;
105 import edu.uci.eecs.specCompiler.specExtraction.InterfaceDefineConstruct;
106 import edu.uci.eecs.specCompiler.specExtraction.EntryPointConstruct;
107 import edu.uci.eecs.specCompiler.specExtraction.ClassBeginConstruct;
108 import edu.uci.eecs.specCompiler.specExtraction.ClassEndConstruct;
109 import edu.uci.eecs.specCompiler.specExtraction.FunctionHeader;
110 import edu.uci.eecs.specCompiler.specExtraction.QualifiedName;
111 import edu.uci.eecs.specCompiler.specExtraction.SourceFileInfo;
112 import edu.uci.eecs.specCompiler.specExtraction.VariableDeclaration;
114 public class SpecParser {
115 private static ArrayList<String> _content;
116 private static File _file;
117 private static ArrayList<Construct> _constructs;
120 public static void main(String[] argvs)
121 throws ParseException, TokenMgrError {
123 File f = new File("./grammer/spec.txt");
124 FileInputStream fis = new FileInputStream(f);
125 SpecParser parser = new SpecParser(fis);
127 ArrayList<String> content = new ArrayList<String>();
128 ArrayList<Construct> constructs = new ArrayList<Construct>();
129 ArrayList<String> headers = new ArrayList<String>();
130 parser.Parse(f, content, constructs, headers);
131 for (int i = 0; i < content.size(); i++) {
132 System.out.println(content.get(i));
135 for (int i = 0; i < constructs.size(); i++) {
136 System.out.println(constructs.get(i));
140 System.out.println("Parsing finished!");
141 } catch (FileNotFoundException e) {
146 public static SourceFileInfo ParseFile(File f)
147 throws ParseException, TokenMgrError {
149 InputStream input = new FileInputStream(f);
150 SpecParser parser = new SpecParser(input);
151 ArrayList<String> content = new ArrayList<String>(),
152 headers = new ArrayList<String>();
153 ArrayList<Construct> constructs = new ArrayList<Construct>();
154 parser.Parse(f, content, constructs, headers);
155 return new SourceFileInfo(f, content, headers, constructs);
156 } catch (FileNotFoundException e) {
162 public static ArrayList<String> getTemplateArg(String line)
163 throws ParseException {
164 InputStream input = new ByteArrayInputStream(line.getBytes());
165 SpecParser parser = new SpecParser(input);
166 return parser.TemplateParamList();
169 public static FunctionHeader parseFuncHeader(String line)
170 throws ParseException {
171 InputStream input = new ByteArrayInputStream(line.getBytes());
172 SpecParser parser = new SpecParser(input);
173 return parser.FuncDecl();
177 public static String stringArray2String(ArrayList<String> content) {
178 StringBuilder sb = new StringBuilder();
179 for (int i = 0; i < content.size(); i++) {
180 sb.append(content.get(i) + "\n");
182 return sb.toString();
186 PARSER_END(SpecParser)
204 "/**" : IN_POTENTIAL_SPEC
207 <IN_POTENTIAL_SPEC> TOKEN : {
208 <BEGIN: "@Begin"> : IN_SPEC
220 // "//" comment for the specification
221 <"//" (~["\n", "\r"])* (["\n", "\r"])>
224 <IN_COMMENT, IN_POTENTIAL_SPEC> SKIP : {
228 <IN_COMMENT, IN_POTENTIAL_SPEC> SKIP : { < ~[] > }
232 // "#" comment for the specification
233 <"#" (~["\n", "\r"])* (["\n", "\r"])>
240 <OPTIONS: "@Options:">
242 <GLOBAL_DEFINE: "@Global_define:">
244 <DECLARE_VAR: "@DeclareVar:">
246 <INIT_VAR: "@InitVar:">
248 <DEFINE_FUNC: "@DefineFunc:">
250 <INTERFACE_CLUSTER: "@Interface_cluster:">
252 <HAPPENS_BEFORE: "@Happens_before:">
254 <INTERFACE: "@Interface:">
256 <COMMIT_POINT_SET: "@Commit_point_set:">
258 <ENTRY_POINT: "@Entry_point">
260 <CLASS_BEGIN: "@Class_begin">
262 <CLASS_END: "@Class_end">
264 <INTERFACE_DEFINE: "@Interface_define:">
266 <CONDITION: "@Condition:">
268 <HB_CONDITION: "@HB_condition:">
278 <POST_ACTION: "@Post_action:">
280 <POST_CHECK: "@Post_check:">
282 <POTENTIAL_COMMIT_POINT_DEFINE: "@Potential_commit_point_define:">
286 <COMMIT_POINT_DEFINE_CHECK: "@Commit_point_define_check:">
288 <COMMIT_POINT_DEFINE: "@Commit_point_define:">
290 <POTENTIAL_COMMIT_POINT_LABEL: "@Potential_commit_point_label:">
294 <IN_SPEC, DEFAULT> TOKEN :
296 /* Specification & C/C++ shared tokens */
304 <TEMPLATE: "template">
308 <#LETTER: ["a"-"z", "A"-"Z"]>
310 <IDENTIFIER: (<LETTER> | "_") (<LETTER> | <DIGIT> | "_")*>
332 /* C/C++ only token*/
363 <GREATER_EQUALS: ">=">
367 <LOGICAL_EQUALS: "==">
387 ((~["\"","\\","\n","\r"])
389 ( ["n","t","b","r","f","\\","'","\""]
390 | ["0"-"7"] ( ["0"-"7"] )?
391 | ["0"-"3"] ["0"-"7"]
400 ((~["'","\\","\n","\r"])
402 (["n","t","b","r","f","\\","'","\""]
403 | ["0"-"7"] ( ["0"-"7"] )?
404 | ["0"-"3"] ["0"-"7"]
412 <DECIMAL_LITERAL> (["l","L"])?
413 | <HEX_LITERAL> (["l","L"])?
414 | <OCTAL_LITERAL> (["l","L"])?>
416 < #DECIMAL_LITERAL: ["1"-"9"] (["0"-"9"])* >
418 < #HEX_LITERAL: "0" ["x","X"] (["0"-"9","a"-"f","A"-"F"])+ >
420 < #OCTAL_LITERAL: "0" (["0"-"7"])* >
422 < FLOATING_POINT_LITERAL:
423 <DECIMAL_FLOATING_POINT_LITERAL>
424 | <HEXADECIMAL_FLOATING_POINT_LITERAL> >
426 < #DECIMAL_FLOATING_POINT_LITERAL:
427 (["0"-"9"])+ "." (["0"-"9"])* (<DECIMAL_EXPONENT>)? (["f","F","d","D"])?
428 | "." (["0"-"9"])+ (<DECIMAL_EXPONENT>)? (["f","F","d","D"])?
429 | (["0"-"9"])+ <DECIMAL_EXPONENT> (["f","F","d","D"])?
430 | (["0"-"9"])+ (<DECIMAL_EXPONENT>)? ["f","F","d","D"]>
432 < #DECIMAL_EXPONENT: ["e","E"] (["+","-"])? (["0"-"9"])+ >
434 < #HEXADECIMAL_FLOATING_POINT_LITERAL:
435 "0" ["x", "X"] (["0"-"9","a"-"f","A"-"F"])+ (".")? <HEXADECIMAL_EXPONENT> (["f","F","d","D"])?
436 | "0" ["x", "X"] (["0"-"9","a"-"f","A"-"F"])* "." (["0"-"9","a"-"f","A"-"F"])+ <HEXADECIMAL_EXPONENT> (["f","F","d","D"])?>
438 < #HEXADECIMAL_EXPONENT: ["p","P"] (["+","-"])? (["0"-"9"])+ >
440 < #SPACE: (" " | "\t")+>
442 < #TO_END_OF_LINE: (~["\n"])+>
445 <INCLUDE: "#" (<SPACE>)? "include" <SPACE> (<STRING_LITERAL> | "<" (<LETTER> | <DOT>)+ ">")>
447 <DEFINE: "#" (<SPACE>)? <TO_END_OF_LINE>>
461 (((str = <STRUCT>.image | str = <CLASS>.image) { type = type + " " + str; })?
463 name = ParseQualifiedName() {
464 if (!type.equals(""))
465 type = type + " " + name.fullName;
467 type = name.fullName;
470 ((str = "const".image {
471 if (!type.equals(""))
472 type = type + " " + str;
476 (str = <STAR>.image {
477 if (!type.equals(""))
478 type = type + " " + str;
483 if (!type.equals(""))
484 type = type + " " + str;
503 System.out.println(str);
508 System.out.println(func);
512 String ParameterizedName() :
518 (str = <IDENTIFIER>.image {res = str;})
519 ("<" str = <IDENTIFIER>.image { res = res + "<" + str; }
520 ("," str = <IDENTIFIER>.image { res = res + ", " + str; })* ">"
528 FunctionHeader FuncDecl() :
531 QualifiedName funcName;
532 ArrayList<VariableDeclaration> args;
536 funcName = ParseQualifiedName()
537 args = FormalParamList()
539 FunctionHeader res = new FunctionHeader(ret, funcName, args);
540 //System.out.println(res);
545 QualifiedName ParseQualifiedName() :
547 String qualifiedName, str;
550 { qualifiedName = ""; }
551 (str = ParameterizedName() { qualifiedName = qualifiedName + str; } )
552 ( <DOUBLECOLON> (str = ParameterizedName() { qualifiedName = qualifiedName +
555 QualifiedName res = new QualifiedName(qualifiedName);
556 //System.out.println(res);
561 ArrayList<String> TemplateParamList() :
563 ArrayList<String> params;
568 params = new ArrayList<String>();
572 (str = <IDENTIFIER>.image
573 str = <IDENTIFIER>.image {params.add(str);})
575 ("," str = <IDENTIFIER>.image
576 str = <IDENTIFIER>.image {params.add(str);})*
579 //System.out.println(params);
584 ArrayList<VariableDeclaration > FormalParamList() :
586 ArrayList<VariableDeclaration > typeParams;
587 VariableDeclaration varDecl;
591 typeParams = new ArrayList<VariableDeclaration >();
594 ((varDecl = TypeParam() {typeParams.add(varDecl);})
595 ((<COMMA> varDecl = TypeParam() {typeParams.add(varDecl);}))*)?
602 VariableDeclaration TypeParam() :
607 (type = Type()) (param = <IDENTIFIER>.image)
609 return new VariableDeclaration(type, param);
613 ArrayList<String> C_CPP_CODE(ArrayList<String> headers) :
617 boolean newLine = false;
618 boolean inTemplate = false;
619 ArrayList<String> content;
626 content = new ArrayList<String>();
631 t = <CONST> | t = <STRUCT> | t = <CLASS> |
632 (t = <TEMPLATE> { inTemplate = true; })|
633 (header = <INCLUDE>.image {
634 if (headers != null) {
635 headers.add(header.substring(header.lastIndexOf(' ') + 1));
638 | t = <IDENTIFIER> | t = <POUND> |
639 (t = <OPEN_BRACE> { newLine = true; } ) |
640 (t = <CLOSE_BRACE> { newLine = true; } ) |
641 t = <EQUALS> | t = <OPEN_PAREN> | t = <CLOSE_PAREN> |
642 t = <OPEN_BRACKET> | t = <CLOSE_BRACKET>
643 | t = <HB_SYMBOL> | t = <COMMA> |
644 t = <DOT> | t = <STAR> | t = <NEGATE> | t = <EXCLAMATION> | t = <AND> | t = <OR> | t = <MOD> | t = <PLUS> |
645 t = <PLUSPLUS> | t = <MINUS> | t = <MINUSMINUS> | t = <DIVIDE> | t = <BACKSLASH> |
647 (t = <GREATER_THAN> { if (inTemplate) newLine = true; }) |
648 t = <GREATER_EQUALS> | t = <LESS_EQUALS> |
649 t = <LOGICAL_EQUALS> | t = <NOT_EQUALS> | t = <LOGICAL_AND> | t = <LOGICAL_OR> | t = <XOR> |
650 t = <QUESTION_MARK> | t = <COLON> | t = <DOUBLECOLON> |
651 (t = <SEMI_COLON> { newLine = true; } )
652 | t = <STRING_LITERAL> | t = <CHARACTER_LITERAL> |
653 t = <INTEGER_LITERAL> | t = <FLOATING_POINT_LITERAL> |
654 (t = <DEFINE> { newLine = true; } )
657 text = text + " " + t.image;
672 void Parse(File f, ArrayList<String> content, ArrayList<Construct> constructs, ArrayList<String> headers) :
675 ArrayList<String> code;
681 _constructs = constructs;
683 ((inst = ParseSpec() { _constructs.add(inst); }) |
684 ((code = C_CPP_CODE(headers)) { _content.addAll(code); })
688 Construct ParseSpec() :
694 LOOKAHEAD(2) res = Global_construct() |
695 LOOKAHEAD(2) res = Interface() |
696 LOOKAHEAD(2) res = Potential_commit_point_define() |
697 LOOKAHEAD(2) res = Commit_point_define() |
698 LOOKAHEAD(2) res = Commit_point_define_check() |
699 LOOKAHEAD(2) res = Entry_point() |
700 LOOKAHEAD(2) res = Class_begin() |
701 LOOKAHEAD(2) res = Class_end() |
702 LOOKAHEAD(2) res = Interface_define()
705 //System.out.println(res);
710 GlobalConstruct Global_construct() :
713 SequentialDefineSubConstruct code;
714 HashMap<String, String> options;
720 options = new HashMap<String, String>();
724 ((key = <IDENTIFIER>.image)
726 (value = <IDENTIFIER>.image)
728 if (options.containsKey(key)) {
729 throw new ParseException("Duplicate options!");
731 options.put(key, value);
736 (code = Global_define())
737 { res = new GlobalConstruct(_file, _content.size(), code, options); }
738 (Interface_clusters(res))?
739 (Happens_before(res))?
742 res.unfoldInterfaceCluster();
747 SequentialDefineSubConstruct Global_define() :
749 ArrayList<String> initVar, defineFunc, code;
750 ArrayList<VariableDeclaration> declareVars;
751 VariableDeclaration declareVar;
761 (<DECLARE_VAR> ((declareVar = TypeParam() ";" {
762 declareVars.add(declareVar); } )*))?
763 (<INIT_VAR> (code = C_CPP_CODE(null) { initVar = code; } ))?
764 (<DEFINE_FUNC> (code = C_CPP_CODE(null) { defineFunc = code; }))?
766 SequentialDefineSubConstruct res = new
767 SequentialDefineSubConstruct(declareVars, initVar, defineFunc);
768 //System.out.println(res);
773 ConditionalInterface Conditional_interface() :
775 String interfaceName, hbConditionLabel;
779 hbConditionLabel = "";
781 interfaceName = <IDENTIFIER>.image (<OPEN_BRACKET> hbConditionLabel =
782 <IDENTIFIER>.image <CLOSE_BRACKET>)?
784 return new ConditionalInterface(interfaceName, hbConditionLabel);
788 void Interface_cluster(GlobalConstruct inst) :
791 ConditionalInterface condInterface;
794 (clusterName= <IDENTIFIER>.image)
795 <EQUALS> <OPEN_PAREN>
796 (condInterface = Conditional_interface()
797 { inst.addInterface2Cluster(clusterName, condInterface); }
799 (<COMMA> condInterface = Conditional_interface()
800 { inst.addInterface2Cluster(clusterName, condInterface); }
805 void Interface_clusters(GlobalConstruct inst) :
808 <INTERFACE_CLUSTER> (Interface_cluster(inst))+
811 void Happens_before(GlobalConstruct inst) :
813 ConditionalInterface left, right;
818 left = Conditional_interface() <HB_SYMBOL> right = Conditional_interface()
819 { inst.addHBCondition(left, right); }
823 InterfaceConstruct Interface() :
825 InterfaceConstruct res;
826 String interfaceName, condition, idCode, check,
827 postCheck, commitPoint, hbLabel, hbCondition;
828 ArrayList<String> commitPointSet;
829 ArrayList<String> action, postAction;
830 HashMap<String, String> hbConditions;
831 ArrayList<String> content;
841 commitPointSet = new ArrayList<String>();
842 hbConditions = new HashMap<String, String>();
848 <INTERFACE> (interfaceName = <IDENTIFIER>.image)
850 (commitPoint = <IDENTIFIER>.image
851 { commitPointSet.add(commitPoint); }
854 (commitPoint = <IDENTIFIER>.image)
856 if (commitPointSet.contains(commitPoint)) {
857 throw new ParseException(interfaceName + " has" +
858 "duplicate commit point labels");
860 commitPointSet.add(commitPoint);
864 (<CONDITION> (content = C_CPP_CODE(null) { condition = stringArray2String(content); }))?
867 (hbLabel = <IDENTIFIER>.image)
868 (content = C_CPP_CODE(null) { hbCondition = stringArray2String(content); })
870 if (hbConditions.containsKey(hbLabel)) {
871 throw new ParseException(interfaceName + " has" +
872 "duplicate happens-before condtion labels");
874 hbConditions.put(hbLabel, hbCondition);
877 (<ID> (content = C_CPP_CODE(null) { idCode = stringArray2String(content); }))?
878 (<CHECK> (content = C_CPP_CODE(null) { check = stringArray2String(content); }))?
879 (<ACTION> action = C_CPP_CODE(null))?
880 (<POST_ACTION> (postAction = C_CPP_CODE(null) ))?
881 (<POST_CHECK> (content = C_CPP_CODE(null) { postCheck = stringArray2String(content); }))?
884 res = new InterfaceConstruct(_file, _content.size(), interfaceName, commitPointSet, condition,
885 hbConditions, idCode, check, action, postAction, postCheck);
891 PotentialCPDefineConstruct Potential_commit_point_define() :
893 PotentialCPDefineConstruct res;
894 String label, condition;
895 ArrayList<String> content;
901 <POTENTIAL_COMMIT_POINT_DEFINE> (content = C_CPP_CODE(null) { condition = stringArray2String(content); })
902 <LABEL> (label = <IDENTIFIER>.image)
905 res = new PotentialCPDefineConstruct(_file, _content.size(), label, condition);
911 CPDefineConstruct Commit_point_define() :
913 CPDefineConstruct res;
914 String label, potentialCPLabel, condition;
915 ArrayList<String> content;
921 <COMMIT_POINT_DEFINE> (content = C_CPP_CODE(null) { condition = stringArray2String(content); })
922 <POTENTIAL_COMMIT_POINT_LABEL> (potentialCPLabel = <IDENTIFIER>.image)
923 <LABEL> (label = <IDENTIFIER>.image)
926 res = new CPDefineConstruct(_file, _content.size(), label, potentialCPLabel, condition);
932 CPDefineCheckConstruct Commit_point_define_check() :
934 CPDefineCheckConstruct res;
935 String label, condition;
936 ArrayList<String> content;
942 <COMMIT_POINT_DEFINE_CHECK> (content = C_CPP_CODE(null) { condition = stringArray2String(content); })
943 <LABEL> (label = <IDENTIFIER>.image)
946 res = new CPDefineCheckConstruct(_file, _content.size(), label, condition);
951 EntryPointConstruct Entry_point() :
959 return new EntryPointConstruct(_file, _content.size());
963 ClassBeginConstruct Class_begin() :
971 return new ClassBeginConstruct(_file, _content.size());
975 ClassEndConstruct Class_end() :
983 return new ClassEndConstruct(_file, _content.size());
987 InterfaceDefineConstruct Interface_define() :
993 <INTERFACE_DEFINE> (name = <IDENTIFIER>.image)
996 return new InterfaceDefineConstruct(_file, _content.size(), name);