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