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