more data structures
[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<VariableDeclaration> 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                 boolean spaceSeparator(Token t) {
211                         switch (t.image) {
212                                 case "[":
213                                 case "]":
214                                 case "=":
215                                 case "(":
216                                 case ")":
217                                 case ",":
218                                 case ".":
219                                 case "*":
220                                 case "~":
221                                 case "!":
222                                 case "&":
223                                 case "|":
224                                 case "%":
225                                 case "+":
226                                 case "-":
227                                 case "/":
228                                 case "<":
229                                 case ">":
230                                 case "<=":
231                                 case ">=":
232                                 case "==":
233                                 case "!=":
234                                 case "&&":
235                                 case "||":
236                                 case "^":
237                                 case "?":
238                                 case ":":
239                                 case "::":
240                                 case "<<":
241                                 case ">>":
242                                 case ">>>":
243                                 case "+=":
244                                 case "-=":
245                                 case "*=":
246                                 case "/=":
247                                 case "%=":
248                                 case "^=":
249                                 case "&=":
250                                 case ";":
251                                         return false;
252                                 default:
253                                         return true;
254                         }
255                 }
256                 */
257
258         }
259 PARSER_END(SpecParser)
260
261
262
263 <*> SKIP :
264 {
265         " "
266 |
267         "\n"
268 |
269         "\r"
270 |
271         "\r\n"
272 |
273         "\t"
274 }
275
276 SKIP : {
277         "/**" : IN_POTENTIAL_SPEC
278 }
279
280 <IN_POTENTIAL_SPEC> TOKEN : {
281         <BEGIN: "@Begin"> : IN_SPEC
282 }
283
284 <IN_SPEC> SKIP : {
285         "*/" : DEFAULT
286 }
287
288 SKIP : {
289         "/*": IN_COMMENT
290 }
291
292 <*> SKIP : {
293         // "//" comment for the specification
294         <"//" (~["\n", "\r"])* (["\n", "\r"])>
295 }
296
297 <IN_COMMENT, IN_POTENTIAL_SPEC> SKIP : {
298         "*/": DEFAULT
299 }
300
301 <IN_COMMENT, IN_POTENTIAL_SPEC> SKIP : { <  ~[] > }
302
303 <IN_SPEC> SKIP :
304 {
305         // "#" comment for the specification
306         <"#" (~["\n", "\r"])* (["\n", "\r"])>
307 }
308
309
310 <IN_SPEC> TOKEN : {
311         <END: "@End">
312 |
313         <OPTIONS: "@Options:">
314 |
315         <GLOBAL_DEFINE: "@Global_define:">
316 |
317         <DECLARE_STRUCT: "@DeclareStruct:">
318 |
319         <DECLARE_VAR: "@DeclareVar:">
320 |
321         <INIT_VAR: "@InitVar:">
322 |
323         <DEFINE_FUNC: "@DefineFunc:">
324 |
325         <INTERFACE_CLUSTER: "@Interface_cluster:">
326 |
327         <HAPPENS_BEFORE: "@Happens_before:">
328 |
329         <INTERFACE: "@Interface:">
330 |
331         <COMMIT_POINT_SET: "@Commit_point_set:">
332 |
333         <ENTRY_POINT: "@Entry_point">
334 |
335         <CLASS_BEGIN: "@Class_begin">
336 |
337         <CLASS_END: "@Class_end">
338 |
339         <INTERFACE_DEFINE: "@Interface_define:">
340 |
341         <CONDITION: "@Condition:">
342 |
343         <HB_CONDITION: "@HB_condition:">
344 |
345         <ID: "@ID:">
346 |
347         <CHECK: "@Check:">
348 |
349         <ACTION: "@Action:">
350 |
351         <CODE: "@Code:">
352 |
353         <POST_ACTION: "@Post_action:">
354 |
355         <POST_CHECK: "@Post_check:">
356 |
357         <POTENTIAL_COMMIT_POINT_DEFINE: "@Potential_commit_point_define:">
358 |
359         <LABEL: "@Label:">
360 |
361         <COMMIT_POINT_DEFINE_CHECK: "@Commit_point_define_check:">
362 |
363         <COMMIT_POINT_DEFINE: "@Commit_point_define:">
364 |
365         <POTENTIAL_COMMIT_POINT_LABEL: "@Potential_commit_point_label:">
366 }
367
368
369 <IN_SPEC, DEFAULT> TOKEN :
370 {
371 /*   Specification & C/C++ shared tokens   */
372 // Reserved keywords
373         <CONST: "const">
374 |
375         <STRUCT: "struct">
376 |
377         <CLASS: "class">
378 |
379         <UNSIGNED: "unsigned">
380 |
381         <TEMPLATE: "template">
382 |
383         <INLINE: "inline">
384 |
385         <STATIC: "static">
386 |
387         <FOR: "for">
388 |
389         <#DIGIT: ["0"-"9"]>
390 |
391         <#LETTER: ["a"-"z", "A"-"Z"]>
392 |
393         <IDENTIFIER: (<LETTER> | "_") (<LETTER> | <DIGIT> | "_")*>
394 |
395         <POUND: "#">
396 |
397         <OPEN_BRACKET: "[">
398 |
399         <CLOSE_BRACKET: "]">
400 |
401         <EQUALS: "=">
402 |
403         <OPEN_PAREN: "(">
404 |
405         <CLOSE_PAREN: ")">
406 |
407         <OPEN_BRACE: "{">
408 |
409         <CLOSE_BRACE: "}">
410 |
411         <HB_SYMBOL: "->">
412 |
413         <COMMA: ",">
414 |
415 /*   C/C++ only token*/
416         <DOT: ".">
417 |
418         <STAR: "*">
419 |
420         <NEGATE: "~">
421 |
422         <EXCLAMATION: "!">
423 |
424         <AND: "&">
425 |
426         <OR: "|">
427 |
428         <MOD: "%">
429 |
430         <PLUS: "+">
431 |
432         <PLUSPLUS: "++">
433 |
434         <MINUS: "-">
435 |
436         <MINUSMINUS: "--">
437 |
438         <DIVIDE: "/">
439 |
440         <BACKSLASH: "\\">
441 |
442         <LESS_THAN: "<">
443 |
444         <GREATER_THAN: ">">
445 |
446         <GREATER_EQUALS: ">=">
447 |
448         <LESS_EQUALS: "<=">
449 |
450         <LOGICAL_EQUALS: "==">
451 |
452         <NOT_EQUALS: "!=">
453 |
454         <LOGICAL_AND: "&&">
455 |
456         <LOGICAL_OR: "||">
457 |
458         <XOR: "^">
459 |
460         <QUESTION_MARK: "?">
461 |
462         <COLON: ":">
463 |
464         <DOUBLECOLON: "::">
465 |
466         <DOUBLELESSTHAN: "<<">
467 |
468         <DOUBLEGREATERTHAN: ">>">
469 |
470         <TRIPLEGREATERTHAN: ">>>">
471 |
472         <PLUS_EQUALS: "+=">
473 |
474         <MINUS_EQUALS: "-=">
475 |
476         <TIMES_EQUALS: "*=">
477 |
478         <DIVIDE_EQUALS: "/=">
479 |
480         <MOD_EQUALS: "%=">
481 |
482         <XOR_EQUALS: "^=">
483 |
484         <OR_EQUALS: "|=">
485 |
486         <AND_EQUALS: "&=">
487 |
488         <SEMI_COLON: ";">
489 |
490         <STRING_LITERAL:
491         "\""
492         ((~["\"","\\","\n","\r"])
493         | ("\\"
494                 ( ["n","t","b","r","f","\\","'","\""]
495                 | ["0"-"7"] ( ["0"-"7"] )?
496                 | ["0"-"3"] ["0"-"7"]
497                         ["0"-"7"]
498                 )
499                 )
500         )*
501         "\"">
502 |
503         <CHARACTER_LITERAL:
504         "'"
505         ((~["'","\\","\n","\r"])
506         | ("\\"
507                 (["n","t","b","r","f","\\","'","\""]
508                 | ["0"-"7"] ( ["0"-"7"] )?
509                 | ["0"-"3"] ["0"-"7"]
510                 ["0"-"7"]
511                 )
512                 )
513         )
514         "'">
515 |
516         < INTEGER_LITERAL:
517         <DECIMAL_LITERAL> (["l","L"])?
518       | <HEX_LITERAL> (["l","L"])?
519       | <OCTAL_LITERAL> (["l","L"])?>
520 |
521         < #DECIMAL_LITERAL: ["1"-"9"] (["0"-"9"])* >
522 |
523         < #HEX_LITERAL: "0" ["x","X"] (["0"-"9","a"-"f","A"-"F"])+ >
524 |
525         < #OCTAL_LITERAL: "0" (["0"-"7"])* >
526 |
527         < FLOATING_POINT_LITERAL:
528         <DECIMAL_FLOATING_POINT_LITERAL>
529       | <HEXADECIMAL_FLOATING_POINT_LITERAL> >
530 |
531         < #DECIMAL_FLOATING_POINT_LITERAL:
532         (["0"-"9"])+ "." (["0"-"9"])* (<DECIMAL_EXPONENT>)? (["f","F","d","D"])?
533       | "." (["0"-"9"])+ (<DECIMAL_EXPONENT>)? (["f","F","d","D"])?
534       | (["0"-"9"])+ <DECIMAL_EXPONENT> (["f","F","d","D"])?
535       | (["0"-"9"])+ (<DECIMAL_EXPONENT>)? ["f","F","d","D"]>
536 |
537         < #DECIMAL_EXPONENT: ["e","E"] (["+","-"])? (["0"-"9"])+ >
538 |
539         < #HEXADECIMAL_FLOATING_POINT_LITERAL:
540         "0" ["x", "X"] (["0"-"9","a"-"f","A"-"F"])+ (".")? <HEXADECIMAL_EXPONENT> (["f","F","d","D"])?
541       | "0" ["x", "X"] (["0"-"9","a"-"f","A"-"F"])* "." (["0"-"9","a"-"f","A"-"F"])+ <HEXADECIMAL_EXPONENT> (["f","F","d","D"])?>
542 |
543         < #HEXADECIMAL_EXPONENT: ["p","P"] (["+","-"])? (["0"-"9"])+ >
544 |
545         < #SPACE: (" " | "\t")+>
546 |
547         < #TO_END_OF_LINE: (~["\n"])+>
548 |
549         /* Macro token */
550         <INCLUDE: "#" (<SPACE>)? "include" <SPACE> (<STRING_LITERAL> | "<" (<LETTER> | <DOT>)+ ">")>
551 |
552         <DEFINE: "#" (<SPACE>)? <TO_END_OF_LINE>>
553 }
554
555 String Type() :
556 {
557         String type;
558         String str;
559         QualifiedName name;
560 }
561 {
562         { type = ""; }
563         ("const"
564         { type = "const"; }
565         )?
566         (((str = <STRUCT>.image | str = <CLASS>.image | str = <UNSIGNED>.image) { type = type + " " + str; })? 
567         (
568         name = ParseQualifiedName() {
569                 if (!type.equals(""))
570                         type = type + " " + name.fullName;
571                 else
572                         type = name.fullName;
573         })
574         )
575         ((str = "const".image {
576                 if (!type.equals(""))
577                         type = type + " " + str;
578                 else
579                         type = str;
580         }) |
581         (str = <STAR>.image {
582                 if (!type.equals(""))
583                         type = type + " " + str;
584                 else
585                         type = str;
586         }) |
587         (str = <AND>.image {
588                 if (!type.equals(""))
589                         type = type + " " + str;
590                 else
591                         type = str;
592         })
593         )*
594         {
595                 return type;
596         }
597 }
598
599 void Test() :
600 {
601         String str;     
602         FunctionHeader func;
603 }
604 {
605         /*
606         str = Type()
607         {
608                 System.out.println(str);
609         }
610         */
611         func = FuncDecl() 
612         {
613                 System.out.println(func);
614         }
615         
616 }
617
618 String ParameterizedName() :
619 {
620         String res = "";
621         String str;
622 }
623 {
624         (str = <IDENTIFIER>.image {res = str;})
625         ("<" str = Type() { res = res + "<" + str; }
626         ("," str = Type() { res = res + ", " + str; })* ">"
627         { res = res + ">"; }
628         )?
629         {
630                 return res;
631         }
632 }
633
634 FunctionHeader FuncDecl() :
635 {
636         String ret;
637         QualifiedName funcName;
638         ArrayList<VariableDeclaration> args;
639 }
640 {
641         (<STATIC> | <INLINE>)*
642         ret = Type() 
643         funcName = ParseQualifiedName() 
644         args = FormalParamList() 
645         {
646                 FunctionHeader res = new FunctionHeader(ret, funcName, args);
647                 //System.out.println(res);
648                 return res;
649         }
650 }
651
652 QualifiedName ParseQualifiedName() :
653 {
654         String qualifiedName, str;
655 }
656 {
657         { qualifiedName = ""; }
658         (str = ParameterizedName() { qualifiedName = qualifiedName + str; } )
659         ( <DOUBLECOLON> (str = ParameterizedName() { qualifiedName = qualifiedName +
660         "::" + str; }  ))*
661         {
662                 QualifiedName res = new QualifiedName(qualifiedName);
663                 //System.out.println(res);
664                 return res;
665         }
666 }
667
668 ArrayList<VariableDeclaration> TemplateParamList() :
669 {
670         ArrayList<VariableDeclaration> params;
671         String type;
672         String name;
673 }
674 {
675         {
676                 params = new ArrayList<VariableDeclaration>();
677         }
678         <TEMPLATE>
679         "<"
680         (type = <IDENTIFIER>.image 
681         name = <IDENTIFIER>.image
682         {
683                 params.add(new VariableDeclaration(type, name));
684         }
685         )
686
687         ("," type = <IDENTIFIER>.image 
688         name = <IDENTIFIER>.image
689         {
690                 params.add(new VariableDeclaration(type, name));
691         }
692         )*
693         ">"
694         {
695                 //System.out.println(params);
696                 return params;
697         }
698 }
699
700 ArrayList<VariableDeclaration > FormalParamList() :
701 {
702         ArrayList<VariableDeclaration > typeParams;
703         VariableDeclaration varDecl;
704 }
705 {
706         {
707                 typeParams = new ArrayList<VariableDeclaration >();
708         }
709         "("
710         ((varDecl = TypeParam() {typeParams.add(varDecl);})
711         ((<COMMA> varDecl = TypeParam() {typeParams.add(varDecl);}))*)?
712         ")"
713         {
714                 return typeParams;
715         }
716 }
717
718 VariableDeclaration TypeParam() :
719 {
720         String type, param;
721 }
722 {
723         (type = Type()) (param = <IDENTIFIER>.image)
724         {
725                 return new VariableDeclaration(type, param);
726         }
727 }
728
729
730
731 ArrayList<String> C_CPP_CODE(ArrayList<String> headers) :
732 {
733         String text;
734         Token t;
735         boolean newLine = false;
736         boolean newSpace = true;
737         boolean inTemplate = false;
738         boolean inForLoop = false;
739         ArrayList<String> content;
740         String header;
741 }
742 {
743         {
744                 text = "";
745                 t = new Token();
746                 content = new ArrayList<String>();
747         }
748         (
749         LOOKAHEAD(2)
750         (
751         t = <CONST> | t = <STRUCT> | t = <CLASS> | t = <UNSIGNED> |
752         (t = <TEMPLATE> { inTemplate = true;  })|
753         t = <STATIC> | t = <INLINE> |
754         (t = <FOR> { inForLoop = true; })|
755         (t = <INCLUDE>
756         {
757                 header = t.image;
758                 newLine = true;
759                 if (headers != null) {
760                         headers.add(header.substring(header.lastIndexOf(' ') + 1));
761                 }
762         })
763         | t = <IDENTIFIER> | t = <POUND> |
764         (t = <OPEN_BRACE>  { newLine = true; } ) |
765         (t = <CLOSE_BRACE>  { newLine = true; inForLoop = false;} ) | 
766         t = <EQUALS> | t = <OPEN_PAREN> | t = <CLOSE_PAREN> | 
767         t = <OPEN_BRACKET> | t = <CLOSE_BRACKET>
768         | t = <HB_SYMBOL> | t = <COMMA> |
769         t = <DOT> | t = <STAR> | t = <NEGATE> | t = <EXCLAMATION> | t = <AND> | t = <OR> | t = <MOD> | t = <PLUS> |
770         t = <PLUSPLUS> | t = <MINUS> | t = <MINUSMINUS> | t = <DIVIDE> | t = <BACKSLASH> |
771         t = <LESS_THAN> |
772         (t = <GREATER_THAN> { if (inTemplate) newLine = true; }) |
773         t = <GREATER_EQUALS>    | t = <LESS_EQUALS> |
774         t = <LOGICAL_EQUALS> | t = <NOT_EQUALS> | t = <LOGICAL_AND> | t = <LOGICAL_OR> | t = <XOR> |
775         t = <QUESTION_MARK> | t = <COLON> | t = <DOUBLECOLON> |
776         t = <DOUBLELESSTHAN> | 
777         t = <DOUBLEGREATERTHAN> |
778         t = <TRIPLEGREATERTHAN> | 
779
780         t = <PLUS_EQUALS> |
781         t = <MINUS_EQUALS> |
782         t = <TIMES_EQUALS> |
783         t = <DIVIDE_EQUALS> |
784         t = <MOD_EQUALS> |
785         t = <XOR_EQUALS> |
786         t = <OR_EQUALS> |
787         t = <AND_EQUALS> |
788
789         (t = <SEMI_COLON> { if (!inForLoop) newLine = true; } )
790         | t = <STRING_LITERAL> | t = <CHARACTER_LITERAL> |
791         t = <INTEGER_LITERAL> | t = <FLOATING_POINT_LITERAL> |
792         (t = <DEFINE> { newLine = true; } )
793         )
794         {
795                 if (text.equals("")) {
796                         text = t.image;
797                         newSpace = true;
798                 } else {
799                         text = text + " " + t.image;
800                         /*
801                         if (newSpace && spaceSeparator(t)) {
802                                 text = text + " " + t.image;
803                         } else {
804                                 text = text + t.image;
805                                 if (spaceSeparator(t))
806                                         newSpace = true;
807                         }*/
808                 }
809                 if (newLine) {
810                         content.add(text);
811                         text = "";
812                         newLine = false;
813                         inTemplate = false;
814                 }
815         }
816         )+
817
818         {
819                 if (content.size() == 0) {
820                         content.add(text);
821                 }
822                 return content;
823         }
824 }
825
826
827 void Parse(File f, ArrayList<String> content, ArrayList<Construct> constructs, ArrayList<String> headers) :
828 {
829         Construct inst;
830         ArrayList<String> code;
831 }
832 {
833         {
834                 _file = f;
835                 _content = content;
836                 _constructs = constructs;
837         }
838         ((inst = ParseSpec() { _constructs.add(inst); }) |
839         ((code = C_CPP_CODE(headers)) { _content.addAll(code); })
840         )* <EOF>
841 }
842
843 Construct ParseSpec() :
844 {
845         Construct res;  
846 }
847 {
848         (
849         LOOKAHEAD(2) res = Global_construct() |
850         LOOKAHEAD(2) res = Interface() |
851         LOOKAHEAD(2) res = Potential_commit_point_define() |
852         LOOKAHEAD(2) res = Commit_point_define() |
853         LOOKAHEAD(2) res = Commit_point_define_check() |
854         LOOKAHEAD(2) res = Entry_point() |
855         LOOKAHEAD(2) res = Class_begin() |
856         LOOKAHEAD(2) res = Class_end() |
857         LOOKAHEAD(2) res = Interface_define()
858         )
859         {
860                 //System.out.println(res);
861                 return res;
862         }
863 }
864
865 GlobalConstruct Global_construct() :
866 {
867         GlobalConstruct res;
868         SequentialDefineSubConstruct code;
869         HashMap<String, String> options;
870         String key, value;
871 }
872 {
873         {
874                 res = null;
875                 options = new HashMap<String, String>();
876         }
877                 <BEGIN> 
878                         (<OPTIONS>
879                                 ((key = <IDENTIFIER>.image)
880                                 <EQUALS>
881                                 (value = <IDENTIFIER>.image)
882                                 {
883                                         if (options.containsKey(key)) {
884                                                 throw new ParseException("Duplicate options!");
885                                         }
886                                         options.put(key, value);
887                                 }
888                                 <SEMI_COLON>
889                                 )*
890                         )?
891                         (code = Global_define())
892                         { res = new GlobalConstruct(_file, _content.size(), code, options); }
893                         (Interface_clusters(res))?
894                         (Happens_before(res))?
895                 <END>
896         {
897                 res.unfoldInterfaceCluster();
898                 return res;
899         }
900 }
901
902 SequentialDefineSubConstruct Global_define() :
903 {
904         ArrayList<String> initVar, defineFunc, code, declareStruct;
905         ArrayList<ArrayList<String>> defineFuncs;
906         ArrayList<VariableDeclaration> declareVars;
907         ArrayList<ArrayList<String>> declareStructs;
908         VariableDeclaration declareVar;
909
910 }
911 {
912         {
913                 declareVars = new ArrayList<VariableDeclaration>();
914                 initVar = null;
915                 defineFuncs = new ArrayList<ArrayList<String>>();
916                 declareStructs = new ArrayList<ArrayList<String>>();
917         }
918         <GLOBAL_DEFINE>
919         (<DECLARE_STRUCT> (declareStruct = C_CPP_CODE(null) {
920                 declareStructs.add(declareStruct); }))*
921                 (<DECLARE_VAR> ((declareVar = TypeParam() ";" {
922                         declareVars.add(declareVar); } )*))?
923         (<INIT_VAR> (code = C_CPP_CODE(null) { initVar = code; } ))?
924         (<DEFINE_FUNC> (defineFunc = C_CPP_CODE(null) { defineFuncs.add(defineFunc); }))*
925         {
926                 SequentialDefineSubConstruct res = new
927                         SequentialDefineSubConstruct(declareStructs, declareVars, initVar, defineFuncs);
928                 //System.out.println(res);
929                 return res;
930         }
931 }
932
933 ConditionalInterface Conditional_interface() :
934 {
935         String interfaceName, hbConditionLabel;
936 }
937 {
938         {
939                 hbConditionLabel = "";
940         }
941         interfaceName = <IDENTIFIER>.image (<OPEN_PAREN> hbConditionLabel =
942         <IDENTIFIER>.image <CLOSE_PAREN>)?
943         {
944                 return new ConditionalInterface(interfaceName, hbConditionLabel);
945         }
946 }
947
948 void Interface_cluster(GlobalConstruct inst) :
949 {
950         String clusterName;
951         ConditionalInterface condInterface;
952 }
953 {
954         (clusterName= <IDENTIFIER>.image)
955         <EQUALS> <OPEN_BRACE>
956                 (condInterface = Conditional_interface()
957                 { inst.addInterface2Cluster(clusterName, condInterface); } 
958                 )
959                 (<COMMA> condInterface = Conditional_interface()
960                 { inst.addInterface2Cluster(clusterName, condInterface); } 
961                 )*
962         <CLOSE_BRACE>
963 }
964
965 void Interface_clusters(GlobalConstruct inst) :
966 {}
967 {
968         <INTERFACE_CLUSTER> (Interface_cluster(inst))+
969 }
970
971 void Happens_before(GlobalConstruct inst) :
972 {
973         ConditionalInterface left, right;       
974 }
975 {
976         <HAPPENS_BEFORE> 
977         (
978         left = Conditional_interface() <HB_SYMBOL> right = Conditional_interface()
979         { inst.addHBCondition(left, right); }
980         )+
981 }
982
983 InterfaceConstruct Interface() :
984 {
985         InterfaceConstruct res;
986         String interfaceName, condition, idCode, check,
987                 postCheck, commitPoint, hbLabel, hbCondition;
988         ArrayList<String> commitPointSet;
989         ArrayList<String> action, postAction;
990         HashMap<String, String> hbConditions;
991         ArrayList<String> content;
992 }
993 {
994         {
995                 res = null;
996                 action = new ArrayList<String>();
997                 condition = "";
998                 idCode = "";
999                 check = "";
1000                 postCheck = "";
1001                 commitPointSet = new ArrayList<String>();
1002                 hbConditions = new HashMap<String, String>();
1003                 postAction = new ArrayList<String>();
1004         }
1005                 <BEGIN>
1006                         <INTERFACE> (interfaceName = <IDENTIFIER>.image)
1007                         <COMMIT_POINT_SET>
1008                                 (commitPoint = <IDENTIFIER>.image
1009                                 { commitPointSet.add(commitPoint); }
1010                                 )
1011                                 (<OR>
1012                                         (commitPoint = <IDENTIFIER>.image)
1013                                         {
1014                                                 if (commitPointSet.contains(commitPoint)) {
1015                                                         throw new ParseException(interfaceName + " has" +
1016                                                                 "duplicate commit point labels");
1017                                                 }
1018                                                 commitPointSet.add(commitPoint);
1019                                         }
1020                                 )*
1021
1022                         (<CONDITION> (content = C_CPP_CODE(null) { condition = stringArray2String(content); }))?
1023                         (
1024                                 <HB_CONDITION>
1025                                 (hbLabel = <IDENTIFIER>.image) <DOUBLECOLON>
1026                                 (content = C_CPP_CODE(null) { hbCondition = stringArray2String(content); })
1027                                 {
1028                                         if (hbConditions.containsKey(hbLabel)) {
1029                                                 throw new ParseException(interfaceName + " has" +
1030                                                         "duplicate happens-before condtion labels");
1031                                         }
1032                                         hbConditions.put(hbLabel, hbCondition);
1033                                 }
1034                         )*
1035                         (<ID> (content = C_CPP_CODE(null) { idCode = stringArray2String(content); }))?
1036                         (<CHECK> (content = C_CPP_CODE(null) { check = stringArray2String(content); }))?
1037                         (<ACTION> action = C_CPP_CODE(null))?
1038                         (<POST_ACTION> (postAction = C_CPP_CODE(null) ))?
1039                         (<POST_CHECK> (content = C_CPP_CODE(null) { postCheck = stringArray2String(content); }))?
1040                 <END>
1041         {
1042                 res = new InterfaceConstruct(_file, _content.size(), interfaceName, commitPointSet, condition,
1043                         hbConditions, idCode, check, action, postAction, postCheck);
1044                 return res;
1045         }
1046 }
1047
1048
1049 PotentialCPDefineConstruct Potential_commit_point_define() :
1050 {
1051         PotentialCPDefineConstruct res;
1052         String label, condition;
1053         ArrayList<String> content;
1054 }
1055 {
1056
1057         { res = null; }
1058                 <BEGIN>
1059                         <POTENTIAL_COMMIT_POINT_DEFINE> (content = C_CPP_CODE(null) { condition = stringArray2String(content); })
1060                         <LABEL> (label = <IDENTIFIER>.image)
1061                 <END>
1062         {
1063                 res = new PotentialCPDefineConstruct(_file, _content.size(), label, condition); 
1064                 return res;
1065         }
1066 }
1067
1068
1069 CPDefineConstruct Commit_point_define() :
1070 {
1071         CPDefineConstruct res;
1072         String label, potentialCPLabel, condition;
1073         ArrayList<String> content;
1074 }
1075 {
1076
1077         { res = null; }
1078                 <BEGIN>
1079                         <COMMIT_POINT_DEFINE> (content = C_CPP_CODE(null) { condition = stringArray2String(content); })
1080                         <POTENTIAL_COMMIT_POINT_LABEL> (potentialCPLabel = <IDENTIFIER>.image)
1081                         <LABEL> (label = <IDENTIFIER>.image)
1082                 <END>
1083         {
1084                 res = new CPDefineConstruct(_file, _content.size(), label, potentialCPLabel, condition);
1085                 return res;
1086         }
1087 }
1088
1089
1090 CPDefineCheckConstruct Commit_point_define_check() :
1091 {
1092         CPDefineCheckConstruct res;     
1093         String label, condition;
1094         ArrayList<String> content;
1095 }
1096 {
1097
1098         { res = null; }
1099                 <BEGIN> 
1100                         <COMMIT_POINT_DEFINE_CHECK> (content = C_CPP_CODE(null) { condition = stringArray2String(content); })
1101                         <LABEL> (label = <IDENTIFIER>.image)
1102                 <END>
1103         {
1104                 res = new CPDefineCheckConstruct(_file, _content.size(), label, condition);
1105                 return res;
1106         }
1107 }
1108
1109 EntryPointConstruct Entry_point() :
1110 {}
1111 {
1112
1113                 <BEGIN> 
1114                         <ENTRY_POINT>
1115                 <END>
1116         {
1117                 return new EntryPointConstruct(_file, _content.size());
1118         }
1119 }
1120
1121 ClassBeginConstruct Class_begin() :
1122 {}
1123 {
1124
1125                 <BEGIN> 
1126                         <CLASS_BEGIN>
1127                 <END>
1128         {
1129                 return new ClassBeginConstruct(_file, _content.size());
1130         }
1131 }
1132
1133 ClassEndConstruct Class_end() :
1134 {}
1135 {
1136
1137                 <BEGIN> 
1138                         <CLASS_END>
1139                 <END>
1140         {
1141                 return new ClassEndConstruct(_file, _content.size());
1142         }
1143 }
1144
1145 InterfaceDefineConstruct Interface_define() :
1146 {
1147         String name;    
1148 }
1149 {
1150                 <BEGIN>
1151                         <INTERFACE_DEFINE> (name = <IDENTIFIER>.image)
1152                 <END>
1153         {
1154                 return new InterfaceDefineConstruct(_file, _content.size(), name);
1155         }
1156 }