Charj: allow multiple type definitions per file
[charm.git] / src / langs / charj / src / charj / translator / CharjASTModifier.g
1 /**
2  * The semantic phase walks the tree and builds the symbol table, handles
3  * all the imports, and does the semantic checks. The resulting tree and
4  * symbol table are used by the emitter to generate the output. 
5  */
6
7 tree grammar CharjASTModifier;
8
9 options {
10     backtrack = true; 
11     memoize = true;
12     tokenVocab = Charj;
13     ASTLabelType = CharjAST;
14     output = AST;
15 }
16
17 @header {
18 package charj.translator;
19 }
20
21 @members {
22     SymbolTable symtab = null;
23     PackageScope currentPackage = null;
24     ClassSymbol currentClass = null;
25     MethodSymbol currentMethod = null;
26     LocalScope currentLocalScope = null;
27     Translator translator;
28
29     PupRoutineCreator puper = new PupRoutineCreator();
30 }
31
32 // Replace default ANTLR generated catch clauses with this action, allowing early failure.
33 @rulecatch {
34     catch (RecognitionException re) {
35         reportError(re);
36         throw re;
37     }
38 }
39
40
41 // Starting point for parsing a Charj file.
42 charjSource[SymbolTable _symtab] returns [ClassSymbol cs]
43 @init {
44     symtab = _symtab;
45 }
46     // TODO: go back to allowing multiple type definitions per file, check that
47     // there is exactly one public type and return that one.
48     :   ^(CHARJ_SOURCE 
49         (packageDeclaration)? 
50         (importDeclarations) 
51         (typeDeclaration[$importDeclarations.packageNames])*)
52         { $cs = $typeDeclaration.sym; }
53     ;
54
55 packageDeclaration
56     :   ^(PACKAGE (ids+=IDENT)+)  
57     ;
58     
59 importDeclarations returns [List<CharjAST> packageNames]
60     :   (^(IMPORT qualifiedIdentifier '.*'?))*
61     ;
62
63 typeDeclaration[List<CharjAST> imports] returns [ClassSymbol sym]
64     :   ^(TYPE (CLASS | chareType) IDENT (^('extends' parent=type))? (^('implements' type+))? classScopeDeclaration*)
65         {
66             $TYPE.tree.addChild(puper.getPupRoutineNode());
67             $TYPE.tree.addChild(puper.getInitRoutineNode());
68             puper = new PupRoutineCreator();
69         }
70     |   ^(INTERFACE IDENT (^('extends' type+))?  interfaceScopeDeclaration*)
71     |   ^(ENUM IDENT (^('implements' type+))? enumConstant+ classScopeDeclaration*)
72     ;
73
74 chareType
75     :   CHARE
76     |   GROUP
77     |   NODEGROUP
78     |   MAINCHARE
79     |   ^(CHARE_ARRAY ARRAY_DIMENSION)
80     ;
81
82 enumConstant
83     :   ^(IDENT arguments?)
84     ;
85     
86 classScopeDeclaration
87     :   ^(FUNCTION_METHOD_DECL m=modifierList? g=genericTypeParameterList? 
88             ty=type IDENT f=formalParameterList a=arrayDeclaratorList? 
89             b=block?)
90     |   ^(PRIMITIVE_VAR_DECLARATION modifierList? simpleType variableDeclaratorList)
91     |   ^(OBJECT_VAR_DECLARATION modifierList? objectType variableDeclaratorList)
92     |   ^(CONSTRUCTOR_DECL m=modifierList? g=genericTypeParameterList? IDENT f=formalParameterList 
93             b=block)
94     ;
95     
96 interfaceScopeDeclaration
97     :   ^(FUNCTION_METHOD_DECL modifierList? genericTypeParameterList? 
98             type IDENT formalParameterList arrayDeclaratorList?)
99         // Interface constant declarations have been switched to variable
100         // declarations by Charj.g; the parser has already checked that
101         // there's an obligatory initializer.
102     |   ^(PRIMITIVE_VAR_DECLARATION modifierList? simpleType variableDeclaratorList)
103     |   ^(OBJECT_VAR_DECLARATION modifierList? objectType variableDeclaratorList)
104     ;
105
106 variableDeclaratorList
107     :   ^(VAR_DECLARATOR_LIST variableDeclarator+)
108     ;
109
110 variableDeclarator
111     :   ^(VAR_DECLARATOR variableDeclaratorId variableInitializer?)
112     ;
113     
114 variableDeclaratorId
115     :   ^(IDENT arrayDeclaratorList?)
116         {
117             puper.varPup($IDENT);
118         }
119     ;
120
121 variableInitializer
122     :   arrayInitializer
123     |   expression
124     ;
125
126 arrayDeclaratorList
127     :   ^(ARRAY_DECLARATOR_LIST ARRAY_DECLARATOR*)  
128     ;
129     
130 arrayInitializer
131     :   ^(ARRAY_INITIALIZER variableInitializer*)
132     ;
133
134 genericTypeParameterList
135     :   ^(GENERIC_TYPE_PARAM_LIST genericTypeParameter+)
136     ;
137
138 genericTypeParameter
139     :   ^(IDENT bound?)
140     ;
141         
142 bound
143     :   ^(EXTENDS_BOUND_LIST type+)
144     ;
145
146 modifierList
147     :   ^(MODIFIER_LIST modifier+)
148     ;
149
150 modifier
151     :   PUBLIC
152     |   PROTECTED
153     |   PRIVATE
154     |   ENTRY
155     |   ABSTRACT
156     |   NATIVE
157     |   localModifier
158     ;
159
160 localModifierList
161     :   ^(LOCAL_MODIFIER_LIST localModifier+)
162     ;
163
164 localModifier
165     :   FINAL
166     |   STATIC
167     |   VOLATILE
168     ;
169
170 type
171     :   simpleType
172     |   objectType 
173     |   VOID
174     ;
175
176 simpleType
177     :   ^(SIMPLE_TYPE primitiveType arrayDeclaratorList?)
178     ;
179     
180 objectType
181     :   ^(OBJECT_TYPE qualifiedTypeIdent arrayDeclaratorList?)
182     |   ^(PROXY_TYPE qualifiedTypeIdent arrayDeclaratorList?)
183     |   ^(REFERENCE_TYPE qualifiedTypeIdent arrayDeclaratorList?)
184     |   ^(POINTER_TYPE qualifiedTypeIdent arrayDeclaratorList?)
185     ;
186
187 qualifiedTypeIdent
188     :   ^(QUALIFIED_TYPE_IDENT typeIdent+) 
189     ;
190
191 typeIdent
192     :   ^(IDENT genericTypeArgumentList?)
193     ;
194
195 primitiveType
196     :   BOOLEAN     { $start.symbol = new Symbol(symtab, "bool_primitive", symtab.resolveBuiltinType("bool")); }
197     |   CHAR        { $start.symbol = new Symbol(symtab, "char_primitive", symtab.resolveBuiltinType("char")); }
198     |   BYTE        { $start.symbol = new Symbol(symtab, "byte_primitive", symtab.resolveBuiltinType("char")); }
199     |   SHORT       { $start.symbol = new Symbol(symtab, "short_primitive", symtab.resolveBuiltinType("short")); }
200     |   INT         { $start.symbol = new Symbol(symtab, "int_primitive", symtab.resolveBuiltinType("int")); }
201     |   LONG        { $start.symbol = new Symbol(symtab, "long_primitive", symtab.resolveBuiltinType("long")); }
202     |   FLOAT       { $start.symbol = new Symbol(symtab, "float_primitive", symtab.resolveBuiltinType("float")); }
203     |   DOUBLE      { $start.symbol = new Symbol(symtab, "double_primitive", symtab.resolveBuiltinType("double")); }
204     ;
205
206 genericTypeArgumentList
207     :   ^(GENERIC_TYPE_ARG_LIST genericTypeArgument+)
208     ;
209     
210 genericTypeArgument
211     :   type
212     |   '?'
213     ;
214
215 formalParameterList
216     :   ^(FORMAL_PARAM_LIST formalParameterStandardDecl* formalParameterVarargDecl?) 
217     ;
218     
219 formalParameterStandardDecl
220     :   ^(FORMAL_PARAM_STD_DECL localModifierList? type variableDeclaratorId)
221     ;
222     
223 formalParameterVarargDecl
224     :   ^(FORMAL_PARAM_VARARG_DECL localModifierList? type variableDeclaratorId)
225     ;
226     
227 // FIXME: is this rule right? Verify that this is ok, I expected something like:
228 // IDENT (^(DOT qualifiedIdentifier IDENT))*
229 qualifiedIdentifier
230     :   IDENT
231     |   ^(DOT qualifiedIdentifier IDENT)
232     ;
233     
234 block
235     :   ^(BLOCK (blockStatement)*)
236     ;
237     
238 blockStatement
239     :   localVariableDeclaration
240     |   statement
241     ;
242     
243 localVariableDeclaration
244     :   ^(PRIMITIVE_VAR_DECLARATION localModifierList? simpleType variableDeclaratorList)
245     |   ^(OBJECT_VAR_DECLARATION localModifierList? objectType variableDeclaratorList)
246     ;
247
248 statement
249     :   nonBlockStatement
250     |   block
251     ;
252
253 nonBlockStatement
254     :   ^(ASSERT expression expression?)
255     |   ^(IF parenthesizedExpression block block?)
256     |   ^(FOR forInit? FOR_EXPR expression? FOR_UPDATE expression* block)
257     |   ^(FOR_EACH localModifierList? type IDENT expression block) 
258     |   ^(WHILE parenthesizedExpression block)
259     |   ^(DO block parenthesizedExpression)
260     |   ^(SWITCH parenthesizedExpression switchCaseLabel*)
261     |   ^(RETURN expression?)
262     |   ^(THROW expression)
263     |   ^(BREAK IDENT?) {
264             if ($IDENT != null) {
265                 translator.error(this, "Labeled break not supported yet, ignoring.", $IDENT);
266             }
267         }
268     |   ^(CONTINUE IDENT?) {
269             if ($IDENT != null) {
270                 translator.error(this, "Labeled continue not supported yet, ignoring.", $IDENT);
271             }
272         }
273     |   ^(LABELED_STATEMENT IDENT statement)
274     |   expression
275     |   ^('delete' qualifiedIdentifier)
276     |   ^(EMBED STRING_LITERAL EMBED_BLOCK)
277     |   ';' // Empty statement.
278     ;
279         
280 switchCaseLabel
281     :   ^(CASE expression blockStatement*)
282     |   ^(DEFAULT blockStatement*)
283     ;
284     
285 forInit
286     :   localVariableDeclaration 
287     |   expression+
288     ;
289     
290 // EXPRESSIONS
291
292 parenthesizedExpression
293     :   ^(PAREN_EXPR expression)
294     ;
295     
296 expression
297     :   ^(EXPR expr)
298     ;
299
300 expr
301     :   ^(ASSIGNMENT expr expr)
302     |   ^(PLUS_EQUALS expr expr)
303     |   ^(MINUS_EQUALS expr expr)
304     |   ^(TIMES_EQUALS expr expr)
305     |   ^(DIVIDE_EQUALS expr expr)
306     |   ^(AND_EQUALS expr expr)
307     |   ^(OR_EQUALS expr expr)
308     |   ^(POWER_EQUALS expr expr)
309     |   ^(MOD_EQUALS expr expr)
310     |   ^('>>>=' expr expr)
311     |   ^('>>=' expr expr)
312     |   ^('<<=' expr expr)
313     |   ^('?' expr expr expr)
314     |   ^(OR expr expr)
315     |   ^(AND expr expr)
316     |   ^(BITWISE_OR expr expr)
317     |   ^(POWER expr expr)
318     |   ^(BITWISE_AND expr expr)
319     |   ^(EQUALS expr expr)
320     |   ^(NOT_EQUALS expr expr)
321     |   ^(INSTANCEOF expr type)
322     |   ^(LTE expr expr)
323     |   ^(GTE expr expr)
324     |   ^('>>>' expr expr)
325     |   ^('>>' expr expr)
326     |   ^(GT expr expr)
327     |   ^('<<' expr expr)
328     |   ^(LT expr expr)
329     |   ^(PLUS expr expr)
330     |   ^(MINUS expr expr)
331     |   ^(TIMES expr expr)
332     |   ^(DIVIDE expr expr)
333     |   ^(MOD expr expr)
334     |   ^(UNARY_PLUS expr)
335     |   ^(UNARY_MINUS expr)
336     |   ^(PRE_INC expr)
337     |   ^(PRE_DEC expr)
338     |   ^(POST_INC expr)
339     |   ^(POST_DEC expr)
340     |   ^(TILDE expr)
341     |   ^(NOT expr)
342     |   ^(CAST_EXPR type expr)
343     |   primaryExpression
344     ;
345     
346 primaryExpression
347     :   ^(DOT primaryExpression
348                 (   IDENT
349                 |   THIS
350                 |   SUPER
351                 )
352         )
353         ->   ^(ARROW primaryExpression
354                    IDENT?
355                    THIS?
356                    SUPER?
357              )
358     |   parenthesizedExpression
359     |   IDENT
360     |   ^(METHOD_CALL primaryExpression genericTypeArgumentList? arguments)
361     |   ^(ENTRY_METHOD_CALL ^(AT primaryExpression IDENT) genericTypeArgumentList? arguments)
362         ->  ^(ENTRY_METHOD_CALL ^(DOT primaryExpression IDENT) genericTypeArgumentList? arguments)
363     |   explicitConstructorCall
364     |   ^(ARRAY_ELEMENT_ACCESS primaryExpression expression)
365     |   literal
366     |   newExpression
367     |   THIS
368     |   arrayTypeDeclarator
369     |   SUPER
370     ;
371     
372 explicitConstructorCall
373     :   ^(THIS_CONSTRUCTOR_CALL genericTypeArgumentList? arguments)
374     |   ^(SUPER_CONSTRUCTOR_CALL primaryExpression? genericTypeArgumentList? arguments)
375     ;
376
377 arrayTypeDeclarator
378     :   ^(ARRAY_DECLARATOR (arrayTypeDeclarator | qualifiedIdentifier | primitiveType))
379     ;
380
381 newExpression
382     :   ^(  STATIC_ARRAY_CREATOR
383             (   primitiveType newArrayConstruction
384             |   genericTypeArgumentList? qualifiedTypeIdent newArrayConstruction
385             )
386         )
387     |   ^(NEW qualifiedTypeIdent arguments)
388     ;
389
390 newArrayConstruction
391     :   arrayDeclaratorList arrayInitializer
392     |   expression+ arrayDeclaratorList?
393     ;
394
395 arguments
396     :   ^(ARGUMENT_LIST expression*)
397     ;
398
399 literal 
400     :   HEX_LITERAL
401     |   OCTAL_LITERAL
402     |   DECIMAL_LITERAL
403     |   FLOATING_POINT_LITERAL
404     |   CHARACTER_LITERAL
405     |   STRING_LITERAL          
406     |   TRUE
407     |   FALSE
408     |   NULL
409     ;
410