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