add more parsing
[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         @Global_define:
14                 ...
15         @Interface_cluster:
16                 ...
17         @Happens-before:
18                 ...
19         @End
20         
21         b) Interface construct
22         @Begin
23         @Interface: ...
24         @Commit_point_set:
25                 IDENTIFIER | IDENTIFIER ...
26         @Condition: ... (Optional)
27         @HB_Condition:
28                 IDENTIFIER :: <C_CPP_Condition>
29         @HB_Condition: ...
30         @ID: ... (Optional, use default ID)
31         @Check: (Optional)
32                 ...
33         @Action: (Optional)
34                 @DefineVar: Type var1 = SomeExpression (Optional)
35                 @Code (Optional)
36                 ...
37         @Post_action: (Optional)
38         @Post_check: (Optional)
39         @End
40
41         c) Potential commit construct
42         @Begin
43         @Potential_commit_point_define: ...
44         @Label: ...
45         @End
46
47         d) Commit point define construct
48         @Begin
49         @Commit_point_define_check: ...
50         @Label: ...
51         @End
52         
53                 OR
54
55         @Begin
56         @Commit_point_define: ...
57         @Potential_commit_point_label: ...
58         @Label: ...
59         @End
60 */
61
62
63
64 options {
65         STATIC = false;
66         JAVA_UNICODE_ESCAPE = true;
67 }
68
69 PARSER_BEGIN(SpecParser)
70 package edu.uci.eecs.specCompiler.grammerParser;
71
72 import java.io.FileInputStream;
73 import java.io.FileNotFoundException;
74 import java.util.ArrayList;
75 import java.util.HashMap;
76 import java.util.HashSet;
77
78 import edu.uci.eecs.specCompiler.specExtraction.Construct;
79 import edu.uci.eecs.specCompiler.specExtraction.GlobalConstruct;
80 import edu.uci.eecs.specCompiler.specExtraction.InterfaceConstruct;
81 import edu.uci.eecs.specCompiler.specExtraction.PotentialCPDefineConstruct;
82 import edu.uci.eecs.specCompiler.specExtraction.CPDefineConstruct;
83 import edu.uci.eecs.specCompiler.specExtraction.CPDefineCheckConstruct;
84 import edu.uci.eecs.specCompiler.specExtraction.ConditionalInterface;
85 import edu.uci.eecs.specCompiler.specExtraction.ActionSubConstruct;
86 import edu.uci.eecs.specCompiler.specExtraction.ActionSubConstruct.DefineVar;
87
88         public class SpecParser {
89                 public static void main(String[] argvs)
90                 throws ParseException, TokenMgrError {
91                         try {
92                                 FileInputStream fis = new FileInputStream("./grammer/spec.txt");
93                                 SpecParser parser = new SpecParser(fis);
94                                 parser.Parse();
95                                 System.out.println("Parsing finished!");
96                         } catch (FileNotFoundException e) {
97                                 e.printStackTrace();
98                         }
99                 }
100         }
101 PARSER_END(SpecParser)
102
103 SKIP :
104 {
105         " "
106 |
107         "\n"
108 |
109         "\r"
110 |
111         "\r\n"
112 |
113         "\t"
114 |
115         // "#" comment for the specification
116         <"#" (~["\n", "\r"])* (["\n", "\r"])>
117 |
118         // "//" comment for the specification
119         <"//" (~["\n", "\r"])* (["\n", "\r"])>
120 }
121
122 TOKEN :
123 {
124 /*   Above are specification-only tokens   */
125         <HEAD: "/**">
126 |
127         <TAIL: "*/">
128 |
129         <BEGIN: "@Begin">
130 |
131         <END: "@End">
132 |
133         <GLOBAL_DEFINE: "@Global_define:">
134 |
135         <INTERFACE_CLUSTER: "@Interface_cluster:">
136 |
137         <HAPPENS_BEFORE: "@Happens_before:">
138 |
139         <INTERFACE: "@Interface:">
140 |
141         <COMMIT_POINT_SET: "@Commit_point_set:">
142 |
143         <CONDITION: "@Condition:">
144 |
145         <HB_CONDITION: "@HB_condition:">
146 |
147         <ID: "@ID:">
148 |
149         <CHECK: "@Check:">
150 |
151         <ACTION: "@Action:">
152 |
153         <DEFINEVAR: "@DefineVar:">
154 |
155         <CODE: "@Code:">
156 |
157         <POST_ACTION: "@Post_action:">
158 |
159         <POST_CHECK: "@Post_check:">
160 |
161         <POTENTIAL_COMMIT_POINT_DEFINE: "@Potential_commit_point_define:">
162 |
163         <LABEL: "@Label:">
164 |
165         <COMMIT_POINT_DEFINE_CHECK: "@Commit_point_define_check:">
166 |
167         <COMMIT_POINT_DEFINE: "@Commit_point_define:">
168 |
169         <POTENTIAL_COMMIT_POINT_LABEL: "@Potential_commit_point_label:">
170
171
172 /*   Specification & C/C++ shared tokens   */
173 |
174         <#DIGIT: ["0"-"9"]>
175 |
176         <#LETTER: ["a"-"z", "A"-"Z"]>
177 |
178         <IDENTIFIER: (<LETTER> | "_") (<LETTER> | <DIGIT> | "_")*>
179 |
180         <EQUALS: "=">
181 |
182         <OPEN_PAREN: "{">
183 |
184         <CLOSE_PAREN: "}">
185 |
186         <OPEN_BRACKET: "(">
187 |
188         <CLOSE_BRACKET: ")">
189 |
190         <HB_SYMBOL: "->">
191 |
192         <COMMA: ",">
193
194 |
195 /*   C/C++ only token*/
196         <DOT: ".">
197 |
198         <STAR: "*">
199 |
200         <NEGATE: "~">
201 |
202         <AND: "&">
203 |
204         <OR: "|">
205 |
206         <MOD: "%">
207 |
208         <PLUS: "+">
209 |
210         <PLUSPLUS: "++">
211 |
212         <MINUS: "-">
213 |
214         <MINUSMINUS: "--">
215 |
216         <DIVIDE: "/">
217 |
218         <BACKSLASH: "\\">
219 |
220         <LESS_THAN: "<">
221 |
222         <GREATER_THAN: ">">
223 |
224         <GREATER_EQUALS: ">=">
225 |
226         <LESS_EQUALS: "<=">
227 |
228         <LOGICAL_EQUALS: "==">
229 |
230         <NOT_EQUALS: "!=">
231 |
232         <LOGICAL_AND: "&&">
233 |
234         <LOGICAL_OR: "||">
235 |
236         <XOR: "^">
237 |
238         <QUESTION_MARK: "?">
239 |
240         <COLON: ":">
241 |
242         <DOUBLECOLON: "::">
243 |
244         <SEMI_COLON: ";">
245 |
246         <STRING_LITERAL:
247         "\""
248         ((~["\"","\\","\n","\r"])
249         | ("\\"
250                 ( ["n","t","b","r","f","\\","'","\""]
251                 | ["0"-"7"] ( ["0"-"7"] )?
252                 | ["0"-"3"] ["0"-"7"]
253                         ["0"-"7"]
254                 )
255                 )
256         )*
257         "\"">
258 |
259         <CHARACTER_LITERAL:
260         "'"
261         ((~["'","\\","\n","\r"])
262         | ("\\"
263                 (["n","t","b","r","f","\\","'","\""]
264                 | ["0"-"7"] ( ["0"-"7"] )?
265                 | ["0"-"3"] ["0"-"7"]
266                 ["0"-"7"]
267                 )
268                 )
269         )
270         "'">
271 |
272         < INTEGER_LITERAL:
273         <DECIMAL_LITERAL> (["l","L"])?
274       | <HEX_LITERAL> (["l","L"])?
275       | <OCTAL_LITERAL> (["l","L"])?>
276 |
277         < #DECIMAL_LITERAL: ["1"-"9"] (["0"-"9"])* >
278 |
279         < #HEX_LITERAL: "0" ["x","X"] (["0"-"9","a"-"f","A"-"F"])+ >
280 |
281         < #OCTAL_LITERAL: "0" (["0"-"7"])* >
282 |
283         < FLOATING_POINT_LITERAL:
284         <DECIMAL_FLOATING_POINT_LITERAL>
285       | <HEXADECIMAL_FLOATING_POINT_LITERAL> >
286 |
287         < #DECIMAL_FLOATING_POINT_LITERAL:
288         (["0"-"9"])+ "." (["0"-"9"])* (<DECIMAL_EXPONENT>)? (["f","F","d","D"])?
289       | "." (["0"-"9"])+ (<DECIMAL_EXPONENT>)? (["f","F","d","D"])?
290       | (["0"-"9"])+ <DECIMAL_EXPONENT> (["f","F","d","D"])?
291       | (["0"-"9"])+ (<DECIMAL_EXPONENT>)? ["f","F","d","D"]>
292 |
293         < #DECIMAL_EXPONENT: ["e","E"] (["+","-"])? (["0"-"9"])+ >
294 |
295         < #HEXADECIMAL_FLOATING_POINT_LITERAL:
296         "0" ["x", "X"] (["0"-"9","a"-"f","A"-"F"])+ (".")? <HEXADECIMAL_EXPONENT> (["f","F","d","D"])?
297       | "0" ["x", "X"] (["0"-"9","a"-"f","A"-"F"])* "." (["0"-"9","a"-"f","A"-"F"])+ <HEXADECIMAL_EXPONENT> (["f","F","d","D"])?>
298 |
299         < #HEXADECIMAL_EXPONENT: ["p","P"] (["+","-"])? (["0"-"9"])+ >
300 }
301
302 Construct Parse() :
303 {
304         Construct res;  
305 }
306 {
307         (
308         LOOKAHEAD(3) res = Global_construct() |
309         LOOKAHEAD(3) res = Interface() |
310         LOOKAHEAD(3) res = Potential_commit_point_define() |
311         LOOKAHEAD(3) res = Commit_point_define() |
312         LOOKAHEAD(3) res = Commit_point_define_check()
313         )
314         <EOF>
315         {
316                 System.out.println(res);
317                 return res;
318         }
319 }
320
321 GlobalConstruct Global_construct() :
322 {
323         GlobalConstruct res;
324         String code;
325 }
326 {
327         { res = null; }
328         <HEAD>
329                 <BEGIN> 
330                         (code = Global_define())
331                         { res = new GlobalConstruct(code); }
332                         (Interface_clusters(res))?
333                         (Happens_before(res))?
334                 <END>
335         <TAIL>
336         {
337                 res.unfoldInterfaceCluster();
338                 return res;
339         }
340 }
341
342 String C_CPP_CODE() :
343 {
344         StringBuilder text;
345         Token t;
346 }
347 {
348         {
349                 text = new StringBuilder();
350                 t = new Token();
351         }
352         (
353         //LOOKAHEAD(2)
354         (
355         t = <IDENTIFIER> | t = <EQUALS> | t = <OPEN_PAREN> | t = <CLOSE_PAREN> |
356         t = <OPEN_BRACKET> | t = <CLOSE_BRACKET> | t = <HB_SYMBOL> | t = <COMMA> |
357         t = <DOT> | t = <STAR> | t = <NEGATE> | t = <AND> | t = <OR> | t = <MOD> | t = <PLUS> |
358         t = <PLUSPLUS> | t = <MINUS> | t = <MINUSMINUS> | t = <DIVIDE> | t = <BACKSLASH> |
359         t = <LESS_THAN> | t = <GREATER_THAN> | t = <GREATER_EQUALS>     | t = <LESS_EQUALS> |
360         t = <LOGICAL_EQUALS> | t = <NOT_EQUALS> | t = <LOGICAL_AND> | t = <LOGICAL_OR> | t = <XOR> |
361         t = <QUESTION_MARK> | t = <COLON> | t = <DOUBLECOLON> |
362         t = <SEMI_COLON> | t = <STRING_LITERAL> | t = <CHARACTER_LITERAL> |
363         t = <INTEGER_LITERAL> | t = <FLOATING_POINT_LITERAL>
364         )
365         {
366                 text.append(t.image);
367                 if (t.image.equals(";") || t.image.equals("\\")
368                         || t.image.equals("{") || t.image.equals("}"))
369                         text.append("\n");
370                 else
371                         text.append(" ");
372         }
373         )+
374         {
375                 //System.out.println(text);
376                 return text.toString();
377         }
378 }
379
380 String Global_define() :
381 {
382         String code;    
383 }
384 {
385         <GLOBAL_DEFINE> (code = C_CPP_CODE())
386         {
387                 return code;
388         }
389 }
390
391 ConditionalInterface Conditional_interface() :
392 {
393         String interfaceName, hbConditionLabel;
394 }
395 {
396         {
397                 hbConditionLabel = "";
398         }
399         interfaceName = <IDENTIFIER>.image (<OPEN_BRACKET> hbConditionLabel =
400         <IDENTIFIER>.image <CLOSE_BRACKET>)?
401         {
402                 return new ConditionalInterface(interfaceName, hbConditionLabel);
403         }
404 }
405
406 void Interface_cluster(GlobalConstruct inst) :
407 {
408         String clusterName;
409         ConditionalInterface condInterface;
410 }
411 {
412         (clusterName= <IDENTIFIER>.image)
413         <EQUALS> <OPEN_PAREN>
414                 (condInterface = Conditional_interface()
415                 { inst.addInterface2Cluster(clusterName, condInterface); } 
416                 )
417                 (<COMMA> condInterface = Conditional_interface()
418                 { inst.addInterface2Cluster(clusterName, condInterface); } 
419                 )*
420         <CLOSE_PAREN>
421 }
422
423 void Interface_clusters(GlobalConstruct inst) :
424 {}
425 {
426         <INTERFACE_CLUSTER> (Interface_cluster(inst))+
427 }
428
429 void Happens_before(GlobalConstruct inst) :
430 {
431         ConditionalInterface left, right;       
432 }
433 {
434         <HAPPENS_BEFORE> 
435         (
436         left = Conditional_interface() <HB_SYMBOL> right = Conditional_interface()
437         { inst.addHBCondition(left, right); }
438         )+
439 }
440
441 InterfaceConstruct Interface() :
442 {
443         InterfaceConstruct res;
444         String interfaceName, condition, idCode, check, postAction,
445                 postCheck, commitPoint, hbLabel, hbCondition;
446         ActionSubConstruct action;
447         ArrayList<String> commitPointSet;
448         HashMap<String, String> hbConditions;
449 }
450 {
451         {
452                 res = null;
453                 action = null;
454                 condition = "";
455                 idCode = "";
456                 check = "";
457                 postAction = "";
458                 postCheck = "";
459                 commitPointSet = new ArrayList<String>();
460                 hbConditions = new HashMap<String, String>();
461         }
462         <HEAD> 
463                 <BEGIN>
464                         <INTERFACE> (interfaceName = <IDENTIFIER>.image)
465                         <COMMIT_POINT_SET>
466                                 (commitPoint = <IDENTIFIER>.image
467                                 { commitPointSet.add(commitPoint); }
468                                 )
469                                 (<OR>
470                                         (commitPoint = <IDENTIFIER>.image)
471                                         {
472                                                 if (commitPointSet.contains(commitPoint)) {
473                                                         throw new ParseException(interfaceName + " has" +
474                                                                 "duplicate commit point labels");
475                                                 }
476                                                 commitPointSet.add(commitPoint);
477                                         }
478                                 )*
479
480                         (<CONDITION> (condition = C_CPP_CODE()))?
481                         (
482                                 <HB_CONDITION>
483                                 (hbLabel = <IDENTIFIER>.image)
484                                 (hbCondition = C_CPP_CODE())
485                                 {
486                                         if (hbConditions.containsKey(hbLabel)) {
487                                                 throw new ParseException(interfaceName + " has" +
488                                                         "duplicate happens-before condtion labels");
489                                         }
490                                         hbConditions.put(hbLabel, hbCondition);
491                                 }
492                         )*
493                         (<ID> (idCode = C_CPP_CODE()))?
494                         (<CHECK> (check = C_CPP_CODE()))?
495                         (action = Action())?
496                         (<POST_ACTION> (postAction = C_CPP_CODE()))?
497                         (<POST_CHECK> (postCheck = C_CPP_CODE()))?
498                 <END>
499         <TAIL>
500         {
501                 res = new InterfaceConstruct(interfaceName, commitPointSet, condition,
502                         hbConditions, idCode, check, action, postAction, postCheck);
503                 return res;
504         }
505 }
506
507 ActionSubConstruct Action() :
508 {
509         String type, name, expr, defineVarStr, code;
510         ArrayList<DefineVar> defineVars;
511 }
512 {
513         {
514                 defineVars = new ArrayList<DefineVar>();
515         }
516         <ACTION>
517                 (<DEFINEVAR> (defineVarStr = C_CPP_CODE()) 
518                 {
519                         int eqIdx = defineVarStr.indexOf('=');
520                         int typeEnd = defineVarStr.lastIndexOf(' ', eqIdx - 2);
521                         type = defineVarStr.substring(0, typeEnd);
522                         name = defineVarStr.substring(typeEnd + 1, eqIdx - 1);
523                         expr = defineVarStr.substring(eqIdx + 2);
524                         DefineVar defineVar = new DefineVar(type, name, expr);
525                         defineVars.add(defineVar);
526                 }
527                 )*
528                 <CODE> (code = C_CPP_CODE())
529                 {
530                         ActionSubConstruct res = new ActionSubConstruct(defineVars, code);
531                         return res;
532                 }
533 }
534
535 PotentialCPDefineConstruct Potential_commit_point_define() :
536 {
537         PotentialCPDefineConstruct res;
538         String label, condition;
539 }
540 {
541
542         { res = null; }
543         <HEAD> 
544                 <BEGIN>
545                         <POTENTIAL_COMMIT_POINT_DEFINE> (condition = C_CPP_CODE())
546                         <LABEL> (label = <IDENTIFIER>.image)
547                 <END>
548         <TAIL>
549         {
550                 res = new PotentialCPDefineConstruct(label, condition); 
551                 return res;
552         }
553 }
554
555
556 CPDefineConstruct Commit_point_define() :
557 {
558         CPDefineConstruct res;
559         String label, potentialCPLabel, condition;
560 }
561 {
562
563         { res = null; }
564         <HEAD> 
565                 <BEGIN>
566                         <COMMIT_POINT_DEFINE> (condition = C_CPP_CODE())
567                         <POTENTIAL_COMMIT_POINT_LABEL> (potentialCPLabel = <IDENTIFIER>.image)
568                         <LABEL> (label = <IDENTIFIER>.image)
569                 <END>
570         <TAIL>
571         {
572                 res = new CPDefineConstruct(label, potentialCPLabel, condition);
573                 return res;
574         }
575 }
576
577
578 CPDefineCheckConstruct Commit_point_define_check() :
579 {
580         CPDefineCheckConstruct res;     
581         String label, condition;
582 }
583 {
584
585         { res = null; }
586         <HEAD> 
587                 <BEGIN> 
588                         <COMMIT_POINT_DEFINE_CHECK> (condition = C_CPP_CODE())
589                         <LABEL> (label = <IDENTIFIER>.image)
590                 <END>
591         <TAIL>
592         {
593                 res = new CPDefineCheckConstruct(label, condition);
594                 return res;
595         }
596 }