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