add spsc
[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         <DOLLAR: "$">
419 |
420         <STAR: "*">
421 |
422         <NEGATE: "~">
423 |
424         <EXCLAMATION: "!">
425 |
426         <AND: "&">
427 |
428         <OR: "|">
429 |
430         <MOD: "%">
431 |
432         <PLUS: "+">
433 |
434         <PLUSPLUS: "++">
435 |
436         <MINUS: "-">
437 |
438         <MINUSMINUS: "--">
439 |
440         <DIVIDE: "/">
441 |
442         <BACKSLASH: "\\">
443 |
444         <LESS_THAN: "<">
445 |
446         <GREATER_THAN: ">">
447 |
448         <GREATER_EQUALS: ">=">
449 |
450         <LESS_EQUALS: "<=">
451 |
452         <LOGICAL_EQUALS: "==">
453 |
454         <NOT_EQUALS: "!=">
455 |
456         <LOGICAL_AND: "&&">
457 |
458         <LOGICAL_OR: "||">
459 |
460         <XOR: "^">
461 |
462         <QUESTION_MARK: "?">
463 |
464         <COLON: ":">
465 |
466         <DOUBLECOLON: "::">
467 |
468         <DOUBLELESSTHAN: "<<">
469 |
470         <DOUBLEGREATERTHAN: ">>">
471 |
472         <TRIPLEGREATERTHAN: ">>>">
473 |
474         <PLUS_EQUALS: "+=">
475 |
476         <MINUS_EQUALS: "-=">
477 |
478         <TIMES_EQUALS: "*=">
479 |
480         <DIVIDE_EQUALS: "/=">
481 |
482         <MOD_EQUALS: "%=">
483 |
484         <XOR_EQUALS: "^=">
485 |
486         <OR_EQUALS: "|=">
487 |
488         <AND_EQUALS: "&=">
489 |
490         <SEMI_COLON: ";">
491 |
492         <STRING_LITERAL:
493         "\""
494         ((~["\"","\\","\n","\r"])
495         | ("\\"
496                 ( ["n","t","b","r","f","\\","'","\""]
497                 | ["0"-"7"] ( ["0"-"7"] )?
498                 | ["0"-"3"] ["0"-"7"]
499                         ["0"-"7"]
500                 )
501                 )
502         )*
503         "\"">
504 |
505         <CHARACTER_LITERAL:
506         "'"
507         ((~["'","\\","\n","\r"])
508         | ("\\"
509                 (["n","t","b","r","f","\\","'","\""]
510                 | ["0"-"7"] ( ["0"-"7"] )?
511                 | ["0"-"3"] ["0"-"7"]
512                 ["0"-"7"]
513                 )
514                 )
515         )
516         "'">
517 |
518         < INTEGER_LITERAL:
519         <DECIMAL_LITERAL> (["l","L"])?
520       | <HEX_LITERAL> (["l","L"])?
521       | <OCTAL_LITERAL> (["l","L"])?>
522 |
523         < #DECIMAL_LITERAL: ["1"-"9"] (["0"-"9"])* >
524 |
525         < #HEX_LITERAL: "0" ["x","X"] (["0"-"9","a"-"f","A"-"F"])+ >
526 |
527         < #OCTAL_LITERAL: "0" (["0"-"7"])* >
528 |
529         < FLOATING_POINT_LITERAL:
530         <DECIMAL_FLOATING_POINT_LITERAL>
531       | <HEXADECIMAL_FLOATING_POINT_LITERAL> >
532 |
533         < #DECIMAL_FLOATING_POINT_LITERAL:
534         (["0"-"9"])+ "." (["0"-"9"])* (<DECIMAL_EXPONENT>)? (["f","F","d","D"])?
535       | "." (["0"-"9"])+ (<DECIMAL_EXPONENT>)? (["f","F","d","D"])?
536       | (["0"-"9"])+ <DECIMAL_EXPONENT> (["f","F","d","D"])?
537       | (["0"-"9"])+ (<DECIMAL_EXPONENT>)? ["f","F","d","D"]>
538 |
539         < #DECIMAL_EXPONENT: ["e","E"] (["+","-"])? (["0"-"9"])+ >
540 |
541         < #HEXADECIMAL_FLOATING_POINT_LITERAL:
542         "0" ["x", "X"] (["0"-"9","a"-"f","A"-"F"])+ (".")? <HEXADECIMAL_EXPONENT> (["f","F","d","D"])?
543       | "0" ["x", "X"] (["0"-"9","a"-"f","A"-"F"])* "." (["0"-"9","a"-"f","A"-"F"])+ <HEXADECIMAL_EXPONENT> (["f","F","d","D"])?>
544 |
545         < #HEXADECIMAL_EXPONENT: ["p","P"] (["+","-"])? (["0"-"9"])+ >
546 |
547         < #SPACE: (" " | "\t")+>
548 |
549         < #TO_END_OF_LINE: (~["\n"])+>
550 |
551         /* Macro token */
552         <INCLUDE: "#" (<SPACE>)? "include" <SPACE> (<STRING_LITERAL> | "<" (<LETTER> | <DOT>)+ ">")>
553 |
554         <DEFINE: "#" (<SPACE>)? <TO_END_OF_LINE>>
555 }
556
557 String Type() :
558 {
559         String type;
560         String str;
561         QualifiedName name;
562 }
563 {
564         { type = ""; }
565         ("const"
566         { type = "const"; }
567         )?
568         (((str = <STRUCT>.image | str = <CLASS>.image | str = <UNSIGNED>.image) { type = type + " " + str; })? 
569         (
570         name = ParseQualifiedName() {
571                 if (!type.equals(""))
572                         type = type + " " + name.fullName;
573                 else
574                         type = name.fullName;
575         })
576         )
577         ((str = "const".image {
578                 if (!type.equals(""))
579                         type = type + " " + str;
580                 else
581                         type = str;
582         }) |
583         (str = <STAR>.image {
584                 if (!type.equals(""))
585                         type = type + " " + str;
586                 else
587                         type = str;
588         }) |
589         (str = <AND>.image {
590                 if (!type.equals(""))
591                         type = type + " " + str;
592                 else
593                         type = str;
594         })
595         )*
596         {
597                 return type;
598         }
599 }
600
601 void Test() :
602 {
603         String str;     
604         FunctionHeader func;
605 }
606 {
607         /*
608         str = Type()
609         {
610                 System.out.println(str);
611         }
612         */
613         func = FuncDecl() 
614         {
615                 System.out.println(func);
616         }
617         
618 }
619
620 String ParameterizedName() :
621 {
622         String res = "";
623         String str;
624 }
625 {
626         (str = <IDENTIFIER>.image {res = str;})
627         ("<" str = Type() { res = res + "<" + str; }
628         ("," str = Type() { res = res + ", " + str; })* ">"
629         { res = res + ">"; }
630         )?
631         {
632                 return res;
633         }
634 }
635
636 FunctionHeader FuncDecl() :
637 {
638         String ret;
639         QualifiedName funcName;
640         ArrayList<VariableDeclaration> args;
641 }
642 {
643         (<STATIC> | <INLINE>)*
644         ret = Type() 
645         funcName = ParseQualifiedName() 
646         args = FormalParamList() 
647         {
648                 FunctionHeader res = new FunctionHeader(ret, funcName, args);
649                 //System.out.println(res);
650                 return res;
651         }
652 }
653
654 QualifiedName ParseQualifiedName() :
655 {
656         String qualifiedName, str;
657 }
658 {
659         { qualifiedName = ""; }
660         (str = ParameterizedName() { qualifiedName = qualifiedName + str; } )
661         ( <DOUBLECOLON> (str = ParameterizedName() { qualifiedName = qualifiedName +
662         "::" + str; }  ))*
663         {
664                 QualifiedName res = new QualifiedName(qualifiedName);
665                 //System.out.println(res);
666                 return res;
667         }
668 }
669
670 ArrayList<VariableDeclaration> TemplateParamList() :
671 {
672         ArrayList<VariableDeclaration> params;
673         String type;
674         String name;
675 }
676 {
677         {
678                 params = new ArrayList<VariableDeclaration>();
679         }
680         <TEMPLATE>
681         "<"
682         (type = <IDENTIFIER>.image 
683         name = <IDENTIFIER>.image
684         {
685                 params.add(new VariableDeclaration(type, name));
686         }
687         )
688
689         ("," type = <IDENTIFIER>.image 
690         name = <IDENTIFIER>.image
691         {
692                 params.add(new VariableDeclaration(type, name));
693         }
694         )*
695         ">"
696         {
697                 //System.out.println(params);
698                 return params;
699         }
700 }
701
702 ArrayList<VariableDeclaration > FormalParamList() :
703 {
704         ArrayList<VariableDeclaration > typeParams;
705         VariableDeclaration varDecl;
706 }
707 {
708         {
709                 typeParams = new ArrayList<VariableDeclaration >();
710         }
711         "("
712         ((varDecl = TypeParam() {typeParams.add(varDecl);})
713         ((<COMMA> varDecl = TypeParam() {typeParams.add(varDecl);}))*)?
714         ")"
715         {
716                 return typeParams;
717         }
718 }
719
720 VariableDeclaration TypeParam() :
721 {
722         String type, param;
723 }
724 {
725         (type = Type()) (param = <IDENTIFIER>.image)
726         {
727                 return new VariableDeclaration(type, param);
728         }
729 }
730
731
732
733 ArrayList<String> C_CPP_CODE(ArrayList<String> headers) :
734 {
735         String text;
736         Token t;
737         boolean newLine = false;
738         boolean newSpace = true;
739         boolean inTemplate = false;
740         boolean inForLoop = false;
741         ArrayList<String> content;
742         String header;
743 }
744 {
745         {
746                 text = "";
747                 t = new Token();
748                 content = new ArrayList<String>();
749         }
750         (
751         LOOKAHEAD(2)
752         (
753         t = <CONST> | t = <STRUCT> | t = <CLASS> | t = <UNSIGNED> |
754         (t = <TEMPLATE> { inTemplate = true;  })|
755         t = <STATIC> | t = <INLINE> |
756         (t = <FOR> { inForLoop = true; })|
757         (t = <INCLUDE>
758         {
759                 header = t.image;
760                 newLine = true;
761                 if (headers != null) {
762                         headers.add(header.substring(header.lastIndexOf(' ') + 1));
763                 }
764         })
765         | t = <IDENTIFIER> | t = <POUND> |
766         (t = <OPEN_BRACE>  { newLine = true; } ) |
767         (t = <CLOSE_BRACE>  { newLine = true; inForLoop = false;} ) | 
768         t = <EQUALS> | t = <OPEN_PAREN> | t = <CLOSE_PAREN> | 
769         t = <OPEN_BRACKET> | t = <CLOSE_BRACKET>
770         | t = <HB_SYMBOL> | t = <COMMA> |
771         t = <DOT> | t = <STAR> | t = <DOLLAR> | t = <NEGATE> | t = <EXCLAMATION> | t = <AND> | t = <OR> | t = <MOD> | t = <PLUS> |
772         t = <PLUSPLUS> | t = <MINUS> | t = <MINUSMINUS> | t = <DIVIDE> | t = <BACKSLASH> |
773         t = <LESS_THAN> |
774         (t = <GREATER_THAN> { if (inTemplate) newLine = true; }) |
775         t = <GREATER_EQUALS>    | t = <LESS_EQUALS> |
776         t = <LOGICAL_EQUALS> | t = <NOT_EQUALS> | t = <LOGICAL_AND> | t = <LOGICAL_OR> | t = <XOR> |
777         t = <QUESTION_MARK> | t = <COLON> | t = <DOUBLECOLON> |
778         t = <DOUBLELESSTHAN> | 
779         t = <DOUBLEGREATERTHAN> |
780         t = <TRIPLEGREATERTHAN> | 
781
782         t = <PLUS_EQUALS> |
783         t = <MINUS_EQUALS> |
784         t = <TIMES_EQUALS> |
785         t = <DIVIDE_EQUALS> |
786         t = <MOD_EQUALS> |
787         t = <XOR_EQUALS> |
788         t = <OR_EQUALS> |
789         t = <AND_EQUALS> |
790
791         (t = <SEMI_COLON> { if (!inForLoop) newLine = true; } )
792         | t = <STRING_LITERAL> | t = <CHARACTER_LITERAL> |
793         t = <INTEGER_LITERAL> | t = <FLOATING_POINT_LITERAL> |
794         (t = <DEFINE> { newLine = true; } )
795         )
796         {
797                 if (text.equals("")) {
798                         text = t.image;
799                         newSpace = true;
800                 } else {
801                         text = text + " " + t.image;
802                         /*
803                         if (newSpace && spaceSeparator(t)) {
804                                 text = text + " " + t.image;
805                         } else {
806                                 text = text + t.image;
807                                 if (spaceSeparator(t))
808                                         newSpace = true;
809                         }*/
810                 }
811                 if (newLine) {
812                         content.add(text);
813                         text = "";
814                         newLine = false;
815                         inTemplate = false;
816                 }
817         }
818         )+
819
820         {
821                 if (content.size() == 0) {
822                         content.add(text);
823                 }
824                 return content;
825         }
826 }
827
828
829 void Parse(File f, ArrayList<String> content, ArrayList<Construct> constructs, ArrayList<String> headers) :
830 {
831         Construct inst;
832         ArrayList<String> code;
833 }
834 {
835         {
836                 _file = f;
837                 _content = content;
838                 _constructs = constructs;
839         }
840         ((inst = ParseSpec() { _constructs.add(inst); }) |
841         ((code = C_CPP_CODE(headers)) { _content.addAll(code); })
842         )* <EOF>
843 }
844
845 Construct ParseSpec() :
846 {
847         Construct res;  
848 }
849 {
850         (
851         LOOKAHEAD(2) res = Global_construct() |
852         LOOKAHEAD(2) res = Interface() |
853         LOOKAHEAD(2) res = Potential_commit_point_define() |
854         LOOKAHEAD(2) res = Commit_point_define() |
855         LOOKAHEAD(2) res = Commit_point_define_check() |
856         LOOKAHEAD(2) res = Entry_point() |
857         LOOKAHEAD(2) res = Class_begin() |
858         LOOKAHEAD(2) res = Class_end() |
859         LOOKAHEAD(2) res = Interface_define()
860         )
861         {
862                 //System.out.println(res);
863                 return res;
864         }
865 }
866
867 GlobalConstruct Global_construct() :
868 {
869         GlobalConstruct res;
870         SequentialDefineSubConstruct code;
871         HashMap<String, String> options;
872         String key, value;
873 }
874 {
875         {
876                 res = null;
877                 options = new HashMap<String, String>();
878         }
879                 <BEGIN> 
880                         (<OPTIONS>
881                                 ((key = <IDENTIFIER>.image)
882                                 <EQUALS>
883                                 (value = <IDENTIFIER>.image)
884                                 {
885                                         if (options.containsKey(key)) {
886                                                 throw new ParseException("Duplicate options!");
887                                         }
888                                         options.put(key, value);
889                                 }
890                                 <SEMI_COLON>
891                                 )*
892                         )?
893                         (code = Global_define())
894                         { res = new GlobalConstruct(_file, _content.size(), code, options); }
895                         (Interface_clusters(res))?
896                         (Happens_before(res))?
897                 <END>
898         {
899                 res.unfoldInterfaceCluster();
900                 return res;
901         }
902 }
903
904 SequentialDefineSubConstruct Global_define() :
905 {
906         ArrayList<String> initVar, defineFunc, code, declareStruct;
907         ArrayList<ArrayList<String>> defineFuncs;
908         ArrayList<VariableDeclaration> declareVars;
909         ArrayList<ArrayList<String>> declareStructs;
910         VariableDeclaration declareVar;
911
912 }
913 {
914         {
915                 declareVars = new ArrayList<VariableDeclaration>();
916                 initVar = null;
917                 defineFuncs = new ArrayList<ArrayList<String>>();
918                 declareStructs = new ArrayList<ArrayList<String>>();
919         }
920         <GLOBAL_DEFINE>
921         (<DECLARE_STRUCT> (declareStruct = C_CPP_CODE(null) {
922                 declareStructs.add(declareStruct); }))*
923                 (<DECLARE_VAR> ((declareVar = TypeParam() ";" {
924                         declareVars.add(declareVar); } )*))?
925         (<INIT_VAR> (code = C_CPP_CODE(null) { initVar = code; } ))?
926         (<DEFINE_FUNC> (defineFunc = C_CPP_CODE(null) { defineFuncs.add(defineFunc); }))*
927         {
928                 SequentialDefineSubConstruct res = new
929                         SequentialDefineSubConstruct(declareStructs, declareVars, initVar, defineFuncs);
930                 //System.out.println(res);
931                 return res;
932         }
933 }
934
935 ConditionalInterface Conditional_interface() :
936 {
937         String interfaceName, hbConditionLabel;
938 }
939 {
940         {
941                 hbConditionLabel = "";
942         }
943         interfaceName = <IDENTIFIER>.image (<OPEN_PAREN> hbConditionLabel =
944         <IDENTIFIER>.image <CLOSE_PAREN>)?
945         {
946                 return new ConditionalInterface(interfaceName, hbConditionLabel);
947         }
948 }
949
950 void Interface_cluster(GlobalConstruct inst) :
951 {
952         String clusterName;
953         ConditionalInterface condInterface;
954 }
955 {
956         (clusterName= <IDENTIFIER>.image)
957         <EQUALS> <OPEN_BRACE>
958                 (condInterface = Conditional_interface()
959                 { inst.addInterface2Cluster(clusterName, condInterface); } 
960                 )
961                 (<COMMA> condInterface = Conditional_interface()
962                 { inst.addInterface2Cluster(clusterName, condInterface); } 
963                 )*
964         <CLOSE_BRACE>
965 }
966
967 void Interface_clusters(GlobalConstruct inst) :
968 {}
969 {
970         <INTERFACE_CLUSTER> (Interface_cluster(inst))+
971 }
972
973 void Happens_before(GlobalConstruct inst) :
974 {
975         ConditionalInterface left, right;       
976 }
977 {
978         <HAPPENS_BEFORE> 
979         (
980         left = Conditional_interface() <HB_SYMBOL> right = Conditional_interface()
981         { inst.addHBCondition(left, right); }
982         )+
983 }
984
985 InterfaceConstruct Interface() :
986 {
987         InterfaceConstruct res;
988         String interfaceName, condition, idCode, check,
989                 postCheck, commitPoint, hbLabel, hbCondition;
990         ArrayList<String> commitPointSet;
991         ArrayList<String> action, postAction;
992         HashMap<String, String> hbConditions;
993         ArrayList<String> content;
994 }
995 {
996         {
997                 res = null;
998                 action = new ArrayList<String>();
999                 condition = "";
1000                 idCode = "";
1001                 check = "";
1002                 postCheck = "";
1003                 commitPointSet = new ArrayList<String>();
1004                 hbConditions = new HashMap<String, String>();
1005                 postAction = new ArrayList<String>();
1006         }
1007                 <BEGIN>
1008                         <INTERFACE> (interfaceName = <IDENTIFIER>.image)
1009                         <COMMIT_POINT_SET>
1010                                 (commitPoint = <IDENTIFIER>.image
1011                                 { commitPointSet.add(commitPoint); }
1012                                 )
1013                                 (<OR>
1014                                         (commitPoint = <IDENTIFIER>.image)
1015                                         {
1016                                                 if (commitPointSet.contains(commitPoint)) {
1017                                                         throw new ParseException(interfaceName + " has" +
1018                                                                 "duplicate commit point labels");
1019                                                 }
1020                                                 commitPointSet.add(commitPoint);
1021                                         }
1022                                 )*
1023
1024                         (<CONDITION> (content = C_CPP_CODE(null) { condition = stringArray2String(content); }))?
1025                         (
1026                                 <HB_CONDITION>
1027                                 (hbLabel = <IDENTIFIER>.image) <DOUBLECOLON>
1028                                 (content = C_CPP_CODE(null) { hbCondition = stringArray2String(content); })
1029                                 {
1030                                         if (hbConditions.containsKey(hbLabel)) {
1031                                                 throw new ParseException(interfaceName + " has" +
1032                                                         "duplicate happens-before condtion labels");
1033                                         }
1034                                         hbConditions.put(hbLabel, hbCondition);
1035                                 }
1036                         )*
1037                         (<ID> (content = C_CPP_CODE(null) { idCode = stringArray2String(content); }))?
1038                         (<CHECK> (content = C_CPP_CODE(null) { check = stringArray2String(content); }))?
1039                         (<ACTION> action = C_CPP_CODE(null))?
1040                         (<POST_ACTION> (postAction = C_CPP_CODE(null) ))?
1041                         (<POST_CHECK> (content = C_CPP_CODE(null) { postCheck = stringArray2String(content); }))?
1042                 <END>
1043         {
1044                 res = new InterfaceConstruct(_file, _content.size(), interfaceName, commitPointSet, condition,
1045                         hbConditions, idCode, check, action, postAction, postCheck);
1046                 return res;
1047         }
1048 }
1049
1050
1051 PotentialCPDefineConstruct Potential_commit_point_define() :
1052 {
1053         PotentialCPDefineConstruct res;
1054         String label, condition;
1055         ArrayList<String> content;
1056 }
1057 {
1058
1059         { res = null; }
1060                 <BEGIN>
1061                         <POTENTIAL_COMMIT_POINT_DEFINE> (content = C_CPP_CODE(null) { condition = stringArray2String(content); })
1062                         <LABEL> (label = <IDENTIFIER>.image)
1063                 <END>
1064         {
1065                 res = new PotentialCPDefineConstruct(_file, _content.size(), label, condition); 
1066                 return res;
1067         }
1068 }
1069
1070
1071 CPDefineConstruct Commit_point_define() :
1072 {
1073         CPDefineConstruct res;
1074         String label, potentialCPLabel, condition;
1075         ArrayList<String> content;
1076 }
1077 {
1078
1079         { res = null; }
1080                 <BEGIN>
1081                         <COMMIT_POINT_DEFINE> (content = C_CPP_CODE(null) { condition = stringArray2String(content); })
1082                         <POTENTIAL_COMMIT_POINT_LABEL> (potentialCPLabel = <IDENTIFIER>.image)
1083                         <LABEL> (label = <IDENTIFIER>.image)
1084                 <END>
1085         {
1086                 res = new CPDefineConstruct(_file, _content.size(), label, potentialCPLabel, condition);
1087                 return res;
1088         }
1089 }
1090
1091
1092 CPDefineCheckConstruct Commit_point_define_check() :
1093 {
1094         CPDefineCheckConstruct res;     
1095         String label, condition;
1096         ArrayList<String> content;
1097 }
1098 {
1099
1100         { res = null; }
1101                 <BEGIN> 
1102                         <COMMIT_POINT_DEFINE_CHECK> (content = C_CPP_CODE(null) { condition = stringArray2String(content); })
1103                         <LABEL> (label = <IDENTIFIER>.image)
1104                 <END>
1105         {
1106                 res = new CPDefineCheckConstruct(_file, _content.size(), label, condition);
1107                 return res;
1108         }
1109 }
1110
1111 EntryPointConstruct Entry_point() :
1112 {}
1113 {
1114
1115                 <BEGIN> 
1116                         <ENTRY_POINT>
1117                 <END>
1118         {
1119                 return new EntryPointConstruct(_file, _content.size());
1120         }
1121 }
1122
1123 ClassBeginConstruct Class_begin() :
1124 {}
1125 {
1126
1127                 <BEGIN> 
1128                         <CLASS_BEGIN>
1129                 <END>
1130         {
1131                 return new ClassBeginConstruct(_file, _content.size());
1132         }
1133 }
1134
1135 ClassEndConstruct Class_end() :
1136 {}
1137 {
1138
1139                 <BEGIN> 
1140                         <CLASS_END>
1141                 <END>
1142         {
1143                 return new ClassEndConstruct(_file, _content.size());
1144         }
1145 }
1146
1147 InterfaceDefineConstruct Interface_define() :
1148 {
1149         String name;    
1150 }
1151 {
1152                 <BEGIN>
1153                         <INTERFACE_DEFINE> (name = <IDENTIFIER>.image)
1154                 <END>
1155         {
1156                 return new InterfaceDefineConstruct(_file, _content.size(), name);
1157         }
1158 }