c048141757d13c02a569022f959815f02e0de274
[cdsspec-compiler.git] / grammer / spec-compiler.jj
1 /* spec-compiler.jj Grammer definition for the specification */
2
3
4 /*
5         SPEC constructs:
6         Each construct should be embraced by /DOUBLE_STAR ... STAR/ annotation.
7         Within there, any line beginning with a "#" is a comment of the annotation.
8         Each constrcut should begin with @Begin and end with @End. Otherwise, the
9         annotation would be considered as normal comments of the source.
10         
11         a) Global construct
12         @Begin
13         @Options:
14                 # If LANG is not define, it's C++ by default. C does not support class
15                 # and template, so if it's defined as C, we should also have a explicit
16                 # entry point.
17                 LANG = C;
18         @Global_define:
19                 @DeclareVar:
20                 @InitVar:
21                 @DefineFunc:
22                 ...
23         @Interface_cluster:
24                 ...
25         @Happens-before:
26                 ...
27         @End
28         
29         b) Interface construct
30         @Begin
31         @Interface: ...
32         @Commit_point_set:
33                 IDENTIFIER | IDENTIFIER ...
34         @Condition: ... (Optional)
35         @HB_Condition:
36                 IDENTIFIER :: <C_CPP_Condition>
37         @HB_Condition: ...
38         @ID: ... (Optional, use default ID)
39         @Check: (Optional)
40                 ...
41         @Action: (Optional)
42                 # Type here must be a pointer
43                 @DefineVar: Type var1 = SomeExpression (Optional)
44                 @Code (Optional)
45                 ...
46         @Post_action: (Optional)
47         @Post_check: (Optional)
48         @End
49
50         c) Potential commit construct
51         @Begin
52         @Potential_commit_point_define: ...
53         @Label: ...
54         @End
55
56         d) Commit point define construct
57         @Begin
58         @Commit_point_define_check: ...
59         @Label: ...
60         @End
61         
62                 OR
63
64         @Begin
65         @Commit_point_define: ...
66         @Potential_commit_point_label: ...
67         @Label: ...
68         @End
69
70         e) Entry point construct
71         @Begin
72         @Entry_point
73         @End
74
75         f) Interface define construct
76         @Begin
77         @Interface_define: <Interface_Name>
78         @End
79 */
80
81
82
83 options {
84         STATIC = false;
85         JAVA_UNICODE_ESCAPE = true;
86 }
87
88 PARSER_BEGIN(SpecParser)
89 package edu.uci.eecs.specCompiler.grammerParser;
90
91 import java.io.FileInputStream;
92 import java.io.FileNotFoundException;
93 import java.io.InputStream;
94 import java.io.ByteArrayInputStream;
95 import java.util.ArrayList;
96 import java.util.HashMap;
97 import java.util.HashSet;
98
99 import edu.uci.eecs.specCompiler.specExtraction.Construct;
100 import edu.uci.eecs.specCompiler.specExtraction.GlobalConstruct;
101 import edu.uci.eecs.specCompiler.specExtraction.InterfaceConstruct;
102 import edu.uci.eecs.specCompiler.specExtraction.PotentialCPDefineConstruct;
103 import edu.uci.eecs.specCompiler.specExtraction.CPDefineConstruct;
104 import edu.uci.eecs.specCompiler.specExtraction.CPDefineCheckConstruct;
105 import edu.uci.eecs.specCompiler.specExtraction.ConditionalInterface;
106 import edu.uci.eecs.specCompiler.specExtraction.ActionSubConstruct;
107 import edu.uci.eecs.specCompiler.specExtraction.ActionSubConstruct.DefineVar;
108 import edu.uci.eecs.specCompiler.specExtraction.SequentialDefineSubConstruct;
109 import edu.uci.eecs.specCompiler.specExtraction.InterfaceDefineConstruct;
110 import edu.uci.eecs.specCompiler.specExtraction.EntryPointConstruct;
111
112         public class SpecParser {
113                 public static void main(String[] argvs)
114                 throws ParseException, TokenMgrError {
115                         try {
116                                 FileInputStream fis = new FileInputStream("./grammer/spec.txt");
117                                 SpecParser parser = new SpecParser(fis);
118                                 parser.ParseSpec();
119                                 System.out.println("Parsing finished!");
120                         } catch (FileNotFoundException e) {
121                                 e.printStackTrace();
122                         }
123                 }
124         
125                 public static Construct parseSpec(String text)
126                 throws ParseException, TokenMgrError {
127                         InputStream input = new ByteArrayInputStream(text.getBytes());
128                         SpecParser parser = new SpecParser(input);
129                         return parser.Parse();
130                 }
131
132
133         }
134 PARSER_END(SpecParser)
135
136 < IN_COMMENT > SKIP : { <  ~[] > }
137
138 < IN_COMMENT, IN_SPEC > SKIP : {
139         "*/": DEFAULT
140 }
141
142 SKIP : {
143         "/*": IN_COMMENT
144 }
145
146 SKIP : {
147         "/**": IN_SPEC
148 }
149
150 <IN_SPEC> TOKEN : {
151         <BEGIN: "@Begin">
152 |
153         <END: "@End">
154 |
155         <OPTIONS: "@Options:">
156 |
157         <GLOBAL_DEFINE: "@Global_define:">
158 |
159         <DECLARE_VAR: "@DeclareVar:">
160 |
161         <INIT_VAR: "@InitVar:">
162 |
163         <DEFINE_FUNC: "@DefineFunc:">
164 |
165         <INTERFACE_CLUSTER: "@Interface_cluster:">
166 |
167         <HAPPENS_BEFORE: "@Happens_before:">
168 |
169         <INTERFACE: "@Interface:">
170 |
171         <COMMIT_POINT_SET: "@Commit_point_set:">
172 |
173         <ENTRY_POINT: "@Entry_point">
174 |
175         <INTERFACE_DEFINE: "@Interface_define:">
176 |
177         <CONDITION: "@Condition:">
178 |
179         <HB_CONDITION: "@HB_condition:">
180 |
181         <ID: "@ID:">
182 |
183         <CHECK: "@Check:">
184 |
185         <ACTION: "@Action:">
186 |
187         <DEFINEVAR: "@DefineVar:">
188 |
189         <CODE: "@Code:">
190 |
191         <POST_ACTION: "@Post_action:">
192 |
193         <POST_CHECK: "@Post_check:">
194 |
195         <POTENTIAL_COMMIT_POINT_DEFINE: "@Potential_commit_point_define:">
196 |
197         <LABEL: "@Label:">
198 |
199         <COMMIT_POINT_DEFINE_CHECK: "@Commit_point_define_check:">
200 |
201         <COMMIT_POINT_DEFINE: "@Commit_point_define:">
202 |
203         <POTENTIAL_COMMIT_POINT_LABEL: "@Potential_commit_point_label:">
204 }
205
206 SKIP :
207 {
208         " "
209 |
210         "\n"
211 |
212         "\r"
213 |
214         "\r\n"
215 |
216         "\t"
217 |
218         // "#" comment for the specification
219         <"#" (~["\n", "\r"])* (["\n", "\r"])>
220 |
221         // "//" comment for the specification
222         <"//" (~["\n", "\r"])* (["\n", "\r"])>
223 }
224
225 <IN_SPEC, DEFAULT> TOKEN :
226 {
227 /*   Specification & C/C++ shared tokens   */
228 // Reserved keywords
229         <CONST: "const">
230 |
231         <STRUCT: "struct">
232 |
233         <TYPENAME: "typename">
234 |
235         <#DIGIT: ["0"-"9"]>
236 |
237         <#LETTER: ["a"-"z", "A"-"Z"]>
238 |
239         <IDENTIFIER: (<LETTER> | "_") (<LETTER> | <DIGIT> | "_")*>
240 |
241         <EQUALS: "=">
242 |
243         <OPEN_PAREN: "{">
244 |
245         <CLOSE_PAREN: "}">
246 |
247         <OPEN_BRACKET: "(">
248 |
249         <CLOSE_BRACKET: ")">
250 |
251         <HB_SYMBOL: "->">
252 |
253         <COMMA: ",">
254
255 |
256 /*   C/C++ only token*/
257         <DOT: ".">
258 |
259         <STAR: "*">
260 |
261         <NEGATE: "~">
262 |
263         <EXCLAMATION: "!">
264 |
265         <AND: "&">
266 |
267         <OR: "|">
268 |
269         <MOD: "%">
270 |
271         <PLUS: "+">
272 |
273         <PLUSPLUS: "++">
274 |
275         <MINUS: "-">
276 |
277         <MINUSMINUS: "--">
278 |
279         <DIVIDE: "/">
280 |
281         <BACKSLASH: "\\">
282 |
283         <LESS_THAN: "<">
284 |
285         <GREATER_THAN: ">">
286 |
287         <GREATER_EQUALS: ">=">
288 |
289         <LESS_EQUALS: "<=">
290 |
291         <LOGICAL_EQUALS: "==">
292 |
293         <NOT_EQUALS: "!=">
294 |
295         <LOGICAL_AND: "&&">
296 |
297         <LOGICAL_OR: "||">
298 |
299         <XOR: "^">
300 |
301         <QUESTION_MARK: "?">
302 |
303         <COLON: ":">
304 |
305         <DOUBLECOLON: "::">
306 |
307         <SEMI_COLON: ";">
308 |
309         <STRING_LITERAL:
310         "\""
311         ((~["\"","\\","\n","\r"])
312         | ("\\"
313                 ( ["n","t","b","r","f","\\","'","\""]
314                 | ["0"-"7"] ( ["0"-"7"] )?
315                 | ["0"-"3"] ["0"-"7"]
316                         ["0"-"7"]
317                 )
318                 )
319         )*
320         "\"">
321 |
322         <CHARACTER_LITERAL:
323         "'"
324         ((~["'","\\","\n","\r"])
325         | ("\\"
326                 (["n","t","b","r","f","\\","'","\""]
327                 | ["0"-"7"] ( ["0"-"7"] )?
328                 | ["0"-"3"] ["0"-"7"]
329                 ["0"-"7"]
330                 )
331                 )
332         )
333         "'">
334 |
335         < INTEGER_LITERAL:
336         <DECIMAL_LITERAL> (["l","L"])?
337       | <HEX_LITERAL> (["l","L"])?
338       | <OCTAL_LITERAL> (["l","L"])?>
339 |
340         < #DECIMAL_LITERAL: ["1"-"9"] (["0"-"9"])* >
341 |
342         < #HEX_LITERAL: "0" ["x","X"] (["0"-"9","a"-"f","A"-"F"])+ >
343 |
344         < #OCTAL_LITERAL: "0" (["0"-"7"])* >
345 |
346         < FLOATING_POINT_LITERAL:
347         <DECIMAL_FLOATING_POINT_LITERAL>
348       | <HEXADECIMAL_FLOATING_POINT_LITERAL> >
349 |
350         < #DECIMAL_FLOATING_POINT_LITERAL:
351         (["0"-"9"])+ "." (["0"-"9"])* (<DECIMAL_EXPONENT>)? (["f","F","d","D"])?
352       | "." (["0"-"9"])+ (<DECIMAL_EXPONENT>)? (["f","F","d","D"])?
353       | (["0"-"9"])+ <DECIMAL_EXPONENT> (["f","F","d","D"])?
354       | (["0"-"9"])+ (<DECIMAL_EXPONENT>)? ["f","F","d","D"]>
355 |
356         < #DECIMAL_EXPONENT: ["e","E"] (["+","-"])? (["0"-"9"])+ >
357 |
358         < #HEXADECIMAL_FLOATING_POINT_LITERAL:
359         "0" ["x", "X"] (["0"-"9","a"-"f","A"-"F"])+ (".")? <HEXADECIMAL_EXPONENT> (["f","F","d","D"])?
360       | "0" ["x", "X"] (["0"-"9","a"-"f","A"-"F"])* "." (["0"-"9","a"-"f","A"-"F"])+ <HEXADECIMAL_EXPONENT> (["f","F","d","D"])?>
361 |
362         < #HEXADECIMAL_EXPONENT: ["p","P"] (["+","-"])? (["0"-"9"])+ >
363 }
364
365 String Type() :
366 {
367         String type;
368         String str;
369 }
370 {
371         { type = ""; }
372         ("const"
373         { type = "const"; }
374         )?
375         (("struct" { type = type + " struct"; })? 
376         (str = <IDENTIFIER>.image {
377                 if (!type.equals(""))
378                         type = type + " " + str;
379                 else
380                         type = str;
381         }))
382         ((str = "const".image {
383                 if (!type.equals(""))
384                         type = type + " " + str;
385                 else
386                         type = str;
387         }) |
388         (str = <STAR>.image {
389                 if (!type.equals(""))
390                         type = type + " " + str;
391                 else
392                         type = str;
393         }) |
394         (str = <AND>.image {
395                 if (!type.equals(""))
396                         type = type + " " + str;
397                 else
398                         type = str;
399         })
400         )*
401         {
402                 return type;
403         }
404 }
405
406 ArrayList<String> FormalParamList() :
407 {
408         ArrayList<String> typeParams;
409 }
410 {
411         {
412                 typeParams = new ArrayList<String>();
413         }
414         (TypeParam(typeParams) (<COMMA> TypeParam(typeParams))*)?
415         {
416                 System.out.println(typeParams);
417                 return typeParams;
418         }
419 }
420
421 void TypeParam(ArrayList<String> typeParams) :
422 {
423         String type, param;
424 }
425 {
426         (type = Type()) (param = <IDENTIFIER>.image)
427         {
428                 typeParams.add(type);
429                 typeParams.add(param);
430         }
431 }
432
433 void ParseSpec() :
434 {}
435 {
436         <BEGIN> <POTENTIAL_COMMIT_POINT_DEFINE> C_CPP_CODE() <LABEL> <END>
437 }
438
439 String C_CPP_CODE() :
440 {
441         StringBuilder text;
442         Token t;
443 }
444 {
445         {
446                 text = new StringBuilder();
447                 t = new Token();
448         }
449         (
450         //LOOKAHEAD(2)
451         (
452         t = <CONST> | t = <STRUCT> |
453         t = <IDENTIFIER> | t = <EQUALS> | t = <OPEN_PAREN> | t = <CLOSE_PAREN> |
454         t = <OPEN_BRACKET> | t = <CLOSE_BRACKET> | t = <HB_SYMBOL> | t = <COMMA> |
455         t = <DOT> | t = <STAR> | t = <NEGATE> | t = <EXCLAMATION> | t = <AND> | t = <OR> | t = <MOD> | t = <PLUS> |
456         t = <PLUSPLUS> | t = <MINUS> | t = <MINUSMINUS> | t = <DIVIDE> | t = <BACKSLASH> |
457         t = <LESS_THAN> | t = <GREATER_THAN> | t = <GREATER_EQUALS>     | t = <LESS_EQUALS> |
458         t = <LOGICAL_EQUALS> | t = <NOT_EQUALS> | t = <LOGICAL_AND> | t = <LOGICAL_OR> | t = <XOR> |
459         t = <QUESTION_MARK> | t = <COLON> | t = <DOUBLECOLON> |
460         t = <SEMI_COLON> | t = <STRING_LITERAL> | t = <CHARACTER_LITERAL> |
461         t = <INTEGER_LITERAL> | t = <FLOATING_POINT_LITERAL>
462         )
463         {
464                 text.append(t.image);
465                 if (t.image.equals(";") || t.image.equals("\\")
466                         || t.image.equals("{") || t.image.equals("}"))
467                         text.append("\n");
468                 else
469                         text.append(" ");
470         }
471         )+
472         {
473                 //System.out.println(text);
474                 return text.toString();
475         }
476 }
477
478
479 void Comment() :
480 {}
481 {
482         C_CPP_CODE() 
483 }
484
485 void Parse() :
486 {}
487 {
488         C_CPP_CODE() | 
489         <EOF>
490 }