fixed minor 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                         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");
186                         }
187                         return sb.toString();
188                 }
189
190         }
191 PARSER_END(SpecParser)
192
193
194
195 <*> SKIP :
196 {
197         " "
198 |
199         "\n"
200 |
201         "\r"
202 |
203         "\r\n"
204 |
205         "\t"
206 }
207
208 SKIP : {
209         "/**" : IN_POTENTIAL_SPEC
210 }
211
212 <IN_POTENTIAL_SPEC> TOKEN : {
213         <BEGIN: "@Begin"> : IN_SPEC
214 }
215
216 <IN_SPEC> SKIP : {
217         "*/" : DEFAULT
218 }
219
220 SKIP : {
221         "/*": IN_COMMENT
222 }
223
224 <*> SKIP : {
225         // "//" comment for the specification
226         <"//" (~["\n", "\r"])* (["\n", "\r"])>
227 }
228
229 <IN_COMMENT, IN_POTENTIAL_SPEC> SKIP : {
230         "*/": DEFAULT
231 }
232
233 <IN_COMMENT, IN_POTENTIAL_SPEC> SKIP : { <  ~[] > }
234
235 <IN_SPEC> SKIP :
236 {
237         // "#" comment for the specification
238         <"#" (~["\n", "\r"])* (["\n", "\r"])>
239 }
240
241
242 <IN_SPEC> TOKEN : {
243         <END: "@End">
244 |
245         <OPTIONS: "@Options:">
246 |
247         <GLOBAL_DEFINE: "@Global_define:">
248 |
249         <DECLARE_STRUCT: "@DeclareStruct:">
250 |
251         <DECLARE_VAR: "@DeclareVar:">
252 |
253         <INIT_VAR: "@InitVar:">
254 |
255         <DEFINE_FUNC: "@DefineFunc:">
256 |
257         <INTERFACE_CLUSTER: "@Interface_cluster:">
258 |
259         <HAPPENS_BEFORE: "@Happens_before:">
260 |
261         <INTERFACE: "@Interface:">
262 |
263         <COMMIT_POINT_SET: "@Commit_point_set:">
264 |
265         <ENTRY_POINT: "@Entry_point">
266 |
267         <CLASS_BEGIN: "@Class_begin">
268 |
269         <CLASS_END: "@Class_end">
270 |
271         <INTERFACE_DEFINE: "@Interface_define:">
272 |
273         <CONDITION: "@Condition:">
274 |
275         <HB_CONDITION: "@HB_condition:">
276 |
277         <ID: "@ID:">
278 |
279         <CHECK: "@Check:">
280 |
281         <ACTION: "@Action:">
282 |
283         <CODE: "@Code:">
284 |
285         <POST_ACTION: "@Post_action:">
286 |
287         <POST_CHECK: "@Post_check:">
288 |
289         <POTENTIAL_COMMIT_POINT_DEFINE: "@Potential_commit_point_define:">
290 |
291         <LABEL: "@Label:">
292 |
293         <COMMIT_POINT_DEFINE_CHECK: "@Commit_point_define_check:">
294 |
295         <COMMIT_POINT_DEFINE: "@Commit_point_define:">
296 |
297         <POTENTIAL_COMMIT_POINT_LABEL: "@Potential_commit_point_label:">
298 }
299
300
301 <IN_SPEC, DEFAULT> TOKEN :
302 {
303 /*   Specification & C/C++ shared tokens   */
304 // Reserved keywords
305         <CONST: "const">
306 |
307         <STRUCT: "struct">
308 |
309         <CLASS: "class">
310 |
311         <UNSIGNED: "unsigned">
312 |
313         <TEMPLATE: "template">
314 |
315         <INLINE: "inline">
316 |
317         <STATIC: "static">
318 |
319         <#DIGIT: ["0"-"9"]>
320 |
321         <#LETTER: ["a"-"z", "A"-"Z"]>
322 |
323         <IDENTIFIER: (<LETTER> | "_") (<LETTER> | <DIGIT> | "_")*>
324 |
325         <POUND: "#">
326 |
327         <OPEN_BRACKET: "[">
328 |
329         <CLOSE_BRACKET: "]">
330 |
331         <EQUALS: "=">
332 |
333         <OPEN_PAREN: "(">
334 |
335         <CLOSE_PAREN: ")">
336 |
337         <OPEN_BRACE: "{">
338 |
339         <CLOSE_BRACE: "}">
340 |
341         <HB_SYMBOL: "->">
342 |
343         <COMMA: ",">
344 |
345 /*   C/C++ only token*/
346         <DOT: ".">
347 |
348         <STAR: "*">
349 |
350         <NEGATE: "~">
351 |
352         <EXCLAMATION: "!">
353 |
354         <AND: "&">
355 |
356         <OR: "|">
357 |
358         <MOD: "%">
359 |
360         <PLUS: "+">
361 |
362         <PLUSPLUS: "++">
363 |
364         <MINUS: "-">
365 |
366         <MINUSMINUS: "--">
367 |
368         <DIVIDE: "/">
369 |
370         <BACKSLASH: "\\">
371 |
372         <LESS_THAN: "<">
373 |
374         <GREATER_THAN: ">">
375 |
376         <GREATER_EQUALS: ">=">
377 |
378         <LESS_EQUALS: "<=">
379 |
380         <LOGICAL_EQUALS: "==">
381 |
382         <NOT_EQUALS: "!=">
383 |
384         <LOGICAL_AND: "&&">
385 |
386         <LOGICAL_OR: "||">
387 |
388         <XOR: "^">
389 |
390         <QUESTION_MARK: "?">
391 |
392         <COLON: ":">
393 |
394         <DOUBLECOLON: "::">
395 |
396         <DOUBLELESSTHAN: "<<">
397 |
398         <DOUBLEGREATERTHAN: ">>">
399 |
400         <TRIPLEGREATERTHAN: ">>>">
401 |
402         <PLUS_EQUALS: "+=">
403 |
404         <MINUS_EQUALS: "-=">
405 |
406         <TIMES_EQUALS: "*=">
407 |
408         <DIVIDE_EQUALS: "/=">
409 |
410         <MOD_EQUALS: "%=">
411 |
412         <XOR_EQUALS: "^=">
413 |
414         <OR_EQUALS: "|=">
415 |
416         <AND_EQUALS: "&=">
417
418 |
419         <SEMI_COLON: ";">
420 |
421         <STRING_LITERAL:
422         "\""
423         ((~["\"","\\","\n","\r"])
424         | ("\\"
425                 ( ["n","t","b","r","f","\\","'","\""]
426                 | ["0"-"7"] ( ["0"-"7"] )?
427                 | ["0"-"3"] ["0"-"7"]
428                         ["0"-"7"]
429                 )
430                 )
431         )*
432         "\"">
433 |
434         <CHARACTER_LITERAL:
435         "'"
436         ((~["'","\\","\n","\r"])
437         | ("\\"
438                 (["n","t","b","r","f","\\","'","\""]
439                 | ["0"-"7"] ( ["0"-"7"] )?
440                 | ["0"-"3"] ["0"-"7"]
441                 ["0"-"7"]
442                 )
443                 )
444         )
445         "'">
446 |
447         < INTEGER_LITERAL:
448         <DECIMAL_LITERAL> (["l","L"])?
449       | <HEX_LITERAL> (["l","L"])?
450       | <OCTAL_LITERAL> (["l","L"])?>
451 |
452         < #DECIMAL_LITERAL: ["1"-"9"] (["0"-"9"])* >
453 |
454         < #HEX_LITERAL: "0" ["x","X"] (["0"-"9","a"-"f","A"-"F"])+ >
455 |
456         < #OCTAL_LITERAL: "0" (["0"-"7"])* >
457 |
458         < FLOATING_POINT_LITERAL:
459         <DECIMAL_FLOATING_POINT_LITERAL>
460       | <HEXADECIMAL_FLOATING_POINT_LITERAL> >
461 |
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"]>
467 |
468         < #DECIMAL_EXPONENT: ["e","E"] (["+","-"])? (["0"-"9"])+ >
469 |
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"])?>
473 |
474         < #HEXADECIMAL_EXPONENT: ["p","P"] (["+","-"])? (["0"-"9"])+ >
475 |
476         < #SPACE: (" " | "\t")+>
477 |
478         < #TO_END_OF_LINE: (~["\n"])+>
479 |
480         /* Macro token */
481         <INCLUDE: "#" (<SPACE>)? "include" <SPACE> (<STRING_LITERAL> | "<" (<LETTER> | <DOT>)+ ">")>
482 |
483         <DEFINE: "#" (<SPACE>)? <TO_END_OF_LINE>>
484 }
485
486 String Type() :
487 {
488         String type;
489         String str;
490         QualifiedName name;
491 }
492 {
493         { type = ""; }
494         ("const"
495         { type = "const"; }
496         )?
497         (((str = <STRUCT>.image | str = <CLASS>.image | str = <UNSIGNED>.image) { type = type + " " + str; })? 
498         (
499         name = ParseQualifiedName() {
500                 if (!type.equals(""))
501                         type = type + " " + name.fullName;
502                 else
503                         type = name.fullName;
504         })
505         )
506         ((str = "const".image {
507                 if (!type.equals(""))
508                         type = type + " " + str;
509                 else
510                         type = str;
511         }) |
512         (str = <STAR>.image {
513                 if (!type.equals(""))
514                         type = type + " " + str;
515                 else
516                         type = str;
517         }) |
518         (str = <AND>.image {
519                 if (!type.equals(""))
520                         type = type + " " + str;
521                 else
522                         type = str;
523         })
524         )*
525         {
526                 return type;
527         }
528 }
529
530 void Test() :
531 {
532         String str;     
533         FunctionHeader func;
534 }
535 {
536         /*
537         str = Type()
538         {
539                 System.out.println(str);
540         }
541         */
542         func = FuncDecl() 
543         {
544                 System.out.println(func);
545         }
546         
547 }
548
549 String ParameterizedName() :
550 {
551         String res = "";
552         String str;
553 }
554 {
555         (str = <IDENTIFIER>.image {res = str;})
556         ("<" str = Type() { res = res + "<" + str; }
557         ("," str = Type() { res = res + ", " + str; })* ">"
558         { res = res + ">"; }
559         )?
560         {
561                 return res;
562         }
563 }
564
565 FunctionHeader FuncDecl() :
566 {
567         String ret;
568         QualifiedName funcName;
569         ArrayList<VariableDeclaration> args;
570 }
571 {
572         (<STATIC> | <INLINE>)*
573         ret = Type() 
574         funcName = ParseQualifiedName() 
575         args = FormalParamList() 
576         {
577                 FunctionHeader res = new FunctionHeader(ret, funcName, args);
578                 //System.out.println(res);
579                 return res;
580         }
581 }
582
583 QualifiedName ParseQualifiedName() :
584 {
585         String qualifiedName, str;
586 }
587 {
588         { qualifiedName = ""; }
589         (str = ParameterizedName() { qualifiedName = qualifiedName + str; } )
590         ( <DOUBLECOLON> (str = ParameterizedName() { qualifiedName = qualifiedName +
591         "::" + str; }  ))*
592         {
593                 QualifiedName res = new QualifiedName(qualifiedName);
594                 //System.out.println(res);
595                 return res;
596         }
597 }
598
599 ArrayList<String> TemplateParamList() :
600 {
601         ArrayList<String> params;
602         String str;
603 }
604 {
605         {
606                 params = new ArrayList<String>();
607         }
608         <TEMPLATE>
609         "<"
610         (str = <IDENTIFIER>.image 
611         str = <IDENTIFIER>.image {params.add(str);})
612
613         ("," str = <IDENTIFIER>.image 
614         str = <IDENTIFIER>.image {params.add(str);})*
615         ">"
616         {
617                 //System.out.println(params);
618                 return params;
619         }
620 }
621
622 ArrayList<VariableDeclaration > FormalParamList() :
623 {
624         ArrayList<VariableDeclaration > typeParams;
625         VariableDeclaration varDecl;
626 }
627 {
628         {
629                 typeParams = new ArrayList<VariableDeclaration >();
630         }
631         "("
632         ((varDecl = TypeParam() {typeParams.add(varDecl);})
633         ((<COMMA> varDecl = TypeParam() {typeParams.add(varDecl);}))*)?
634         ")"
635         {
636                 return typeParams;
637         }
638 }
639
640 VariableDeclaration TypeParam() :
641 {
642         String type, param;
643 }
644 {
645         (type = Type()) (param = <IDENTIFIER>.image)
646         {
647                 return new VariableDeclaration(type, param);
648         }
649 }
650
651 ArrayList<String> C_CPP_CODE(ArrayList<String> headers) :
652 {
653         String text;
654         Token t;
655         boolean newLine = false;
656         boolean inTemplate = false;
657         ArrayList<String> content;
658         String header;
659 }
660 {
661         {
662                 text = "";
663                 t = new Token();
664                 content = new ArrayList<String>();
665         }
666         (
667         LOOKAHEAD(2)
668         (
669         t = <CONST> | t = <STRUCT> | t = <CLASS> | t = <UNSIGNED> |
670         (t = <TEMPLATE> { inTemplate = true;  })|
671         t = <STATIC> | t = <INLINE> |
672         (t = <INCLUDE>
673         {
674                 header = t.image;
675                 newLine = true;
676                 if (headers != null) {
677                         headers.add(header.substring(header.lastIndexOf(' ') + 1));
678                 }
679         })
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> |
688         t = <LESS_THAN> |
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> | 
696
697         t = <PLUS_EQUALS> |
698         t = <MINUS_EQUALS> |
699         t = <TIMES_EQUALS> |
700         t = <DIVIDE_EQUALS> |
701         t = <MOD_EQUALS> |
702         t = <XOR_EQUALS> |
703         t = <OR_EQUALS> |
704         t = <AND_EQUALS> |
705
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; } )
710         )
711         {
712                 if (text.equals("")) {
713                         text = t.image;
714                 } else {
715                         text = text + " " + t.image;
716                 }
717                 if (newLine) {
718                         content.add(text);
719                         text = "";
720                         newLine = false;
721                         inTemplate = false;
722                 }
723         }
724         )+
725
726         {
727                 if (content.size() == 0) {
728                         content.add(text);
729                 }
730                 return content;
731         }
732 }
733
734
735 void Parse(File f, ArrayList<String> content, ArrayList<Construct> constructs, ArrayList<String> headers) :
736 {
737         Construct inst;
738         ArrayList<String> code;
739 }
740 {
741         {
742                 _file = f;
743                 _content = content;
744                 _constructs = constructs;
745         }
746         ((inst = ParseSpec() { _constructs.add(inst); }) |
747         ((code = C_CPP_CODE(headers)) { _content.addAll(code); })
748         )* <EOF>
749 }
750
751 Construct ParseSpec() :
752 {
753         Construct res;  
754 }
755 {
756         (
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()
766         )
767         {
768                 //System.out.println(res);
769                 return res;
770         }
771 }
772
773 GlobalConstruct Global_construct() :
774 {
775         GlobalConstruct res;
776         SequentialDefineSubConstruct code;
777         HashMap<String, String> options;
778         String key, value;
779 }
780 {
781         {
782                 res = null;
783                 options = new HashMap<String, String>();
784         }
785                 <BEGIN> 
786                         (<OPTIONS>
787                                 ((key = <IDENTIFIER>.image)
788                                 <EQUALS>
789                                 (value = <IDENTIFIER>.image)
790                                 {
791                                         if (options.containsKey(key)) {
792                                                 throw new ParseException("Duplicate options!");
793                                         }
794                                         options.put(key, value);
795                                 }
796                                 <SEMI_COLON>
797                                 )*
798                         )?
799                         (code = Global_define())
800                         { res = new GlobalConstruct(_file, _content.size(), code, options); }
801                         (Interface_clusters(res))?
802                         (Happens_before(res))?
803                 <END>
804         {
805                 res.unfoldInterfaceCluster();
806                 return res;
807         }
808 }
809
810 SequentialDefineSubConstruct Global_define() :
811 {
812         ArrayList<String> initVar, defineFunc, code, declareStruct;
813         ArrayList<ArrayList<String>> defineFuncs;
814         ArrayList<VariableDeclaration> declareVars;
815         ArrayList<ArrayList<String>> declareStructs;
816         VariableDeclaration declareVar;
817
818 }
819 {
820         {
821                 declareVars = new ArrayList<VariableDeclaration>();
822                 initVar = null;
823                 defineFuncs = new ArrayList<ArrayList<String>>();
824                 declareStructs = new ArrayList<ArrayList<String>>();
825         }
826         <GLOBAL_DEFINE>
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); }))*
833         {
834                 SequentialDefineSubConstruct res = new
835                         SequentialDefineSubConstruct(declareStructs, declareVars, initVar, defineFuncs);
836                 //System.out.println(res);
837                 return res;
838         }
839 }
840
841 ConditionalInterface Conditional_interface() :
842 {
843         String interfaceName, hbConditionLabel;
844 }
845 {
846         {
847                 hbConditionLabel = "";
848         }
849         interfaceName = <IDENTIFIER>.image (<OPEN_PAREN> hbConditionLabel =
850         <IDENTIFIER>.image <CLOSE_PAREN>)?
851         {
852                 return new ConditionalInterface(interfaceName, hbConditionLabel);
853         }
854 }
855
856 void Interface_cluster(GlobalConstruct inst) :
857 {
858         String clusterName;
859         ConditionalInterface condInterface;
860 }
861 {
862         (clusterName= <IDENTIFIER>.image)
863         <EQUALS> <OPEN_BRACE>
864                 (condInterface = Conditional_interface()
865                 { inst.addInterface2Cluster(clusterName, condInterface); } 
866                 )
867                 (<COMMA> condInterface = Conditional_interface()
868                 { inst.addInterface2Cluster(clusterName, condInterface); } 
869                 )*
870         <CLOSE_BRACE>
871 }
872
873 void Interface_clusters(GlobalConstruct inst) :
874 {}
875 {
876         <INTERFACE_CLUSTER> (Interface_cluster(inst))+
877 }
878
879 void Happens_before(GlobalConstruct inst) :
880 {
881         ConditionalInterface left, right;       
882 }
883 {
884         <HAPPENS_BEFORE> 
885         (
886         left = Conditional_interface() <HB_SYMBOL> right = Conditional_interface()
887         { inst.addHBCondition(left, right); }
888         )+
889 }
890
891 InterfaceConstruct Interface() :
892 {
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;
900 }
901 {
902         {
903                 res = null;
904                 action = new ArrayList<String>();
905                 condition = "";
906                 idCode = "";
907                 check = "";
908                 postCheck = "";
909                 commitPointSet = new ArrayList<String>();
910                 hbConditions = new HashMap<String, String>();
911                 postAction = new ArrayList<String>();
912         }
913                 <BEGIN>
914                         <INTERFACE> (interfaceName = <IDENTIFIER>.image)
915                         <COMMIT_POINT_SET>
916                                 (commitPoint = <IDENTIFIER>.image
917                                 { commitPointSet.add(commitPoint); }
918                                 )
919                                 (<OR>
920                                         (commitPoint = <IDENTIFIER>.image)
921                                         {
922                                                 if (commitPointSet.contains(commitPoint)) {
923                                                         throw new ParseException(interfaceName + " has" +
924                                                                 "duplicate commit point labels");
925                                                 }
926                                                 commitPointSet.add(commitPoint);
927                                         }
928                                 )*
929
930                         (<CONDITION> (content = C_CPP_CODE(null) { condition = stringArray2String(content); }))?
931                         (
932                                 <HB_CONDITION>
933                                 (hbLabel = <IDENTIFIER>.image) <DOUBLECOLON>
934                                 (content = C_CPP_CODE(null) { hbCondition = stringArray2String(content); })
935                                 {
936                                         if (hbConditions.containsKey(hbLabel)) {
937                                                 throw new ParseException(interfaceName + " has" +
938                                                         "duplicate happens-before condtion labels");
939                                         }
940                                         hbConditions.put(hbLabel, hbCondition);
941                                 }
942                         )*
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); }))?
948                 <END>
949         {
950                 res = new InterfaceConstruct(_file, _content.size(), interfaceName, commitPointSet, condition,
951                         hbConditions, idCode, check, action, postAction, postCheck);
952                 return res;
953         }
954 }
955
956
957 PotentialCPDefineConstruct Potential_commit_point_define() :
958 {
959         PotentialCPDefineConstruct res;
960         String label, condition;
961         ArrayList<String> content;
962 }
963 {
964
965         { res = null; }
966                 <BEGIN>
967                         <POTENTIAL_COMMIT_POINT_DEFINE> (content = C_CPP_CODE(null) { condition = stringArray2String(content); })
968                         <LABEL> (label = <IDENTIFIER>.image)
969                 <END>
970         {
971                 res = new PotentialCPDefineConstruct(_file, _content.size(), label, condition); 
972                 return res;
973         }
974 }
975
976
977 CPDefineConstruct Commit_point_define() :
978 {
979         CPDefineConstruct res;
980         String label, potentialCPLabel, condition;
981         ArrayList<String> content;
982 }
983 {
984
985         { res = null; }
986                 <BEGIN>
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)
990                 <END>
991         {
992                 res = new CPDefineConstruct(_file, _content.size(), label, potentialCPLabel, condition);
993                 return res;
994         }
995 }
996
997
998 CPDefineCheckConstruct Commit_point_define_check() :
999 {
1000         CPDefineCheckConstruct res;     
1001         String label, condition;
1002         ArrayList<String> content;
1003 }
1004 {
1005
1006         { res = null; }
1007                 <BEGIN> 
1008                         <COMMIT_POINT_DEFINE_CHECK> (content = C_CPP_CODE(null) { condition = stringArray2String(content); })
1009                         <LABEL> (label = <IDENTIFIER>.image)
1010                 <END>
1011         {
1012                 res = new CPDefineCheckConstruct(_file, _content.size(), label, condition);
1013                 return res;
1014         }
1015 }
1016
1017 EntryPointConstruct Entry_point() :
1018 {}
1019 {
1020
1021                 <BEGIN> 
1022                         <ENTRY_POINT>
1023                 <END>
1024         {
1025                 return new EntryPointConstruct(_file, _content.size());
1026         }
1027 }
1028
1029 ClassBeginConstruct Class_begin() :
1030 {}
1031 {
1032
1033                 <BEGIN> 
1034                         <CLASS_BEGIN>
1035                 <END>
1036         {
1037                 return new ClassBeginConstruct(_file, _content.size());
1038         }
1039 }
1040
1041 ClassEndConstruct Class_end() :
1042 {}
1043 {
1044
1045                 <BEGIN> 
1046                         <CLASS_END>
1047                 <END>
1048         {
1049                 return new ClassEndConstruct(_file, _content.size());
1050         }
1051 }
1052
1053 InterfaceDefineConstruct Interface_define() :
1054 {
1055         String name;    
1056 }
1057 {
1058                 <BEGIN>
1059                         <INTERFACE_DEFINE> (name = <IDENTIFIER>.image)
1060                 <END>
1061         {
1062                 return new InterfaceDefineConstruct(_file, _content.size(), name);
1063         }
1064 }