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