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)
42 # Type here must be a pointer
43 @DefineVar: Type var1 = SomeExpression (Optional)
46 @Post_action: (Optional)
47 @Post_check: (Optional)
50 c) Potential commit construct
52 @Potential_commit_point_define: ...
56 d) Commit point define construct
58 @Commit_point_define_check: ...
65 @Commit_point_define: ...
66 @Potential_commit_point_label: ...
70 e) Entry point construct
75 f) Interface define construct
77 @Interface_define: <Interface_Name>
85 JAVA_UNICODE_ESCAPE = true;
88 PARSER_BEGIN(SpecParser)
89 package edu.uci.eecs.specCompiler.grammerParser;
91 import java.io.FileInputStream;
92 import java.io.FileNotFoundException;
93 import java.io.InputStream;
94 import java.io.ByteArrayInputStream;
96 import java.util.ArrayList;
97 import java.util.HashMap;
98 import java.util.HashSet;
100 import edu.uci.eecs.specCompiler.specExtraction.Construct;
101 import edu.uci.eecs.specCompiler.specExtraction.GlobalConstruct;
102 import edu.uci.eecs.specCompiler.specExtraction.InterfaceConstruct;
103 import edu.uci.eecs.specCompiler.specExtraction.PotentialCPDefineConstruct;
104 import edu.uci.eecs.specCompiler.specExtraction.CPDefineConstruct;
105 import edu.uci.eecs.specCompiler.specExtraction.CPDefineCheckConstruct;
106 import edu.uci.eecs.specCompiler.specExtraction.ConditionalInterface;
107 import edu.uci.eecs.specCompiler.specExtraction.ActionSubConstruct;
108 import edu.uci.eecs.specCompiler.specExtraction.ActionSubConstruct.DefineVar;
109 import edu.uci.eecs.specCompiler.specExtraction.SequentialDefineSubConstruct;
110 import edu.uci.eecs.specCompiler.specExtraction.InterfaceDefineConstruct;
111 import edu.uci.eecs.specCompiler.specExtraction.EntryPointConstruct;
113 public class SpecParser {
114 private static ArrayList<String> _content;
115 private static File _file;
116 private static ArrayList<Construct> _constructs;
118 public static void main(String[] argvs)
119 throws ParseException, TokenMgrError {
121 File f = new File("./grammer/spec.txt");
122 FileInputStream fis = new FileInputStream(f);
123 SpecParser parser = new SpecParser(fis);
124 ArrayList<String> content = new ArrayList<String>();
125 ArrayList<Construct> constructs = new ArrayList<Construct>();
126 parser.Parse(f, content, constructs);
127 System.out.println("Parsing finished!");
128 } catch (FileNotFoundException e) {
133 public static void ParseFile(File f, ArrayList<String> content, ArrayList<Construct> constructs)
134 throws ParseException, TokenMgrError {
136 InputStream input = new FileInputStream(f);
137 SpecParser parser = new SpecParser(input);
138 parser.Parse(f, content, constructs);
139 } catch (FileNotFoundException e) {
144 public static String stringArray2String(ArrayList<String> content) {
145 StringBuilder sb = new StringBuilder();
146 for (int i = 0; i < content.size(); i++) {
147 sb.append(content.get(i) + "\n");
149 return sb.toString();
153 PARSER_END(SpecParser)
171 "/**" : IN_POTENTIAL_SPEC
174 <IN_POTENTIAL_SPEC> TOKEN : {
175 <BEGIN: "@Begin"> : IN_SPEC
187 // "//" comment for the specification
188 <"//" (~["\n", "\r"])* (["\n", "\r"])>
191 <IN_COMMENT, IN_POTENTIAL_SPEC> SKIP : {
195 <IN_COMMENT, IN_POTENTIAL_SPEC> SKIP : { < ~[] > }
199 // "#" comment for the specification
200 <"#" (~["\n", "\r"])* (["\n", "\r"])>
207 <OPTIONS: "@Options:">
209 <GLOBAL_DEFINE: "@Global_define:">
211 <DECLARE_VAR: "@DeclareVar:">
213 <INIT_VAR: "@InitVar:">
215 <DEFINE_FUNC: "@DefineFunc:">
217 <INTERFACE_CLUSTER: "@Interface_cluster:">
219 <HAPPENS_BEFORE: "@Happens_before:">
221 <INTERFACE: "@Interface:">
223 <COMMIT_POINT_SET: "@Commit_point_set:">
225 <ENTRY_POINT: "@Entry_point">
227 <INTERFACE_DEFINE: "@Interface_define:">
229 <CONDITION: "@Condition:">
231 <HB_CONDITION: "@HB_condition:">
239 <DEFINEVAR: "@DefineVar:">
243 <POST_ACTION: "@Post_action:">
245 <POST_CHECK: "@Post_check:">
247 <POTENTIAL_COMMIT_POINT_DEFINE: "@Potential_commit_point_define:">
251 <COMMIT_POINT_DEFINE_CHECK: "@Commit_point_define_check:">
253 <COMMIT_POINT_DEFINE: "@Commit_point_define:">
255 <POTENTIAL_COMMIT_POINT_LABEL: "@Potential_commit_point_label:">
259 <IN_SPEC, DEFAULT> TOKEN :
261 /* Specification & C/C++ shared tokens */
267 <TYPENAME: "typename">
271 <#LETTER: ["a"-"z", "A"-"Z"]>
273 <IDENTIFIER: (<LETTER> | "_") (<LETTER> | <DIGIT> | "_")*>
296 /* C/C++ only token*/
327 <GREATER_EQUALS: ">=">
331 <LOGICAL_EQUALS: "==">
351 ((~["\"","\\","\n","\r"])
353 ( ["n","t","b","r","f","\\","'","\""]
354 | ["0"-"7"] ( ["0"-"7"] )?
355 | ["0"-"3"] ["0"-"7"]
364 ((~["'","\\","\n","\r"])
366 (["n","t","b","r","f","\\","'","\""]
367 | ["0"-"7"] ( ["0"-"7"] )?
368 | ["0"-"3"] ["0"-"7"]
376 <DECIMAL_LITERAL> (["l","L"])?
377 | <HEX_LITERAL> (["l","L"])?
378 | <OCTAL_LITERAL> (["l","L"])?>
380 < #DECIMAL_LITERAL: ["1"-"9"] (["0"-"9"])* >
382 < #HEX_LITERAL: "0" ["x","X"] (["0"-"9","a"-"f","A"-"F"])+ >
384 < #OCTAL_LITERAL: "0" (["0"-"7"])* >
386 < FLOATING_POINT_LITERAL:
387 <DECIMAL_FLOATING_POINT_LITERAL>
388 | <HEXADECIMAL_FLOATING_POINT_LITERAL> >
390 < #DECIMAL_FLOATING_POINT_LITERAL:
391 (["0"-"9"])+ "." (["0"-"9"])* (<DECIMAL_EXPONENT>)? (["f","F","d","D"])?
392 | "." (["0"-"9"])+ (<DECIMAL_EXPONENT>)? (["f","F","d","D"])?
393 | (["0"-"9"])+ <DECIMAL_EXPONENT> (["f","F","d","D"])?
394 | (["0"-"9"])+ (<DECIMAL_EXPONENT>)? ["f","F","d","D"]>
396 < #DECIMAL_EXPONENT: ["e","E"] (["+","-"])? (["0"-"9"])+ >
398 < #HEXADECIMAL_FLOATING_POINT_LITERAL:
399 "0" ["x", "X"] (["0"-"9","a"-"f","A"-"F"])+ (".")? <HEXADECIMAL_EXPONENT> (["f","F","d","D"])?
400 | "0" ["x", "X"] (["0"-"9","a"-"f","A"-"F"])* "." (["0"-"9","a"-"f","A"-"F"])+ <HEXADECIMAL_EXPONENT> (["f","F","d","D"])?>
402 < #HEXADECIMAL_EXPONENT: ["p","P"] (["+","-"])? (["0"-"9"])+ >
404 < #SPACE: (" " | "\t")+>
406 < #TO_END_OF_LINE: (~["\n"])+>
409 <INCLUDE: "#" (<SPACE>)? "include" <SPACE> (<STRING_LITERAL> | "<" (<LETTER> | <DOT>)+ ">")>
411 <DEFINE: "#" (<SPACE>)? <TO_END_OF_LINE>>
424 (("struct" { type = type + " struct"; })?
425 (str = <IDENTIFIER>.image {
426 if (!type.equals(""))
427 type = type + " " + str;
431 ((str = "const".image {
432 if (!type.equals(""))
433 type = type + " " + str;
437 (str = <STAR>.image {
438 if (!type.equals(""))
439 type = type + " " + str;
444 if (!type.equals(""))
445 type = type + " " + str;
455 ArrayList<String> FormalParamList() :
457 ArrayList<String> typeParams;
461 typeParams = new ArrayList<String>();
463 (TypeParam(typeParams) (<COMMA> TypeParam(typeParams))*)?
465 System.out.println(typeParams);
470 void TypeParam(ArrayList<String> typeParams) :
475 (type = Type()) (param = <IDENTIFIER>.image)
477 typeParams.add(type);
478 typeParams.add(param);
482 ArrayList<String> C_CPP_CODE() :
486 boolean newLine = false;
487 ArrayList<String> content;
493 content = new ArrayList<String>();
498 t = <CONST> | t = <STRUCT> | t = <TYPENAME> |
499 t = <IDENTIFIER> | t = <POUND> |
500 (t = <OPEN_BRACE> { newLine = true; } ) |
501 (t = <CLOSE_BRACE> { newLine = true; } ) |
502 t = <EQUALS> | t = <OPEN_PAREN> | t = <CLOSE_PAREN> |
503 t = <OPEN_BRACKET> | t = <CLOSE_BRACKET>
504 | t = <HB_SYMBOL> | t = <COMMA> |
505 t = <DOT> | t = <STAR> | t = <NEGATE> | t = <EXCLAMATION> | t = <AND> | t = <OR> | t = <MOD> | t = <PLUS> |
506 t = <PLUSPLUS> | t = <MINUS> | t = <MINUSMINUS> | t = <DIVIDE> | t = <BACKSLASH> |
507 t = <LESS_THAN> | t = <GREATER_THAN> | t = <GREATER_EQUALS> | t = <LESS_EQUALS> |
508 t = <LOGICAL_EQUALS> | t = <NOT_EQUALS> | t = <LOGICAL_AND> | t = <LOGICAL_OR> | t = <XOR> |
509 t = <QUESTION_MARK> | t = <COLON> | t = <DOUBLECOLON> |
510 (t = <SEMI_COLON> { newLine = true; } )
511 | t = <STRING_LITERAL> | t = <CHARACTER_LITERAL> |
512 t = <INTEGER_LITERAL> | t = <FLOATING_POINT_LITERAL> |
513 (t = <INCLUDE> { newLine = true; } ) |
514 (t = <DEFINE> { newLine = true; } )
517 text = text + " " + t.image;
532 void Parse(File f, ArrayList<String> content, ArrayList<Construct> constructs) :
535 ArrayList<String> code;
541 _constructs = constructs;
543 ((inst = ParseSpec() { _constructs.add(inst); }) |
544 ((code = C_CPP_CODE()) { _content.addAll(code); })
548 Construct ParseSpec() :
554 LOOKAHEAD(2) res = Global_construct() |
555 LOOKAHEAD(2) res = Interface() |
556 LOOKAHEAD(2) res = Potential_commit_point_define() |
557 LOOKAHEAD(2) res = Commit_point_define() |
558 LOOKAHEAD(2) res = Commit_point_define_check() |
559 LOOKAHEAD(2) res = Entry_point() |
560 LOOKAHEAD(2) res = Interface_define()
563 //System.out.println(res);
568 GlobalConstruct Global_construct() :
571 SequentialDefineSubConstruct code;
572 HashMap<String, String> options;
578 options = new HashMap<String, String>();
582 ((key = <IDENTIFIER>.image)
584 (value = <IDENTIFIER>.image)
586 if (options.containsKey(key)) {
587 throw new ParseException("Duplicate options!");
589 options.put(key, value);
594 (code = Global_define())
595 { res = new GlobalConstruct(_file, _content.size(), code, options); }
596 (Interface_clusters(res))?
597 (Happens_before(res))?
600 res.unfoldInterfaceCluster();
605 SequentialDefineSubConstruct Global_define() :
607 String declareVar, initVar, defineFunc;
608 ArrayList<String> code;
617 (<DECLARE_VAR> (code = C_CPP_CODE() { declareVar = stringArray2String(code); } ))?
618 (<INIT_VAR> (code = C_CPP_CODE() { initVar = stringArray2String(code); } ))?
619 (<DEFINE_FUNC> (code = C_CPP_CODE() { defineFunc = stringArray2String(code); }))?
621 SequentialDefineSubConstruct res = new SequentialDefineSubConstruct(declareVar, initVar, defineFunc);
622 //System.out.println(res);
627 ConditionalInterface Conditional_interface() :
629 String interfaceName, hbConditionLabel;
633 hbConditionLabel = "";
635 interfaceName = <IDENTIFIER>.image (<OPEN_BRACKET> hbConditionLabel =
636 <IDENTIFIER>.image <CLOSE_BRACKET>)?
638 return new ConditionalInterface(interfaceName, hbConditionLabel);
642 void Interface_cluster(GlobalConstruct inst) :
645 ConditionalInterface condInterface;
648 (clusterName= <IDENTIFIER>.image)
649 <EQUALS> <OPEN_PAREN>
650 (condInterface = Conditional_interface()
651 { inst.addInterface2Cluster(clusterName, condInterface); }
653 (<COMMA> condInterface = Conditional_interface()
654 { inst.addInterface2Cluster(clusterName, condInterface); }
659 void Interface_clusters(GlobalConstruct inst) :
662 <INTERFACE_CLUSTER> (Interface_cluster(inst))+
665 void Happens_before(GlobalConstruct inst) :
667 ConditionalInterface left, right;
672 left = Conditional_interface() <HB_SYMBOL> right = Conditional_interface()
673 { inst.addHBCondition(left, right); }
677 InterfaceConstruct Interface() :
679 InterfaceConstruct res;
680 String interfaceName, condition, idCode, check, postAction,
681 postCheck, commitPoint, hbLabel, hbCondition;
682 ActionSubConstruct action;
683 ArrayList<String> commitPointSet;
684 HashMap<String, String> hbConditions;
685 ArrayList<String> content;
696 commitPointSet = new ArrayList<String>();
697 hbConditions = new HashMap<String, String>();
700 <INTERFACE> (interfaceName = <IDENTIFIER>.image)
702 (commitPoint = <IDENTIFIER>.image
703 { commitPointSet.add(commitPoint); }
706 (commitPoint = <IDENTIFIER>.image)
708 if (commitPointSet.contains(commitPoint)) {
709 throw new ParseException(interfaceName + " has" +
710 "duplicate commit point labels");
712 commitPointSet.add(commitPoint);
716 (<CONDITION> (content = C_CPP_CODE() { condition = stringArray2String(content); }))?
719 (hbLabel = <IDENTIFIER>.image)
720 (content = C_CPP_CODE() { hbCondition = stringArray2String(content); })
722 if (hbConditions.containsKey(hbLabel)) {
723 throw new ParseException(interfaceName + " has" +
724 "duplicate happens-before condtion labels");
726 hbConditions.put(hbLabel, hbCondition);
729 (<ID> (content = C_CPP_CODE() { idCode = stringArray2String(content); }))?
730 (<CHECK> (content = C_CPP_CODE() { check = stringArray2String(content); }))?
732 (<POST_ACTION> (content = C_CPP_CODE() { postAction = stringArray2String(content); }))?
733 (<POST_CHECK> (content = C_CPP_CODE() { postCheck = stringArray2String(content); }))?
736 res = new InterfaceConstruct(_file, _content.size(), interfaceName, commitPointSet, condition,
737 hbConditions, idCode, check, action, postAction, postCheck);
742 ActionSubConstruct Action() :
744 String type, name, expr, defineVarStr, code;
745 ArrayList<DefineVar> defineVars;
746 ArrayList<String> content;
750 defineVars = new ArrayList<DefineVar>();
756 (<DEFINEVAR> (content = C_CPP_CODE() { defineVarStr = stringArray2String(content); })
758 int eqIdx = defineVarStr.indexOf('=');
759 int typeEnd = defineVarStr.lastIndexOf(' ', eqIdx - 2);
760 type = defineVarStr.substring(0, typeEnd);
761 name = defineVarStr.substring(typeEnd + 1, eqIdx - 1);
762 expr = defineVarStr.substring(eqIdx + 2);
763 DefineVar defineVar = new DefineVar(type, name, expr);
764 defineVars.add(defineVar);
765 })* (<CODE> (content = C_CPP_CODE() { code = stringArray2String(content); }))? )
769 ActionSubConstruct res = new ActionSubConstruct(defineVars, code);
774 PotentialCPDefineConstruct Potential_commit_point_define() :
776 PotentialCPDefineConstruct res;
777 String label, condition;
778 ArrayList<String> content;
784 <POTENTIAL_COMMIT_POINT_DEFINE> (content = C_CPP_CODE() { condition = stringArray2String(content); })
785 <LABEL> (label = <IDENTIFIER>.image)
788 res = new PotentialCPDefineConstruct(_file, _content.size(), label, condition);
794 CPDefineConstruct Commit_point_define() :
796 CPDefineConstruct res;
797 String label, potentialCPLabel, condition;
798 ArrayList<String> content;
804 <COMMIT_POINT_DEFINE> (content = C_CPP_CODE() { condition = stringArray2String(content); })
805 <POTENTIAL_COMMIT_POINT_LABEL> (potentialCPLabel = <IDENTIFIER>.image)
806 <LABEL> (label = <IDENTIFIER>.image)
809 res = new CPDefineConstruct(_file, _content.size(), label, potentialCPLabel, condition);
815 CPDefineCheckConstruct Commit_point_define_check() :
817 CPDefineCheckConstruct res;
818 String label, condition;
819 ArrayList<String> content;
825 <COMMIT_POINT_DEFINE_CHECK> (content = C_CPP_CODE() { condition = stringArray2String(content); })
826 <LABEL> (label = <IDENTIFIER>.image)
829 res = new CPDefineCheckConstruct(_file, _content.size(), label, condition);
834 EntryPointConstruct Entry_point() :
842 return new EntryPointConstruct(_file, _content.size());
846 InterfaceDefineConstruct Interface_define() :
852 <INTERFACE_DEFINE> (name = <IDENTIFIER>.image)
855 return new InterfaceDefineConstruct(_file, _content.size(), name);