more bug fix
[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         <SEMI_COLON: ";">
397 |
398         <STRING_LITERAL:
399         "\""
400         ((~["\"","\\","\n","\r"])
401         | ("\\"
402                 ( ["n","t","b","r","f","\\","'","\""]
403                 | ["0"-"7"] ( ["0"-"7"] )?
404                 | ["0"-"3"] ["0"-"7"]
405                         ["0"-"7"]
406                 )
407                 )
408         )*
409         "\"">
410 |
411         <CHARACTER_LITERAL:
412         "'"
413         ((~["'","\\","\n","\r"])
414         | ("\\"
415                 (["n","t","b","r","f","\\","'","\""]
416                 | ["0"-"7"] ( ["0"-"7"] )?
417                 | ["0"-"3"] ["0"-"7"]
418                 ["0"-"7"]
419                 )
420                 )
421         )
422         "'">
423 |
424         < INTEGER_LITERAL:
425         <DECIMAL_LITERAL> (["l","L"])?
426       | <HEX_LITERAL> (["l","L"])?
427       | <OCTAL_LITERAL> (["l","L"])?>
428 |
429         < #DECIMAL_LITERAL: ["1"-"9"] (["0"-"9"])* >
430 |
431         < #HEX_LITERAL: "0" ["x","X"] (["0"-"9","a"-"f","A"-"F"])+ >
432 |
433         < #OCTAL_LITERAL: "0" (["0"-"7"])* >
434 |
435         < FLOATING_POINT_LITERAL:
436         <DECIMAL_FLOATING_POINT_LITERAL>
437       | <HEXADECIMAL_FLOATING_POINT_LITERAL> >
438 |
439         < #DECIMAL_FLOATING_POINT_LITERAL:
440         (["0"-"9"])+ "." (["0"-"9"])* (<DECIMAL_EXPONENT>)? (["f","F","d","D"])?
441       | "." (["0"-"9"])+ (<DECIMAL_EXPONENT>)? (["f","F","d","D"])?
442       | (["0"-"9"])+ <DECIMAL_EXPONENT> (["f","F","d","D"])?
443       | (["0"-"9"])+ (<DECIMAL_EXPONENT>)? ["f","F","d","D"]>
444 |
445         < #DECIMAL_EXPONENT: ["e","E"] (["+","-"])? (["0"-"9"])+ >
446 |
447         < #HEXADECIMAL_FLOATING_POINT_LITERAL:
448         "0" ["x", "X"] (["0"-"9","a"-"f","A"-"F"])+ (".")? <HEXADECIMAL_EXPONENT> (["f","F","d","D"])?
449       | "0" ["x", "X"] (["0"-"9","a"-"f","A"-"F"])* "." (["0"-"9","a"-"f","A"-"F"])+ <HEXADECIMAL_EXPONENT> (["f","F","d","D"])?>
450 |
451         < #HEXADECIMAL_EXPONENT: ["p","P"] (["+","-"])? (["0"-"9"])+ >
452 |
453         < #SPACE: (" " | "\t")+>
454 |
455         < #TO_END_OF_LINE: (~["\n"])+>
456 |
457         /* Macro token */
458         <INCLUDE: "#" (<SPACE>)? "include" <SPACE> (<STRING_LITERAL> | "<" (<LETTER> | <DOT>)+ ">")>
459 |
460         <DEFINE: "#" (<SPACE>)? <TO_END_OF_LINE>>
461 }
462
463 String Type() :
464 {
465         String type;
466         String str;
467         QualifiedName name;
468 }
469 {
470         { type = ""; }
471         ("const"
472         { type = "const"; }
473         )?
474         (((str = <STRUCT>.image | str = <CLASS>.image | str = <UNSIGNED>.image) { type = type + " " + str; })? 
475         (
476         name = ParseQualifiedName() {
477                 if (!type.equals(""))
478                         type = type + " " + name.fullName;
479                 else
480                         type = name.fullName;
481         })
482         )
483         ((str = "const".image {
484                 if (!type.equals(""))
485                         type = type + " " + str;
486                 else
487                         type = str;
488         }) |
489         (str = <STAR>.image {
490                 if (!type.equals(""))
491                         type = type + " " + str;
492                 else
493                         type = str;
494         }) |
495         (str = <AND>.image {
496                 if (!type.equals(""))
497                         type = type + " " + str;
498                 else
499                         type = str;
500         })
501         )*
502         {
503                 return type;
504         }
505 }
506
507 void Test() :
508 {
509         String str;     
510         FunctionHeader func;
511 }
512 {
513         /*
514         str = Type()
515         {
516                 System.out.println(str);
517         }
518         */
519         func = FuncDecl() 
520         {
521                 System.out.println(func);
522         }
523         
524 }
525
526 String ParameterizedName() :
527 {
528         String res = "";
529         String str;
530 }
531 {
532         (str = <IDENTIFIER>.image {res = str;})
533         ("<" str = Type() { res = res + "<" + str; }
534         ("," str = Type() { res = res + ", " + str; })* ">"
535         { res = res + ">"; }
536         )?
537         {
538                 return res;
539         }
540 }
541
542 FunctionHeader FuncDecl() :
543 {
544         String ret;
545         QualifiedName funcName;
546         ArrayList<VariableDeclaration> args;
547 }
548 {
549         (<STATIC> | <INLINE>)*
550         ret = Type() 
551         funcName = ParseQualifiedName() 
552         args = FormalParamList() 
553         {
554                 FunctionHeader res = new FunctionHeader(ret, funcName, args);
555                 //System.out.println(res);
556                 return res;
557         }
558 }
559
560 QualifiedName ParseQualifiedName() :
561 {
562         String qualifiedName, str;
563 }
564 {
565         { qualifiedName = ""; }
566         (str = ParameterizedName() { qualifiedName = qualifiedName + str; } )
567         ( <DOUBLECOLON> (str = ParameterizedName() { qualifiedName = qualifiedName +
568         "::" + str; }  ))*
569         {
570                 QualifiedName res = new QualifiedName(qualifiedName);
571                 //System.out.println(res);
572                 return res;
573         }
574 }
575
576 ArrayList<String> TemplateParamList() :
577 {
578         ArrayList<String> params;
579         String str;
580 }
581 {
582         {
583                 params = new ArrayList<String>();
584         }
585         <TEMPLATE>
586         "<"
587         (str = <IDENTIFIER>.image 
588         str = <IDENTIFIER>.image {params.add(str);})
589
590         ("," str = <IDENTIFIER>.image 
591         str = <IDENTIFIER>.image {params.add(str);})*
592         ">"
593         {
594                 //System.out.println(params);
595                 return params;
596         }
597 }
598
599 ArrayList<VariableDeclaration > FormalParamList() :
600 {
601         ArrayList<VariableDeclaration > typeParams;
602         VariableDeclaration varDecl;
603 }
604 {
605         {
606                 typeParams = new ArrayList<VariableDeclaration >();
607         }
608         "("
609         ((varDecl = TypeParam() {typeParams.add(varDecl);})
610         ((<COMMA> varDecl = TypeParam() {typeParams.add(varDecl);}))*)?
611         ")"
612         {
613                 return typeParams;
614         }
615 }
616
617 VariableDeclaration TypeParam() :
618 {
619         String type, param;
620 }
621 {
622         (type = Type()) (param = <IDENTIFIER>.image)
623         {
624                 return new VariableDeclaration(type, param);
625         }
626 }
627
628 ArrayList<String> C_CPP_CODE(ArrayList<String> headers) :
629 {
630         String text;
631         Token t;
632         boolean newLine = false;
633         boolean inTemplate = false;
634         ArrayList<String> content;
635         String header;
636 }
637 {
638         {
639                 text = "";
640                 t = new Token();
641                 content = new ArrayList<String>();
642         }
643         (
644         LOOKAHEAD(2)
645         (
646         t = <CONST> | t = <STRUCT> | t = <CLASS> | t = <UNSIGNED> |
647         (t = <TEMPLATE> { inTemplate = true;  })|
648         t = <STATIC> | t = <INLINE> |
649         (t = <INCLUDE>
650         {
651                 header = t.image;
652                 newLine = true;
653                 if (headers != null) {
654                         headers.add(header.substring(header.lastIndexOf(' ') + 1));
655                 }
656         })
657         | t = <IDENTIFIER> | t = <POUND> |
658         (t = <OPEN_BRACE>  { newLine = true; } ) |
659         (t = <CLOSE_BRACE>  { newLine = true; } ) | 
660         t = <EQUALS> | t = <OPEN_PAREN> | t = <CLOSE_PAREN> | 
661         t = <OPEN_BRACKET> | t = <CLOSE_BRACKET>
662         | t = <HB_SYMBOL> | t = <COMMA> |
663         t = <DOT> | t = <STAR> | t = <NEGATE> | t = <EXCLAMATION> | t = <AND> | t = <OR> | t = <MOD> | t = <PLUS> |
664         t = <PLUSPLUS> | t = <MINUS> | t = <MINUSMINUS> | t = <DIVIDE> | t = <BACKSLASH> |
665         t = <LESS_THAN> |
666         (t = <GREATER_THAN> { if (inTemplate) newLine = true; }) |
667         t = <GREATER_EQUALS>    | t = <LESS_EQUALS> |
668         t = <LOGICAL_EQUALS> | t = <NOT_EQUALS> | t = <LOGICAL_AND> | t = <LOGICAL_OR> | t = <XOR> |
669         t = <QUESTION_MARK> | t = <COLON> | t = <DOUBLECOLON> |
670         (t = <SEMI_COLON> { newLine = true; } )
671         | t = <STRING_LITERAL> | t = <CHARACTER_LITERAL> |
672         t = <INTEGER_LITERAL> | t = <FLOATING_POINT_LITERAL> |
673         (t = <DEFINE> { newLine = true; } )
674         )
675         {
676                 if (text.equals("")) {
677                         text = t.image;
678                 } else {
679                         text = text + " " + t.image;
680                 }
681                 if (newLine) {
682                         content.add(text);
683                         text = "";
684                         newLine = false;
685                         inTemplate = false;
686                 }
687         }
688         )+
689
690         {
691                 if (content.size() == 0) {
692                         content.add(text);
693                 }
694                 return content;
695         }
696 }
697
698
699 void Parse(File f, ArrayList<String> content, ArrayList<Construct> constructs, ArrayList<String> headers) :
700 {
701         Construct inst;
702         ArrayList<String> code;
703 }
704 {
705         {
706                 _file = f;
707                 _content = content;
708                 _constructs = constructs;
709         }
710         ((inst = ParseSpec() { _constructs.add(inst); }) |
711         ((code = C_CPP_CODE(headers)) { _content.addAll(code); })
712         )* <EOF>
713 }
714
715 Construct ParseSpec() :
716 {
717         Construct res;  
718 }
719 {
720         (
721         LOOKAHEAD(2) res = Global_construct() |
722         LOOKAHEAD(2) res = Interface() |
723         LOOKAHEAD(2) res = Potential_commit_point_define() |
724         LOOKAHEAD(2) res = Commit_point_define() |
725         LOOKAHEAD(2) res = Commit_point_define_check() |
726         LOOKAHEAD(2) res = Entry_point() |
727         LOOKAHEAD(2) res = Class_begin() |
728         LOOKAHEAD(2) res = Class_end() |
729         LOOKAHEAD(2) res = Interface_define()
730         )
731         {
732                 //System.out.println(res);
733                 return res;
734         }
735 }
736
737 GlobalConstruct Global_construct() :
738 {
739         GlobalConstruct res;
740         SequentialDefineSubConstruct code;
741         HashMap<String, String> options;
742         String key, value;
743 }
744 {
745         {
746                 res = null;
747                 options = new HashMap<String, String>();
748         }
749                 <BEGIN> 
750                         (<OPTIONS>
751                                 ((key = <IDENTIFIER>.image)
752                                 <EQUALS>
753                                 (value = <IDENTIFIER>.image)
754                                 {
755                                         if (options.containsKey(key)) {
756                                                 throw new ParseException("Duplicate options!");
757                                         }
758                                         options.put(key, value);
759                                 }
760                                 <SEMI_COLON>
761                                 )*
762                         )?
763                         (code = Global_define())
764                         { res = new GlobalConstruct(_file, _content.size(), code, options); }
765                         (Interface_clusters(res))?
766                         (Happens_before(res))?
767                 <END>
768         {
769                 res.unfoldInterfaceCluster();
770                 return res;
771         }
772 }
773
774 SequentialDefineSubConstruct Global_define() :
775 {
776         ArrayList<String> initVar, defineFunc, code, declareStruct;
777         ArrayList<ArrayList<String>> defineFuncs;
778         ArrayList<VariableDeclaration> declareVars;
779         ArrayList<ArrayList<String>> declareStructs;
780         VariableDeclaration declareVar;
781
782 }
783 {
784         {
785                 declareVars = new ArrayList<VariableDeclaration>();
786                 initVar = null;
787                 defineFuncs = new ArrayList<ArrayList<String>>();
788                 declareStructs = new ArrayList<ArrayList<String>>();
789         }
790         <GLOBAL_DEFINE>
791         (<DECLARE_STRUCT> (declareStruct = C_CPP_CODE(null) {
792                 declareStructs.add(declareStruct); }))*
793                 (<DECLARE_VAR> ((declareVar = TypeParam() ";" {
794                         declareVars.add(declareVar); } )*))?
795         (<INIT_VAR> (code = C_CPP_CODE(null) { initVar = code; } ))?
796         (<DEFINE_FUNC> (defineFunc = C_CPP_CODE(null) { defineFuncs.add(defineFunc); }))*
797         {
798                 SequentialDefineSubConstruct res = new
799                         SequentialDefineSubConstruct(declareStructs, declareVars, initVar, defineFuncs);
800                 //System.out.println(res);
801                 return res;
802         }
803 }
804
805 ConditionalInterface Conditional_interface() :
806 {
807         String interfaceName, hbConditionLabel;
808 }
809 {
810         {
811                 hbConditionLabel = "";
812         }
813         interfaceName = <IDENTIFIER>.image (<OPEN_PAREN> hbConditionLabel =
814         <IDENTIFIER>.image <CLOSE_PAREN>)?
815         {
816                 return new ConditionalInterface(interfaceName, hbConditionLabel);
817         }
818 }
819
820 void Interface_cluster(GlobalConstruct inst) :
821 {
822         String clusterName;
823         ConditionalInterface condInterface;
824 }
825 {
826         (clusterName= <IDENTIFIER>.image)
827         <EQUALS> <OPEN_BRACE>
828                 (condInterface = Conditional_interface()
829                 { inst.addInterface2Cluster(clusterName, condInterface); } 
830                 )
831                 (<COMMA> condInterface = Conditional_interface()
832                 { inst.addInterface2Cluster(clusterName, condInterface); } 
833                 )*
834         <CLOSE_BRACE>
835 }
836
837 void Interface_clusters(GlobalConstruct inst) :
838 {}
839 {
840         <INTERFACE_CLUSTER> (Interface_cluster(inst))+
841 }
842
843 void Happens_before(GlobalConstruct inst) :
844 {
845         ConditionalInterface left, right;       
846 }
847 {
848         <HAPPENS_BEFORE> 
849         (
850         left = Conditional_interface() <HB_SYMBOL> right = Conditional_interface()
851         { inst.addHBCondition(left, right); }
852         )+
853 }
854
855 InterfaceConstruct Interface() :
856 {
857         InterfaceConstruct res;
858         String interfaceName, condition, idCode, check,
859                 postCheck, commitPoint, hbLabel, hbCondition;
860         ArrayList<String> commitPointSet;
861         ArrayList<String> action, postAction;
862         HashMap<String, String> hbConditions;
863         ArrayList<String> content;
864 }
865 {
866         {
867                 res = null;
868                 action = new ArrayList<String>();
869                 condition = "";
870                 idCode = "";
871                 check = "";
872                 postCheck = "";
873                 commitPointSet = new ArrayList<String>();
874                 hbConditions = new HashMap<String, String>();
875                 postAction = new ArrayList<String>();
876         }
877                 <BEGIN>
878                         <INTERFACE> (interfaceName = <IDENTIFIER>.image)
879                         <COMMIT_POINT_SET>
880                                 (commitPoint = <IDENTIFIER>.image
881                                 { commitPointSet.add(commitPoint); }
882                                 )
883                                 (<OR>
884                                         (commitPoint = <IDENTIFIER>.image)
885                                         {
886                                                 if (commitPointSet.contains(commitPoint)) {
887                                                         throw new ParseException(interfaceName + " has" +
888                                                                 "duplicate commit point labels");
889                                                 }
890                                                 commitPointSet.add(commitPoint);
891                                         }
892                                 )*
893
894                         (<CONDITION> (content = C_CPP_CODE(null) { condition = stringArray2String(content); }))?
895                         (
896                                 <HB_CONDITION>
897                                 (hbLabel = <IDENTIFIER>.image) <DOUBLECOLON>
898                                 (content = C_CPP_CODE(null) { hbCondition = stringArray2String(content); })
899                                 {
900                                         if (hbConditions.containsKey(hbLabel)) {
901                                                 throw new ParseException(interfaceName + " has" +
902                                                         "duplicate happens-before condtion labels");
903                                         }
904                                         hbConditions.put(hbLabel, hbCondition);
905                                 }
906                         )*
907                         (<ID> (content = C_CPP_CODE(null) { idCode = stringArray2String(content); }))?
908                         (<CHECK> (content = C_CPP_CODE(null) { check = stringArray2String(content); }))?
909                         (<ACTION> action = C_CPP_CODE(null))?
910                         (<POST_ACTION> (postAction = C_CPP_CODE(null) ))?
911                         (<POST_CHECK> (content = C_CPP_CODE(null) { postCheck = stringArray2String(content); }))?
912                 <END>
913         {
914                 res = new InterfaceConstruct(_file, _content.size(), interfaceName, commitPointSet, condition,
915                         hbConditions, idCode, check, action, postAction, postCheck);
916                 return res;
917         }
918 }
919
920
921 PotentialCPDefineConstruct Potential_commit_point_define() :
922 {
923         PotentialCPDefineConstruct res;
924         String label, condition;
925         ArrayList<String> content;
926 }
927 {
928
929         { res = null; }
930                 <BEGIN>
931                         <POTENTIAL_COMMIT_POINT_DEFINE> (content = C_CPP_CODE(null) { condition = stringArray2String(content); })
932                         <LABEL> (label = <IDENTIFIER>.image)
933                 <END>
934         {
935                 res = new PotentialCPDefineConstruct(_file, _content.size(), label, condition); 
936                 return res;
937         }
938 }
939
940
941 CPDefineConstruct Commit_point_define() :
942 {
943         CPDefineConstruct res;
944         String label, potentialCPLabel, condition;
945         ArrayList<String> content;
946 }
947 {
948
949         { res = null; }
950                 <BEGIN>
951                         <COMMIT_POINT_DEFINE> (content = C_CPP_CODE(null) { condition = stringArray2String(content); })
952                         <POTENTIAL_COMMIT_POINT_LABEL> (potentialCPLabel = <IDENTIFIER>.image)
953                         <LABEL> (label = <IDENTIFIER>.image)
954                 <END>
955         {
956                 res = new CPDefineConstruct(_file, _content.size(), label, potentialCPLabel, condition);
957                 return res;
958         }
959 }
960
961
962 CPDefineCheckConstruct Commit_point_define_check() :
963 {
964         CPDefineCheckConstruct res;     
965         String label, condition;
966         ArrayList<String> content;
967 }
968 {
969
970         { res = null; }
971                 <BEGIN> 
972                         <COMMIT_POINT_DEFINE_CHECK> (content = C_CPP_CODE(null) { condition = stringArray2String(content); })
973                         <LABEL> (label = <IDENTIFIER>.image)
974                 <END>
975         {
976                 res = new CPDefineCheckConstruct(_file, _content.size(), label, condition);
977                 return res;
978         }
979 }
980
981 EntryPointConstruct Entry_point() :
982 {}
983 {
984
985                 <BEGIN> 
986                         <ENTRY_POINT>
987                 <END>
988         {
989                 return new EntryPointConstruct(_file, _content.size());
990         }
991 }
992
993 ClassBeginConstruct Class_begin() :
994 {}
995 {
996
997                 <BEGIN> 
998                         <CLASS_BEGIN>
999                 <END>
1000         {
1001                 return new ClassBeginConstruct(_file, _content.size());
1002         }
1003 }
1004
1005 ClassEndConstruct Class_end() :
1006 {}
1007 {
1008
1009                 <BEGIN> 
1010                         <CLASS_END>
1011                 <END>
1012         {
1013                 return new ClassEndConstruct(_file, _content.size());
1014         }
1015 }
1016
1017 InterfaceDefineConstruct Interface_define() :
1018 {
1019         String name;    
1020 }
1021 {
1022                 <BEGIN>
1023                         <INTERFACE_DEFINE> (name = <IDENTIFIER>.image)
1024                 <END>
1025         {
1026                 return new InterfaceDefineConstruct(_file, _content.size(), name);
1027         }
1028 }