fixed bugs
[cdsspec-compiler.git] / grammer / spec_compiler.jj
1 /* spec-compiler.jj Grammer definition for the specification */
2
3
4 /*
5         SPEC constructs:
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.
10         
11         a) Global construct
12         @Begin
13         @Options:
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
16                 # entry point.
17                 LANG = C;
18         @Global_define:
19                 @DeclareStruct:
20                 @DeclareVar:
21                 @InitVar:
22                 @DefineFunc:
23                 ...
24                 @DefineFunc:
25         @Interface_cluster:
26                 ...
27         @Happens-before:
28                 ...
29         @End
30         
31         b) Interface construct
32         @Begin
33         @Interface: ...
34         @Commit_point_set:
35                 IDENTIFIER | IDENTIFIER ...
36         @Condition: ... (Optional)
37         @HB_Condition:
38                 IDENTIFIER :: <C_CPP_Condition>
39         @HB_Condition: ...
40         @ID: ... (Optional, use default ID)
41         @Check: (Optional)
42                 ...
43         @Action: (Optional)
44                 ...
45         @Post_action: (Optional)
46         @Post_check: (Optional)
47         @End
48
49         c) Potential commit construct
50         @Begin
51         @Potential_commit_point_define: ...
52         @Label: ...
53         @End
54
55         d) Commit point define construct
56         @Begin
57         @Commit_point_define_check: ...
58         @Label: ...
59         @End
60         
61                 OR
62
63         @Begin
64         @Commit_point_define: ...
65         @Potential_commit_point_label: ...
66         @Label: ...
67         @End
68
69         e) Entry point construct
70         @Begin
71         @Entry_point
72         @End
73
74         f) Interface define construct
75         @Begin
76         @Interface_define: <Interface_Name>
77         @End
78 */
79
80
81
82 options {
83         STATIC = false;
84         JAVA_UNICODE_ESCAPE = true;
85 }
86
87 PARSER_BEGIN(SpecParser)
88 package edu.uci.eecs.specCompiler.grammerParser;
89
90 import java.io.FileInputStream;
91 import java.io.FileNotFoundException;
92 import java.io.InputStream;
93 import java.io.ByteArrayInputStream;
94 import java.io.File;
95 import java.util.ArrayList;
96 import java.util.HashMap;
97 import java.util.HashSet;
98
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;
115
116         public class SpecParser {
117                 private static ArrayList<String> _content;
118                 private static File _file;
119                 private static ArrayList<Construct> _constructs;
120
121
122                 public static void main(String[] argvs)
123                 throws ParseException, TokenMgrError {
124                         try {
125                                 File f = new File("./grammer/spec.txt");
126                                 FileInputStream fis = new FileInputStream(f);
127                                 SpecParser parser = new SpecParser(fis);
128                                 /*
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));
135                                 }
136                                 
137                                 for (int i = 0; i < constructs.size(); i++) {
138                                         System.out.println(constructs.get(i));
139                                 }
140                                 */
141                                 
142                                 parser.Test();
143                                 System.out.println("Parsing finished!");
144                         } catch (FileNotFoundException e) {
145                                 e.printStackTrace();
146                         }
147                 }
148
149                 public static SourceFileInfo ParseFile(File f)
150                 throws ParseException, TokenMgrError {
151                         try {
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) {
160                                 e.printStackTrace();
161                         }
162                         return null;
163                 }
164
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();
170                 }
171
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();
177                 }
178
179
180                 public static String stringArray2String(ArrayList<String> content) {
181                         StringBuilder sb = new StringBuilder();
182                         for (int i = 0; i < content.size(); i++) {
183                                 sb.append(content.get(i) + "\n");
184                         }
185                         return sb.toString();
186                 }
187
188         }
189 PARSER_END(SpecParser)
190
191
192
193 <*> SKIP :
194 {
195         " "
196 |
197         "\n"
198 |
199         "\r"
200 |
201         "\r\n"
202 |
203         "\t"
204 }
205
206 SKIP : {
207         "/**" : IN_POTENTIAL_SPEC
208 }
209
210 <IN_POTENTIAL_SPEC> TOKEN : {
211         <BEGIN: "@Begin"> : IN_SPEC
212 }
213
214 <IN_SPEC> SKIP : {
215         "*/" : DEFAULT
216 }
217
218 SKIP : {
219         "/*": IN_COMMENT
220 }
221
222 <*> SKIP : {
223         // "//" comment for the specification
224         <"//" (~["\n", "\r"])* (["\n", "\r"])>
225 }
226
227 <IN_COMMENT, IN_POTENTIAL_SPEC> SKIP : {
228         "*/": DEFAULT
229 }
230
231 <IN_COMMENT, IN_POTENTIAL_SPEC> SKIP : { <  ~[] > }
232
233 <IN_SPEC> SKIP :
234 {
235         // "#" comment for the specification
236         <"#" (~["\n", "\r"])* (["\n", "\r"])>
237 }
238
239
240 <IN_SPEC> TOKEN : {
241         <END: "@End">
242 |
243         <OPTIONS: "@Options:">
244 |
245         <GLOBAL_DEFINE: "@Global_define:">
246 |
247         <DECLARE_STRUCT: "@DeclareStruct:">
248 |
249         <DECLARE_VAR: "@DeclareVar:">
250 |
251         <INIT_VAR: "@InitVar:">
252 |
253         <DEFINE_FUNC: "@DefineFunc:">
254 |
255         <INTERFACE_CLUSTER: "@Interface_cluster:">
256 |
257         <HAPPENS_BEFORE: "@Happens_before:">
258 |
259         <INTERFACE: "@Interface:">
260 |
261         <COMMIT_POINT_SET: "@Commit_point_set:">
262 |
263         <ENTRY_POINT: "@Entry_point">
264 |
265         <CLASS_BEGIN: "@Class_begin">
266 |
267         <CLASS_END: "@Class_end">
268 |
269         <INTERFACE_DEFINE: "@Interface_define:">
270 |
271         <CONDITION: "@Condition:">
272 |
273         <HB_CONDITION: "@HB_condition:">
274 |
275         <ID: "@ID:">
276 |
277         <CHECK: "@Check:">
278 |
279         <ACTION: "@Action:">
280 |
281         <CODE: "@Code:">
282 |
283         <POST_ACTION: "@Post_action:">
284 |
285         <POST_CHECK: "@Post_check:">
286 |
287         <POTENTIAL_COMMIT_POINT_DEFINE: "@Potential_commit_point_define:">
288 |
289         <LABEL: "@Label:">
290 |
291         <COMMIT_POINT_DEFINE_CHECK: "@Commit_point_define_check:">
292 |
293         <COMMIT_POINT_DEFINE: "@Commit_point_define:">
294 |
295         <POTENTIAL_COMMIT_POINT_LABEL: "@Potential_commit_point_label:">
296 }
297
298
299 <IN_SPEC, DEFAULT> TOKEN :
300 {
301 /*   Specification & C/C++ shared tokens   */
302 // Reserved keywords
303         <CONST: "const">
304 |
305         <STRUCT: "struct">
306 |
307         <CLASS: "class">
308 |
309         <UNSIGNED: "unsigned">
310 |
311         <TEMPLATE: "template">
312 |
313         <#DIGIT: ["0"-"9"]>
314 |
315         <#LETTER: ["a"-"z", "A"-"Z"]>
316 |
317         <IDENTIFIER: (<LETTER> | "_") (<LETTER> | <DIGIT> | "_")*>
318 |
319         <POUND: "#">
320 |
321         <OPEN_BRACKET: "[">
322 |
323         <CLOSE_BRACKET: "]">
324 |
325         <EQUALS: "=">
326 |
327         <OPEN_PAREN: "(">
328 |
329         <CLOSE_PAREN: ")">
330 |
331         <OPEN_BRACE: "{">
332 |
333         <CLOSE_BRACE: "}">
334 |
335         <HB_SYMBOL: "->">
336 |
337         <COMMA: ",">
338 |
339 /*   C/C++ only token*/
340         <DOT: ".">
341 |
342         <STAR: "*">
343 |
344         <NEGATE: "~">
345 |
346         <EXCLAMATION: "!">
347 |
348         <AND: "&">
349 |
350         <OR: "|">
351 |
352         <MOD: "%">
353 |
354         <PLUS: "+">
355 |
356         <PLUSPLUS: "++">
357 |
358         <MINUS: "-">
359 |
360         <MINUSMINUS: "--">
361 |
362         <DIVIDE: "/">
363 |
364         <BACKSLASH: "\\">
365 |
366         <LESS_THAN: "<">
367 |
368         <GREATER_THAN: ">">
369 |
370         <GREATER_EQUALS: ">=">
371 |
372         <LESS_EQUALS: "<=">
373 |
374         <LOGICAL_EQUALS: "==">
375 |
376         <NOT_EQUALS: "!=">
377 |
378         <LOGICAL_AND: "&&">
379 |
380         <LOGICAL_OR: "||">
381 |
382         <XOR: "^">
383 |
384         <QUESTION_MARK: "?">
385 |
386         <COLON: ":">
387 |
388         <DOUBLECOLON: "::">
389 |
390         <SEMI_COLON: ";">
391 |
392         <STRING_LITERAL:
393         "\""
394         ((~["\"","\\","\n","\r"])
395         | ("\\"
396                 ( ["n","t","b","r","f","\\","'","\""]
397                 | ["0"-"7"] ( ["0"-"7"] )?
398                 | ["0"-"3"] ["0"-"7"]
399                         ["0"-"7"]
400                 )
401                 )
402         )*
403         "\"">
404 |
405         <CHARACTER_LITERAL:
406         "'"
407         ((~["'","\\","\n","\r"])
408         | ("\\"
409                 (["n","t","b","r","f","\\","'","\""]
410                 | ["0"-"7"] ( ["0"-"7"] )?
411                 | ["0"-"3"] ["0"-"7"]
412                 ["0"-"7"]
413                 )
414                 )
415         )
416         "'">
417 |
418         < INTEGER_LITERAL:
419         <DECIMAL_LITERAL> (["l","L"])?
420       | <HEX_LITERAL> (["l","L"])?
421       | <OCTAL_LITERAL> (["l","L"])?>
422 |
423         < #DECIMAL_LITERAL: ["1"-"9"] (["0"-"9"])* >
424 |
425         < #HEX_LITERAL: "0" ["x","X"] (["0"-"9","a"-"f","A"-"F"])+ >
426 |
427         < #OCTAL_LITERAL: "0" (["0"-"7"])* >
428 |
429         < FLOATING_POINT_LITERAL:
430         <DECIMAL_FLOATING_POINT_LITERAL>
431       | <HEXADECIMAL_FLOATING_POINT_LITERAL> >
432 |
433         < #DECIMAL_FLOATING_POINT_LITERAL:
434         (["0"-"9"])+ "." (["0"-"9"])* (<DECIMAL_EXPONENT>)? (["f","F","d","D"])?
435       | "." (["0"-"9"])+ (<DECIMAL_EXPONENT>)? (["f","F","d","D"])?
436       | (["0"-"9"])+ <DECIMAL_EXPONENT> (["f","F","d","D"])?
437       | (["0"-"9"])+ (<DECIMAL_EXPONENT>)? ["f","F","d","D"]>
438 |
439         < #DECIMAL_EXPONENT: ["e","E"] (["+","-"])? (["0"-"9"])+ >
440 |
441         < #HEXADECIMAL_FLOATING_POINT_LITERAL:
442         "0" ["x", "X"] (["0"-"9","a"-"f","A"-"F"])+ (".")? <HEXADECIMAL_EXPONENT> (["f","F","d","D"])?
443       | "0" ["x", "X"] (["0"-"9","a"-"f","A"-"F"])* "." (["0"-"9","a"-"f","A"-"F"])+ <HEXADECIMAL_EXPONENT> (["f","F","d","D"])?>
444 |
445         < #HEXADECIMAL_EXPONENT: ["p","P"] (["+","-"])? (["0"-"9"])+ >
446 |
447         < #SPACE: (" " | "\t")+>
448 |
449         < #TO_END_OF_LINE: (~["\n"])+>
450 |
451         /* Macro token */
452         <INCLUDE: "#" (<SPACE>)? "include" <SPACE> (<STRING_LITERAL> | "<" (<LETTER> | <DOT>)+ ">")>
453 |
454         <DEFINE: "#" (<SPACE>)? <TO_END_OF_LINE>>
455 }
456
457 String Type() :
458 {
459         String type;
460         String str;
461         QualifiedName name;
462 }
463 {
464         { type = ""; }
465         ("const"
466         { type = "const"; }
467         )?
468         (((str = <STRUCT>.image | str = <CLASS>.image | str = <UNSIGNED>.image) { type = type + " " + str; })? 
469         (
470         name = ParseQualifiedName() {
471                 if (!type.equals(""))
472                         type = type + " " + name.fullName;
473                 else
474                         type = name.fullName;
475         })
476         )
477         ((str = "const".image {
478                 if (!type.equals(""))
479                         type = type + " " + str;
480                 else
481                         type = str;
482         }) |
483         (str = <STAR>.image {
484                 if (!type.equals(""))
485                         type = type + " " + str;
486                 else
487                         type = str;
488         }) |
489         (str = <AND>.image {
490                 if (!type.equals(""))
491                         type = type + " " + str;
492                 else
493                         type = str;
494         })
495         )*
496         {
497                 return type;
498         }
499 }
500
501 void Test() :
502 {
503         String str;     
504         FunctionHeader func;
505 }
506 {
507         /*
508         str = Type()
509         {
510                 System.out.println(str);
511         }
512         */
513         func = FuncDecl() 
514         {
515                 System.out.println(func);
516         }
517
518         
519 }
520
521 String ParameterizedName() :
522 {
523         String res = "";
524         String str;
525 }
526 {
527         (str = <IDENTIFIER>.image {res = str;})
528         ("<" str = <IDENTIFIER>.image { res = res + "<" + str; }
529         ("," str = <IDENTIFIER>.image { res = res + ", " + str; })* ">"
530         { res = res + ">"; }
531         )?
532         {
533                 return res;
534         }
535 }
536
537 FunctionHeader FuncDecl() :
538 {
539         String ret;
540         QualifiedName funcName;
541         ArrayList<VariableDeclaration> args;
542 }
543 {
544         ret = Type() 
545         funcName = ParseQualifiedName() 
546         args = FormalParamList() 
547         {
548                 FunctionHeader res = new FunctionHeader(ret, funcName, args);
549                 //System.out.println(res);
550                 return res;
551         }
552 }
553
554 QualifiedName ParseQualifiedName() :
555 {
556         String qualifiedName, str;
557 }
558 {
559         { qualifiedName = ""; }
560         (str = ParameterizedName() { qualifiedName = qualifiedName + str; } )
561         ( <DOUBLECOLON> (str = ParameterizedName() { qualifiedName = qualifiedName +
562         "::" + str; }  ))*
563         {
564                 QualifiedName res = new QualifiedName(qualifiedName);
565                 //System.out.println(res);
566                 return res;
567         }
568 }
569
570 ArrayList<String> TemplateParamList() :
571 {
572         ArrayList<String> params;
573         String str;
574 }
575 {
576         {
577                 params = new ArrayList<String>();
578         }
579         <TEMPLATE>
580         "<"
581         (str = <IDENTIFIER>.image 
582         str = <IDENTIFIER>.image {params.add(str);})
583
584         ("," str = <IDENTIFIER>.image 
585         str = <IDENTIFIER>.image {params.add(str);})*
586         ">"
587         {
588                 //System.out.println(params);
589                 return params;
590         }
591 }
592
593 ArrayList<VariableDeclaration > FormalParamList() :
594 {
595         ArrayList<VariableDeclaration > typeParams;
596         VariableDeclaration varDecl;
597 }
598 {
599         {
600                 typeParams = new ArrayList<VariableDeclaration >();
601         }
602         "("
603         ((varDecl = TypeParam() {typeParams.add(varDecl);})
604         ((<COMMA> varDecl = TypeParam() {typeParams.add(varDecl);}))*)?
605         ")"
606         {
607                 return typeParams;
608         }
609 }
610
611 VariableDeclaration TypeParam() :
612 {
613         String type, param;
614 }
615 {
616         (type = Type()) (param = <IDENTIFIER>.image)
617         {
618                 return new VariableDeclaration(type, param);
619         }
620 }
621
622 ArrayList<String> C_CPP_CODE(ArrayList<String> headers) :
623 {
624         String text;
625         Token t;
626         boolean newLine = false;
627         boolean inTemplate = false;
628         ArrayList<String> content;
629         String header;
630 }
631 {
632         {
633                 text = "";
634                 t = new Token();
635                 content = new ArrayList<String>();
636         }
637         (
638         LOOKAHEAD(2)
639         (
640         t = <CONST> | t = <STRUCT> | t = <CLASS> | t = <UNSIGNED> |
641         (t = <TEMPLATE> { inTemplate = true;  })|
642         (t = <INCLUDE>
643         {
644                 header = t.image;
645                 newLine = true;
646                 if (headers != null) {
647                         headers.add(header.substring(header.lastIndexOf(' ') + 1));
648                 }
649         })
650         | t = <IDENTIFIER> | t = <POUND> |
651         (t = <OPEN_BRACE>  { newLine = true; } ) |
652         (t = <CLOSE_BRACE>  { newLine = true; } ) | 
653         t = <EQUALS> | t = <OPEN_PAREN> | t = <CLOSE_PAREN> | 
654         t = <OPEN_BRACKET> | t = <CLOSE_BRACKET>
655         | t = <HB_SYMBOL> | t = <COMMA> |
656         t = <DOT> | t = <STAR> | t = <NEGATE> | t = <EXCLAMATION> | t = <AND> | t = <OR> | t = <MOD> | t = <PLUS> |
657         t = <PLUSPLUS> | t = <MINUS> | t = <MINUSMINUS> | t = <DIVIDE> | t = <BACKSLASH> |
658         t = <LESS_THAN> |
659         (t = <GREATER_THAN> { if (inTemplate) newLine = true; }) |
660         t = <GREATER_EQUALS>    | t = <LESS_EQUALS> |
661         t = <LOGICAL_EQUALS> | t = <NOT_EQUALS> | t = <LOGICAL_AND> | t = <LOGICAL_OR> | t = <XOR> |
662         t = <QUESTION_MARK> | t = <COLON> | t = <DOUBLECOLON> |
663         (t = <SEMI_COLON> { newLine = true; } )
664         | t = <STRING_LITERAL> | t = <CHARACTER_LITERAL> |
665         t = <INTEGER_LITERAL> | t = <FLOATING_POINT_LITERAL> |
666         (t = <DEFINE> { newLine = true; } )
667         )
668         {
669                 text = text + " " + t.image;
670                 if (newLine) {
671                         content.add(text);
672                         text = "";
673                         newLine = false;
674                 }
675         }
676         )+
677
678         {
679                 if (content.size() == 0) {
680                         content.add(text);
681                 }
682                 return content;
683         }
684 }
685
686
687 void Parse(File f, ArrayList<String> content, ArrayList<Construct> constructs, ArrayList<String> headers) :
688 {
689         Construct inst;
690         ArrayList<String> code;
691 }
692 {
693         {
694                 _file = f;
695                 _content = content;
696                 _constructs = constructs;
697         }
698         ((inst = ParseSpec() { _constructs.add(inst); }) |
699         ((code = C_CPP_CODE(headers)) { _content.addAll(code); })
700         )* <EOF>
701 }
702
703 Construct ParseSpec() :
704 {
705         Construct res;  
706 }
707 {
708         (
709         LOOKAHEAD(2) res = Global_construct() |
710         LOOKAHEAD(2) res = Interface() |
711         LOOKAHEAD(2) res = Potential_commit_point_define() |
712         LOOKAHEAD(2) res = Commit_point_define() |
713         LOOKAHEAD(2) res = Commit_point_define_check() |
714         LOOKAHEAD(2) res = Entry_point() |
715         LOOKAHEAD(2) res = Class_begin() |
716         LOOKAHEAD(2) res = Class_end() |
717         LOOKAHEAD(2) res = Interface_define()
718         )
719         {
720                 //System.out.println(res);
721                 return res;
722         }
723 }
724
725 GlobalConstruct Global_construct() :
726 {
727         GlobalConstruct res;
728         SequentialDefineSubConstruct code;
729         HashMap<String, String> options;
730         String key, value;
731 }
732 {
733         {
734                 res = null;
735                 options = new HashMap<String, String>();
736         }
737                 <BEGIN> 
738                         (<OPTIONS>
739                                 ((key = <IDENTIFIER>.image)
740                                 <EQUALS>
741                                 (value = <IDENTIFIER>.image)
742                                 {
743                                         if (options.containsKey(key)) {
744                                                 throw new ParseException("Duplicate options!");
745                                         }
746                                         options.put(key, value);
747                                 }
748                                 <SEMI_COLON>
749                                 )*
750                         )?
751                         (code = Global_define())
752                         { res = new GlobalConstruct(_file, _content.size(), code, options); }
753                         (Interface_clusters(res))?
754                         (Happens_before(res))?
755                 <END>
756         {
757                 res.unfoldInterfaceCluster();
758                 return res;
759         }
760 }
761
762 SequentialDefineSubConstruct Global_define() :
763 {
764         ArrayList<String> initVar, defineFunc, code, declareStruct;
765         ArrayList<ArrayList<String>> defineFuncs;
766         ArrayList<VariableDeclaration> declareVars;
767         ArrayList<ArrayList<String>> declareStructs;
768         VariableDeclaration declareVar;
769
770 }
771 {
772         {
773                 declareVars = new ArrayList<VariableDeclaration>();
774                 initVar = null;
775                 defineFuncs = new ArrayList<ArrayList<String>>();
776                 declareStructs = new ArrayList<ArrayList<String>>();
777         }
778         <GLOBAL_DEFINE>
779         (<DECLARE_STRUCT> (declareStruct = C_CPP_CODE(null) {
780                 declareStructs.add(declareStruct); }))*
781                 (<DECLARE_VAR> ((declareVar = TypeParam() ";" {
782                         declareVars.add(declareVar); } )*))?
783         (<INIT_VAR> (code = C_CPP_CODE(null) { initVar = code; } ))?
784         (<DEFINE_FUNC> (defineFunc = C_CPP_CODE(null) { defineFuncs.add(defineFunc); }))*
785         {
786                 SequentialDefineSubConstruct res = new
787                         SequentialDefineSubConstruct(declareStructs, declareVars, initVar, defineFuncs);
788                 //System.out.println(res);
789                 return res;
790         }
791 }
792
793 ConditionalInterface Conditional_interface() :
794 {
795         String interfaceName, hbConditionLabel;
796 }
797 {
798         {
799                 hbConditionLabel = "";
800         }
801         interfaceName = <IDENTIFIER>.image (<OPEN_BRACKET> hbConditionLabel =
802         <IDENTIFIER>.image <CLOSE_BRACKET>)?
803         {
804                 return new ConditionalInterface(interfaceName, hbConditionLabel);
805         }
806 }
807
808 void Interface_cluster(GlobalConstruct inst) :
809 {
810         String clusterName;
811         ConditionalInterface condInterface;
812 }
813 {
814         (clusterName= <IDENTIFIER>.image)
815         <EQUALS> <OPEN_PAREN>
816                 (condInterface = Conditional_interface()
817                 { inst.addInterface2Cluster(clusterName, condInterface); } 
818                 )
819                 (<COMMA> condInterface = Conditional_interface()
820                 { inst.addInterface2Cluster(clusterName, condInterface); } 
821                 )*
822         <CLOSE_PAREN>
823 }
824
825 void Interface_clusters(GlobalConstruct inst) :
826 {}
827 {
828         <INTERFACE_CLUSTER> (Interface_cluster(inst))+
829 }
830
831 void Happens_before(GlobalConstruct inst) :
832 {
833         ConditionalInterface left, right;       
834 }
835 {
836         <HAPPENS_BEFORE> 
837         (
838         left = Conditional_interface() <HB_SYMBOL> right = Conditional_interface()
839         { inst.addHBCondition(left, right); }
840         )+
841 }
842
843 InterfaceConstruct Interface() :
844 {
845         InterfaceConstruct res;
846         String interfaceName, condition, idCode, check,
847                 postCheck, commitPoint, hbLabel, hbCondition;
848         ArrayList<String> commitPointSet;
849         ArrayList<String> action, postAction;
850         HashMap<String, String> hbConditions;
851         ArrayList<String> content;
852 }
853 {
854         {
855                 res = null;
856                 action = new ArrayList<String>();
857                 condition = "";
858                 idCode = "";
859                 check = "";
860                 postCheck = "";
861                 commitPointSet = new ArrayList<String>();
862                 hbConditions = new HashMap<String, String>();
863                 postAction = new ArrayList<String>();
864         }
865                 <BEGIN>
866                         <INTERFACE> (interfaceName = <IDENTIFIER>.image)
867                         <COMMIT_POINT_SET>
868                                 (commitPoint = <IDENTIFIER>.image
869                                 { commitPointSet.add(commitPoint); }
870                                 )
871                                 (<OR>
872                                         (commitPoint = <IDENTIFIER>.image)
873                                         {
874                                                 if (commitPointSet.contains(commitPoint)) {
875                                                         throw new ParseException(interfaceName + " has" +
876                                                                 "duplicate commit point labels");
877                                                 }
878                                                 commitPointSet.add(commitPoint);
879                                         }
880                                 )*
881
882                         (<CONDITION> (content = C_CPP_CODE(null) { condition = stringArray2String(content); }))?
883                         (
884                                 <HB_CONDITION>
885                                 (hbLabel = <IDENTIFIER>.image)
886                                 (content = C_CPP_CODE(null) { hbCondition = stringArray2String(content); })
887                                 {
888                                         if (hbConditions.containsKey(hbLabel)) {
889                                                 throw new ParseException(interfaceName + " has" +
890                                                         "duplicate happens-before condtion labels");
891                                         }
892                                         hbConditions.put(hbLabel, hbCondition);
893                                 }
894                         )*
895                         (<ID> (content = C_CPP_CODE(null) { idCode = stringArray2String(content); }))?
896                         (<CHECK> (content = C_CPP_CODE(null) { check = stringArray2String(content); }))?
897                         (<ACTION> action = C_CPP_CODE(null))?
898                         (<POST_ACTION> (postAction = C_CPP_CODE(null) ))?
899                         (<POST_CHECK> (content = C_CPP_CODE(null) { postCheck = stringArray2String(content); }))?
900                 <END>
901         {
902                 res = new InterfaceConstruct(_file, _content.size(), interfaceName, commitPointSet, condition,
903                         hbConditions, idCode, check, action, postAction, postCheck);
904                 return res;
905         }
906 }
907
908
909 PotentialCPDefineConstruct Potential_commit_point_define() :
910 {
911         PotentialCPDefineConstruct res;
912         String label, condition;
913         ArrayList<String> content;
914 }
915 {
916
917         { res = null; }
918                 <BEGIN>
919                         <POTENTIAL_COMMIT_POINT_DEFINE> (content = C_CPP_CODE(null) { condition = stringArray2String(content); })
920                         <LABEL> (label = <IDENTIFIER>.image)
921                 <END>
922         {
923                 res = new PotentialCPDefineConstruct(_file, _content.size(), label, condition); 
924                 return res;
925         }
926 }
927
928
929 CPDefineConstruct Commit_point_define() :
930 {
931         CPDefineConstruct res;
932         String label, potentialCPLabel, condition;
933         ArrayList<String> content;
934 }
935 {
936
937         { res = null; }
938                 <BEGIN>
939                         <COMMIT_POINT_DEFINE> (content = C_CPP_CODE(null) { condition = stringArray2String(content); })
940                         <POTENTIAL_COMMIT_POINT_LABEL> (potentialCPLabel = <IDENTIFIER>.image)
941                         <LABEL> (label = <IDENTIFIER>.image)
942                 <END>
943         {
944                 res = new CPDefineConstruct(_file, _content.size(), label, potentialCPLabel, condition);
945                 return res;
946         }
947 }
948
949
950 CPDefineCheckConstruct Commit_point_define_check() :
951 {
952         CPDefineCheckConstruct res;     
953         String label, condition;
954         ArrayList<String> content;
955 }
956 {
957
958         { res = null; }
959                 <BEGIN> 
960                         <COMMIT_POINT_DEFINE_CHECK> (content = C_CPP_CODE(null) { condition = stringArray2String(content); })
961                         <LABEL> (label = <IDENTIFIER>.image)
962                 <END>
963         {
964                 res = new CPDefineCheckConstruct(_file, _content.size(), label, condition);
965                 return res;
966         }
967 }
968
969 EntryPointConstruct Entry_point() :
970 {}
971 {
972
973                 <BEGIN> 
974                         <ENTRY_POINT>
975                 <END>
976         {
977                 return new EntryPointConstruct(_file, _content.size());
978         }
979 }
980
981 ClassBeginConstruct Class_begin() :
982 {}
983 {
984
985                 <BEGIN> 
986                         <CLASS_BEGIN>
987                 <END>
988         {
989                 return new ClassBeginConstruct(_file, _content.size());
990         }
991 }
992
993 ClassEndConstruct Class_end() :
994 {}
995 {
996
997                 <BEGIN> 
998                         <CLASS_END>
999                 <END>
1000         {
1001                 return new ClassEndConstruct(_file, _content.size());
1002         }
1003 }
1004
1005 InterfaceDefineConstruct Interface_define() :
1006 {
1007         String name;    
1008 }
1009 {
1010                 <BEGIN>
1011                         <INTERFACE_DEFINE> (name = <IDENTIFIER>.image)
1012                 <END>
1013         {
1014                 return new InterfaceDefineConstruct(_file, _content.size(), name);
1015         }
1016 }