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                 # 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
113         public class SpecParser {
114                 private static ArrayList<String> _content;
115                 private static File _file;
116                 private static ArrayList<Construct> _constructs;
117
118                 public static void main(String[] argvs)
119                 throws ParseException, TokenMgrError {
120                         try {
121                                 File f = new File("./grammer/spec.txt");
122                                 FileInputStream fis = new FileInputStream(f);
123                                 SpecParser parser = new SpecParser(fis);
124                                 ArrayList<String> content = new ArrayList<String>();
125                                 ArrayList<Construct> constructs = new ArrayList<Construct>();
126                                 parser.Parse(f, content, constructs);
127                                 System.out.println("Parsing finished!");
128                         } catch (FileNotFoundException e) {
129                                 e.printStackTrace();
130                         }
131                 }
132
133                 public static void ParseFile(File f, ArrayList<String> content, ArrayList<Construct> constructs)
134                 throws ParseException, TokenMgrError {
135                         try {
136                                 InputStream input = new FileInputStream(f);
137                                 SpecParser parser = new SpecParser(input);
138                                 parser.Parse(f, content, constructs);
139                         } catch (FileNotFoundException e) {
140                                 e.printStackTrace();
141                         }
142                 }
143
144                 public static String stringArray2String(ArrayList<String> content) {
145                         StringBuilder sb = new StringBuilder();
146                         for (int i = 0; i < content.size(); i++) {
147                                 sb.append(content.get(i) + "\n");
148                         }
149                         return sb.toString();
150                 }
151
152         }
153 PARSER_END(SpecParser)
154
155
156
157 <*> SKIP :
158 {
159         " "
160 |
161         "\n"
162 |
163         "\r"
164 |
165         "\r\n"
166 |
167         "\t"
168 }
169
170 SKIP : {
171         "/**" : IN_POTENTIAL_SPEC
172 }
173
174 <IN_POTENTIAL_SPEC> TOKEN : {
175         <BEGIN: "@Begin"> : IN_SPEC
176 }
177
178 <IN_SPEC> SKIP : {
179         "*/" : DEFAULT
180 }
181
182 SKIP : {
183         "/*": IN_COMMENT
184 }
185
186 <*> SKIP : {
187         // "//" comment for the specification
188         <"//" (~["\n", "\r"])* (["\n", "\r"])>
189 }
190
191 <IN_COMMENT, IN_POTENTIAL_SPEC> SKIP : {
192         "*/": DEFAULT
193 }
194
195 <IN_COMMENT, IN_POTENTIAL_SPEC> SKIP : { <  ~[] > }
196
197 <IN_SPEC> SKIP :
198 {
199         // "#" comment for the specification
200         <"#" (~["\n", "\r"])* (["\n", "\r"])>
201 }
202
203
204 <IN_SPEC> TOKEN : {
205         <END: "@End">
206 |
207         <OPTIONS: "@Options:">
208 |
209         <GLOBAL_DEFINE: "@Global_define:">
210 |
211         <DECLARE_VAR: "@DeclareVar:">
212 |
213         <INIT_VAR: "@InitVar:">
214 |
215         <DEFINE_FUNC: "@DefineFunc:">
216 |
217         <INTERFACE_CLUSTER: "@Interface_cluster:">
218 |
219         <HAPPENS_BEFORE: "@Happens_before:">
220 |
221         <INTERFACE: "@Interface:">
222 |
223         <COMMIT_POINT_SET: "@Commit_point_set:">
224 |
225         <ENTRY_POINT: "@Entry_point">
226 |
227         <INTERFACE_DEFINE: "@Interface_define:">
228 |
229         <CONDITION: "@Condition:">
230 |
231         <HB_CONDITION: "@HB_condition:">
232 |
233         <ID: "@ID:">
234 |
235         <CHECK: "@Check:">
236 |
237         <ACTION: "@Action:">
238 |
239         <DEFINEVAR: "@DefineVar:">
240 |
241         <CODE: "@Code:">
242 |
243         <POST_ACTION: "@Post_action:">
244 |
245         <POST_CHECK: "@Post_check:">
246 |
247         <POTENTIAL_COMMIT_POINT_DEFINE: "@Potential_commit_point_define:">
248 |
249         <LABEL: "@Label:">
250 |
251         <COMMIT_POINT_DEFINE_CHECK: "@Commit_point_define_check:">
252 |
253         <COMMIT_POINT_DEFINE: "@Commit_point_define:">
254 |
255         <POTENTIAL_COMMIT_POINT_LABEL: "@Potential_commit_point_label:">
256 }
257
258
259 <IN_SPEC, DEFAULT> TOKEN :
260 {
261 /*   Specification & C/C++ shared tokens   */
262 // Reserved keywords
263         <CONST: "const">
264 |
265         <STRUCT: "struct">
266 |
267         <TYPENAME: "typename">
268 |
269         <#DIGIT: ["0"-"9"]>
270 |
271         <#LETTER: ["a"-"z", "A"-"Z"]>
272 |
273         <IDENTIFIER: (<LETTER> | "_") (<LETTER> | <DIGIT> | "_")*>
274 |
275         <POUND: "#">
276 |
277         <OPEN_BRACKET: "[">
278 |
279         <CLOSE_BRACKET: "]">
280 |
281         <EQUALS: "=">
282 |
283         <OPEN_PAREN: "(">
284 |
285         <CLOSE_PAREN: ")">
286 |
287         <OPEN_BRACE: "{">
288 |
289         <CLOSE_BRACE: "}">
290 |
291         <HB_SYMBOL: "->">
292 |
293         <COMMA: ",">
294
295 |
296 /*   C/C++ only token*/
297         <DOT: ".">
298 |
299         <STAR: "*">
300 |
301         <NEGATE: "~">
302 |
303         <EXCLAMATION: "!">
304 |
305         <AND: "&">
306 |
307         <OR: "|">
308 |
309         <MOD: "%">
310 |
311         <PLUS: "+">
312 |
313         <PLUSPLUS: "++">
314 |
315         <MINUS: "-">
316 |
317         <MINUSMINUS: "--">
318 |
319         <DIVIDE: "/">
320 |
321         <BACKSLASH: "\\">
322 |
323         <LESS_THAN: "<">
324 |
325         <GREATER_THAN: ">">
326 |
327         <GREATER_EQUALS: ">=">
328 |
329         <LESS_EQUALS: "<=">
330 |
331         <LOGICAL_EQUALS: "==">
332 |
333         <NOT_EQUALS: "!=">
334 |
335         <LOGICAL_AND: "&&">
336 |
337         <LOGICAL_OR: "||">
338 |
339         <XOR: "^">
340 |
341         <QUESTION_MARK: "?">
342 |
343         <COLON: ":">
344 |
345         <DOUBLECOLON: "::">
346 |
347         <SEMI_COLON: ";">
348 |
349         <STRING_LITERAL:
350         "\""
351         ((~["\"","\\","\n","\r"])
352         | ("\\"
353                 ( ["n","t","b","r","f","\\","'","\""]
354                 | ["0"-"7"] ( ["0"-"7"] )?
355                 | ["0"-"3"] ["0"-"7"]
356                         ["0"-"7"]
357                 )
358                 )
359         )*
360         "\"">
361 |
362         <CHARACTER_LITERAL:
363         "'"
364         ((~["'","\\","\n","\r"])
365         | ("\\"
366                 (["n","t","b","r","f","\\","'","\""]
367                 | ["0"-"7"] ( ["0"-"7"] )?
368                 | ["0"-"3"] ["0"-"7"]
369                 ["0"-"7"]
370                 )
371                 )
372         )
373         "'">
374 |
375         < INTEGER_LITERAL:
376         <DECIMAL_LITERAL> (["l","L"])?
377       | <HEX_LITERAL> (["l","L"])?
378       | <OCTAL_LITERAL> (["l","L"])?>
379 |
380         < #DECIMAL_LITERAL: ["1"-"9"] (["0"-"9"])* >
381 |
382         < #HEX_LITERAL: "0" ["x","X"] (["0"-"9","a"-"f","A"-"F"])+ >
383 |
384         < #OCTAL_LITERAL: "0" (["0"-"7"])* >
385 |
386         < FLOATING_POINT_LITERAL:
387         <DECIMAL_FLOATING_POINT_LITERAL>
388       | <HEXADECIMAL_FLOATING_POINT_LITERAL> >
389 |
390         < #DECIMAL_FLOATING_POINT_LITERAL:
391         (["0"-"9"])+ "." (["0"-"9"])* (<DECIMAL_EXPONENT>)? (["f","F","d","D"])?
392       | "." (["0"-"9"])+ (<DECIMAL_EXPONENT>)? (["f","F","d","D"])?
393       | (["0"-"9"])+ <DECIMAL_EXPONENT> (["f","F","d","D"])?
394       | (["0"-"9"])+ (<DECIMAL_EXPONENT>)? ["f","F","d","D"]>
395 |
396         < #DECIMAL_EXPONENT: ["e","E"] (["+","-"])? (["0"-"9"])+ >
397 |
398         < #HEXADECIMAL_FLOATING_POINT_LITERAL:
399         "0" ["x", "X"] (["0"-"9","a"-"f","A"-"F"])+ (".")? <HEXADECIMAL_EXPONENT> (["f","F","d","D"])?
400       | "0" ["x", "X"] (["0"-"9","a"-"f","A"-"F"])* "." (["0"-"9","a"-"f","A"-"F"])+ <HEXADECIMAL_EXPONENT> (["f","F","d","D"])?>
401 |
402         < #HEXADECIMAL_EXPONENT: ["p","P"] (["+","-"])? (["0"-"9"])+ >
403 |
404         < #SPACE: (" " | "\t")+>
405 |
406         < #TO_END_OF_LINE: (~["\n"])+>
407 |
408         /* Macro token */
409         <INCLUDE: "#" (<SPACE>)? "include" <SPACE> (<STRING_LITERAL> | "<" (<LETTER> | <DOT>)+ ">")>
410 |
411         <DEFINE: "#" (<SPACE>)? <TO_END_OF_LINE>>
412 }
413
414 String Type() :
415 {
416         String type;
417         String str;
418 }
419 {
420         { type = ""; }
421         ("const"
422         { type = "const"; }
423         )?
424         (("struct" { type = type + " struct"; })? 
425         (str = <IDENTIFIER>.image {
426                 if (!type.equals(""))
427                         type = type + " " + str;
428                 else
429                         type = str;
430         }))
431         ((str = "const".image {
432                 if (!type.equals(""))
433                         type = type + " " + str;
434                 else
435                         type = str;
436         }) |
437         (str = <STAR>.image {
438                 if (!type.equals(""))
439                         type = type + " " + str;
440                 else
441                         type = str;
442         }) |
443         (str = <AND>.image {
444                 if (!type.equals(""))
445                         type = type + " " + str;
446                 else
447                         type = str;
448         })
449         )*
450         {
451                 return type;
452         }
453 }
454
455 ArrayList<String> FormalParamList() :
456 {
457         ArrayList<String> typeParams;
458 }
459 {
460         {
461                 typeParams = new ArrayList<String>();
462         }
463         (TypeParam(typeParams) (<COMMA> TypeParam(typeParams))*)?
464         {
465                 System.out.println(typeParams);
466                 return typeParams;
467         }
468 }
469
470 void TypeParam(ArrayList<String> typeParams) :
471 {
472         String type, param;
473 }
474 {
475         (type = Type()) (param = <IDENTIFIER>.image)
476         {
477                 typeParams.add(type);
478                 typeParams.add(param);
479         }
480 }
481
482 ArrayList<String> C_CPP_CODE() :
483 {
484         String text;
485         Token t;
486         boolean newLine = false;
487         ArrayList<String> content;
488 }
489 {
490         {
491                 text = "";
492                 t = new Token();
493                 content = new ArrayList<String>();
494         }
495         (
496         LOOKAHEAD(2)
497         (
498         t = <CONST> | t = <STRUCT> | t = <TYPENAME> |
499         t = <IDENTIFIER> | t = <POUND> |
500         (t = <OPEN_BRACE>  { newLine = true; } ) |
501         (t = <CLOSE_BRACE>  { newLine = true; } ) | 
502         t = <EQUALS> | t = <OPEN_PAREN> | t = <CLOSE_PAREN> | 
503         t = <OPEN_BRACKET> | t = <CLOSE_BRACKET>
504         | t = <HB_SYMBOL> | t = <COMMA> |
505         t = <DOT> | t = <STAR> | t = <NEGATE> | t = <EXCLAMATION> | t = <AND> | t = <OR> | t = <MOD> | t = <PLUS> |
506         t = <PLUSPLUS> | t = <MINUS> | t = <MINUSMINUS> | t = <DIVIDE> | t = <BACKSLASH> |
507         t = <LESS_THAN> | t = <GREATER_THAN> | t = <GREATER_EQUALS>     | t = <LESS_EQUALS> |
508         t = <LOGICAL_EQUALS> | t = <NOT_EQUALS> | t = <LOGICAL_AND> | t = <LOGICAL_OR> | t = <XOR> |
509         t = <QUESTION_MARK> | t = <COLON> | t = <DOUBLECOLON> |
510         (t = <SEMI_COLON> { newLine = true; } )
511         | t = <STRING_LITERAL> | t = <CHARACTER_LITERAL> |
512         t = <INTEGER_LITERAL> | t = <FLOATING_POINT_LITERAL> |
513         (t = <INCLUDE> { newLine = true; } ) |
514         (t = <DEFINE> { newLine = true; } )
515         )
516         {
517                 text = text + " " + t.image;
518                 if (newLine) {
519                         content.add(text);
520                         text = "";
521                         newLine = false;
522                 }
523         }
524         )+
525
526         {
527                 return content;
528         }
529 }
530
531
532 void Parse(File f, ArrayList<String> content, ArrayList<Construct> constructs) :
533 {
534         Construct inst;
535         ArrayList<String> code;
536 }
537 {
538         {
539                 _file = f;
540                 _content = content;
541                 _constructs = constructs;
542         }
543         ((inst = ParseSpec() { _constructs.add(inst); }) |
544         ((code = C_CPP_CODE()) { _content.addAll(code); })
545         )* <EOF>
546 }
547
548 Construct ParseSpec() :
549 {
550         Construct res;  
551 }
552 {
553         (
554         LOOKAHEAD(2) res = Global_construct() |
555         LOOKAHEAD(2) res = Interface() |
556         LOOKAHEAD(2) res = Potential_commit_point_define() |
557         LOOKAHEAD(2) res = Commit_point_define() |
558         LOOKAHEAD(2) res = Commit_point_define_check() |
559         LOOKAHEAD(2) res = Entry_point() |
560         LOOKAHEAD(2) res = Interface_define()
561         )
562         {
563                 //System.out.println(res);
564                 return res;
565         }
566 }
567
568 GlobalConstruct Global_construct() :
569 {
570         GlobalConstruct res;
571         SequentialDefineSubConstruct code;
572         HashMap<String, String> options;
573         String key, value;
574 }
575 {
576         {
577                 res = null;
578                 options = new HashMap<String, String>();
579         }
580                 <BEGIN> 
581                         (<OPTIONS>
582                                 ((key = <IDENTIFIER>.image)
583                                 <EQUALS>
584                                 (value = <IDENTIFIER>.image)
585                                 {
586                                         if (options.containsKey(key)) {
587                                                 throw new ParseException("Duplicate options!");
588                                         }
589                                         options.put(key, value);
590                                 }
591                                 <SEMI_COLON>
592                                 )*
593                         )?
594                         (code = Global_define())
595                         { res = new GlobalConstruct(_file, _content.size(), code, options); }
596                         (Interface_clusters(res))?
597                         (Happens_before(res))?
598                 <END>
599         {
600                 res.unfoldInterfaceCluster();
601                 return res;
602         }
603 }
604
605 SequentialDefineSubConstruct Global_define() :
606 {
607         String declareVar, initVar, defineFunc;
608         ArrayList<String> code;
609 }
610 {
611         {
612                 declareVar = "";
613                 initVar = "";
614                 defineFunc = "";
615         }
616         <GLOBAL_DEFINE>
617                 (<DECLARE_VAR> (code = C_CPP_CODE() { declareVar = stringArray2String(code); } ))?
618         (<INIT_VAR> (code = C_CPP_CODE() { initVar = stringArray2String(code); } ))?
619         (<DEFINE_FUNC> (code = C_CPP_CODE() { defineFunc = stringArray2String(code); }))?
620         {
621                 SequentialDefineSubConstruct res = new SequentialDefineSubConstruct(declareVar, initVar, defineFunc);
622                 //System.out.println(res);
623                 return res;
624         }
625 }
626
627 ConditionalInterface Conditional_interface() :
628 {
629         String interfaceName, hbConditionLabel;
630 }
631 {
632         {
633                 hbConditionLabel = "";
634         }
635         interfaceName = <IDENTIFIER>.image (<OPEN_BRACKET> hbConditionLabel =
636         <IDENTIFIER>.image <CLOSE_BRACKET>)?
637         {
638                 return new ConditionalInterface(interfaceName, hbConditionLabel);
639         }
640 }
641
642 void Interface_cluster(GlobalConstruct inst) :
643 {
644         String clusterName;
645         ConditionalInterface condInterface;
646 }
647 {
648         (clusterName= <IDENTIFIER>.image)
649         <EQUALS> <OPEN_PAREN>
650                 (condInterface = Conditional_interface()
651                 { inst.addInterface2Cluster(clusterName, condInterface); } 
652                 )
653                 (<COMMA> condInterface = Conditional_interface()
654                 { inst.addInterface2Cluster(clusterName, condInterface); } 
655                 )*
656         <CLOSE_PAREN>
657 }
658
659 void Interface_clusters(GlobalConstruct inst) :
660 {}
661 {
662         <INTERFACE_CLUSTER> (Interface_cluster(inst))+
663 }
664
665 void Happens_before(GlobalConstruct inst) :
666 {
667         ConditionalInterface left, right;       
668 }
669 {
670         <HAPPENS_BEFORE> 
671         (
672         left = Conditional_interface() <HB_SYMBOL> right = Conditional_interface()
673         { inst.addHBCondition(left, right); }
674         )+
675 }
676
677 InterfaceConstruct Interface() :
678 {
679         InterfaceConstruct res;
680         String interfaceName, condition, idCode, check, postAction,
681                 postCheck, commitPoint, hbLabel, hbCondition;
682         ActionSubConstruct action;
683         ArrayList<String> commitPointSet;
684         HashMap<String, String> hbConditions;
685         ArrayList<String> content;
686 }
687 {
688         {
689                 res = null;
690                 action = null;
691                 condition = "";
692                 idCode = "";
693                 check = "";
694                 postAction = "";
695                 postCheck = "";
696                 commitPointSet = new ArrayList<String>();
697                 hbConditions = new HashMap<String, String>();
698         }
699                 <BEGIN>
700                         <INTERFACE> (interfaceName = <IDENTIFIER>.image)
701                         <COMMIT_POINT_SET>
702                                 (commitPoint = <IDENTIFIER>.image
703                                 { commitPointSet.add(commitPoint); }
704                                 )
705                                 (<OR>
706                                         (commitPoint = <IDENTIFIER>.image)
707                                         {
708                                                 if (commitPointSet.contains(commitPoint)) {
709                                                         throw new ParseException(interfaceName + " has" +
710                                                                 "duplicate commit point labels");
711                                                 }
712                                                 commitPointSet.add(commitPoint);
713                                         }
714                                 )*
715
716                         (<CONDITION> (content = C_CPP_CODE() { condition = stringArray2String(content); }))?
717                         (
718                                 <HB_CONDITION>
719                                 (hbLabel = <IDENTIFIER>.image)
720                                 (content = C_CPP_CODE() { hbCondition = stringArray2String(content); })
721                                 {
722                                         if (hbConditions.containsKey(hbLabel)) {
723                                                 throw new ParseException(interfaceName + " has" +
724                                                         "duplicate happens-before condtion labels");
725                                         }
726                                         hbConditions.put(hbLabel, hbCondition);
727                                 }
728                         )*
729                         (<ID> (content = C_CPP_CODE() { idCode = stringArray2String(content); }))?
730                         (<CHECK> (content = C_CPP_CODE() { check = stringArray2String(content); }))?
731                         (action = Action())?
732                         (<POST_ACTION> (content = C_CPP_CODE() { postAction = stringArray2String(content); }))?
733                         (<POST_CHECK> (content = C_CPP_CODE() { postCheck = stringArray2String(content); }))?
734                 <END>
735         {
736                 res = new InterfaceConstruct(_file, _content.size(), interfaceName, commitPointSet, condition,
737                         hbConditions, idCode, check, action, postAction, postCheck);
738                 return res;
739         }
740 }
741
742 ActionSubConstruct Action() :
743 {
744         String type, name, expr, defineVarStr, code;
745         ArrayList<DefineVar> defineVars;
746         ArrayList<String> content;
747 }
748 {
749         {
750                 defineVars = new ArrayList<DefineVar>();
751                 code = "";
752         }
753         <ACTION>
754         (
755                 (
756                 (<DEFINEVAR> (content = C_CPP_CODE() { defineVarStr = stringArray2String(content); }) 
757                 {
758                         int eqIdx = defineVarStr.indexOf('=');
759                         int typeEnd = defineVarStr.lastIndexOf(' ', eqIdx - 2);
760                         type = defineVarStr.substring(0, typeEnd);
761                         name = defineVarStr.substring(typeEnd + 1, eqIdx - 1);
762                         expr = defineVarStr.substring(eqIdx + 2);
763                         DefineVar defineVar = new DefineVar(type, name, expr);
764                         defineVars.add(defineVar);
765                 })*  (<CODE> (content = C_CPP_CODE() { code = stringArray2String(content); }))? ) 
766         )
767         
768         {
769                 ActionSubConstruct res = new ActionSubConstruct(defineVars, code);
770                 return res;
771         }
772 }
773
774 PotentialCPDefineConstruct Potential_commit_point_define() :
775 {
776         PotentialCPDefineConstruct res;
777         String label, condition;
778         ArrayList<String> content;
779 }
780 {
781
782         { res = null; }
783                 <BEGIN>
784                         <POTENTIAL_COMMIT_POINT_DEFINE> (content = C_CPP_CODE() { condition = stringArray2String(content); })
785                         <LABEL> (label = <IDENTIFIER>.image)
786                 <END>
787         {
788                 res = new PotentialCPDefineConstruct(_file, _content.size(), label, condition); 
789                 return res;
790         }
791 }
792
793
794 CPDefineConstruct Commit_point_define() :
795 {
796         CPDefineConstruct res;
797         String label, potentialCPLabel, condition;
798         ArrayList<String> content;
799 }
800 {
801
802         { res = null; }
803                 <BEGIN>
804                         <COMMIT_POINT_DEFINE> (content = C_CPP_CODE() { condition = stringArray2String(content); })
805                         <POTENTIAL_COMMIT_POINT_LABEL> (potentialCPLabel = <IDENTIFIER>.image)
806                         <LABEL> (label = <IDENTIFIER>.image)
807                 <END>
808         {
809                 res = new CPDefineConstruct(_file, _content.size(), label, potentialCPLabel, condition);
810                 return res;
811         }
812 }
813
814
815 CPDefineCheckConstruct Commit_point_define_check() :
816 {
817         CPDefineCheckConstruct res;     
818         String label, condition;
819         ArrayList<String> content;
820 }
821 {
822
823         { res = null; }
824                 <BEGIN> 
825                         <COMMIT_POINT_DEFINE_CHECK> (content = C_CPP_CODE() { condition = stringArray2String(content); })
826                         <LABEL> (label = <IDENTIFIER>.image)
827                 <END>
828         {
829                 res = new CPDefineCheckConstruct(_file, _content.size(), label, condition);
830                 return res;
831         }
832 }
833
834 EntryPointConstruct Entry_point() :
835 {}
836 {
837
838                 <BEGIN> 
839                         <ENTRY_POINT>
840                 <END>
841         {
842                 return new EntryPointConstruct(_file, _content.size());
843         }
844 }
845
846 InterfaceDefineConstruct Interface_define() :
847 {
848         String name;    
849 }
850 {
851                 <BEGIN>
852                         <INTERFACE_DEFINE> (name = <IDENTIFIER>.image)
853                 <END>
854         {
855                 return new InterfaceDefineConstruct(_file, _content.size(), name);
856         }
857 }