a87844470257df290ec4eaa44df1fecb69dfa29b
[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         }
68     |   ^(INTERFACE IDENT (^('extends' type+))?  interfaceScopeDeclaration*)
69     |   ^(ENUM IDENT (^('implements' type+))? enumConstant+ classScopeDeclaration*)
70     ;
71
72 chareType
73     :   CHARE
74     |   GROUP
75     |   NODEGROUP
76     |   ^(CHARE_ARRAY ARRAY_DIMENSION)
77     ;
78
79 enumConstant
80     :   ^(IDENT arguments?)
81     ;
82     
83 classScopeDeclaration
84     :   ^(FUNCTION_METHOD_DECL m=modifierList? g=genericTypeParameterList? 
85             ty=type IDENT f=formalParameterList a=arrayDeclaratorList? 
86             b=block?)
87     |   ^(PRIMITIVE_VAR_DECLARATION modifierList? simpleType variableDeclaratorList)
88     |   ^(OBJECT_VAR_DECLARATION modifierList? objectType variableDeclaratorList)
89     |   ^(CONSTRUCTOR_DECL m=modifierList? g=genericTypeParameterList? IDENT f=formalParameterList 
90             b=block)
91     ;
92     
93 interfaceScopeDeclaration
94     :   ^(FUNCTION_METHOD_DECL modifierList? genericTypeParameterList? 
95             type IDENT formalParameterList arrayDeclaratorList?)
96         // Interface constant declarations have been switched to variable
97         // declarations by Charj.g; the parser has already checked that
98         // there's an obligatory initializer.
99     |   ^(PRIMITIVE_VAR_DECLARATION modifierList? simpleType variableDeclaratorList)
100     |   ^(OBJECT_VAR_DECLARATION modifierList? objectType variableDeclaratorList)
101     ;
102
103 variableDeclaratorList
104     :   ^(VAR_DECLARATOR_LIST variableDeclarator+)
105     ;
106
107 variableDeclarator
108     :   ^(VAR_DECLARATOR variableDeclaratorId variableInitializer?)
109     ;
110     
111 variableDeclaratorId
112     :   ^(IDENT arrayDeclaratorList?)
113         {
114             puper.varPup($IDENT);
115         }
116     ;
117
118 variableInitializer
119     :   arrayInitializer
120     |   expression
121     ;
122
123 arrayDeclaratorList
124     :   ^(ARRAY_DECLARATOR_LIST ARRAY_DECLARATOR*)  
125     ;
126     
127 arrayInitializer
128     :   ^(ARRAY_INITIALIZER variableInitializer*)
129     ;
130
131 genericTypeParameterList
132     :   ^(GENERIC_TYPE_PARAM_LIST genericTypeParameter+)
133     ;
134
135 genericTypeParameter
136     :   ^(IDENT bound?)
137     ;
138         
139 bound
140     :   ^(EXTENDS_BOUND_LIST type+)
141     ;
142
143 modifierList
144     :   ^(MODIFIER_LIST modifier+)
145     ;
146
147 modifier
148     :   PUBLIC
149     |   PROTECTED
150     |   PRIVATE
151     |   ENTRY
152     |   ABSTRACT
153     |   NATIVE
154     |   localModifier
155     ;
156
157 localModifierList
158     :   ^(LOCAL_MODIFIER_LIST localModifier+)
159     ;
160
161 localModifier
162     :   FINAL
163     |   STATIC
164     |   VOLATILE
165     ;
166
167 type
168     :   simpleType
169     |   objectType 
170     |   VOID
171     ;
172
173 simpleType
174     :   ^(SIMPLE_TYPE primitiveType arrayDeclaratorList?)
175     ;
176     
177 objectType
178     :   ^(OBJECT_TYPE qualifiedTypeIdent arrayDeclaratorList?)
179     |   ^(REFERENCE_TYPE qualifiedTypeIdent arrayDeclaratorList?)
180     |   ^(POINTER_TYPE qualifiedTypeIdent arrayDeclaratorList?)
181     ;
182
183 qualifiedTypeIdent
184     :   ^(QUALIFIED_TYPE_IDENT typeIdent+) 
185     ;
186
187 typeIdent
188     :   ^(IDENT genericTypeArgumentList?)
189     ;
190
191 primitiveType
192     :   BOOLEAN     { $start.symbol = new Symbol(symtab, "bool_primitive", symtab.resolveBuiltinType("bool")); }
193     |   CHAR        { $start.symbol = new Symbol(symtab, "char_primitive", symtab.resolveBuiltinType("char")); }
194     |   BYTE        { $start.symbol = new Symbol(symtab, "byte_primitive", symtab.resolveBuiltinType("char")); }
195     |   SHORT       { $start.symbol = new Symbol(symtab, "short_primitive", symtab.resolveBuiltinType("short")); }
196     |   INT         { $start.symbol = new Symbol(symtab, "int_primitive", symtab.resolveBuiltinType("int")); }
197     |   LONG        { $start.symbol = new Symbol(symtab, "long_primitive", symtab.resolveBuiltinType("long")); }
198     |   FLOAT       { $start.symbol = new Symbol(symtab, "float_primitive", symtab.resolveBuiltinType("float")); }
199     |   DOUBLE      { $start.symbol = new Symbol(symtab, "double_primitive", symtab.resolveBuiltinType("double")); }
200     ;
201
202 genericTypeArgumentList
203     :   ^(GENERIC_TYPE_ARG_LIST genericTypeArgument+)
204     ;
205     
206 genericTypeArgument
207     :   type
208     |   '?'
209     ;
210
211 formalParameterList
212     :   ^(FORMAL_PARAM_LIST formalParameterStandardDecl* formalParameterVarargDecl?) 
213     ;
214     
215 formalParameterStandardDecl
216     :   ^(FORMAL_PARAM_STD_DECL localModifierList? type variableDeclaratorId)
217     ;
218     
219 formalParameterVarargDecl
220     :   ^(FORMAL_PARAM_VARARG_DECL localModifierList? type variableDeclaratorId)
221     ;
222     
223 // FIXME: is this rule right? Verify that this is ok, I expected something like:
224 // IDENT (^('.' qualifiedIdentifier IDENT))*
225 qualifiedIdentifier
226     :   IDENT
227     |   ^('.' qualifiedIdentifier IDENT)
228     ;
229     
230 block
231     :   ^(BLOCK (blockStatement)*)
232     ;
233     
234 blockStatement
235     :   localVariableDeclaration
236     |   statement
237     ;
238     
239 localVariableDeclaration
240     :   ^(PRIMITIVE_VAR_DECLARATION localModifierList? simpleType variableDeclaratorList)
241     |   ^(OBJECT_VAR_DECLARATION localModifierList? objectType variableDeclaratorList)
242     ;
243
244 statement
245     :   nonBlockStatement
246     |   block
247     ;
248
249 nonBlockStatement
250     :   ^(ASSERT expression expression?)
251     |   ^(IF parenthesizedExpression block block?)
252     |   ^(FOR forInit? FOR_EXPR expression? FOR_UPDATE expression* block)
253     |   ^(FOR_EACH localModifierList? type IDENT expression block) 
254     |   ^(WHILE parenthesizedExpression block)
255     |   ^(DO block parenthesizedExpression)
256     |   ^(SWITCH parenthesizedExpression switchCaseLabel*)
257     |   ^(RETURN expression?)
258     |   ^(THROW expression)
259     |   ^(BREAK IDENT?) {
260             if ($IDENT != null) {
261                 translator.error(this, "Labeled break not supported yet, ignoring.", $IDENT);
262             }
263         }
264     |   ^(CONTINUE IDENT?) {
265             if ($IDENT != null) {
266                 translator.error(this, "Labeled continue not supported yet, ignoring.", $IDENT);
267             }
268         }
269     |   ^(LABELED_STATEMENT IDENT statement)
270     |   expression
271     |   ^('delete' qualifiedIdentifier)
272     |   ^(EMBED STRING_LITERAL EMBED_BLOCK)
273     |   ';' // Empty statement.
274     ;
275         
276 switchCaseLabel
277     :   ^(CASE expression blockStatement*)
278     |   ^(DEFAULT blockStatement*)
279     ;
280     
281 forInit
282     :   localVariableDeclaration 
283     |   expression+
284     ;
285     
286 // EXPRESSIONS
287
288 parenthesizedExpression
289     :   ^(PAREN_EXPR expression)
290     ;
291     
292 expression
293     :   ^(EXPR expr)
294     ;
295
296 expr
297     :   ^(ASSIGNMENT expr expr)
298     |   ^(PLUS_EQUALS expr expr)
299     |   ^(MINUS_EQUALS expr expr)
300     |   ^(TIMES_EQUALS expr expr)
301     |   ^(DIVIDE_EQUALS expr expr)
302     |   ^(AND_EQUALS expr expr)
303     |   ^(OR_EQUALS expr expr)
304     |   ^(POWER_EQUALS expr expr)
305     |   ^(MOD_EQUALS expr expr)
306     |   ^('>>>=' expr expr)
307     |   ^('>>=' expr expr)
308     |   ^('<<=' expr expr)
309     |   ^('?' expr expr expr)
310     |   ^(OR expr expr)
311     |   ^(AND expr expr)
312     |   ^(BITWISE_OR expr expr)
313     |   ^(POWER expr expr)
314     |   ^(BITWISE_AND expr expr)
315     |   ^(EQUALS expr expr)
316     |   ^(NOT_EQUALS expr expr)
317     |   ^(INSTANCEOF expr type)
318     |   ^(LTE expr expr)
319     |   ^(GTE expr expr)
320     |   ^('>>>' expr expr)
321     |   ^('>>' expr expr)
322     |   ^(GT expr expr)
323     |   ^('<<' expr expr)
324     |   ^(LT expr expr)
325     |   ^(PLUS expr expr)
326     |   ^(MINUS expr expr)
327     |   ^(TIMES expr expr)
328     |   ^(DIVIDE expr expr)
329     |   ^(MOD expr expr)
330     |   ^(UNARY_PLUS expr)
331     |   ^(UNARY_MINUS expr)
332     |   ^(PRE_INC expr)
333     |   ^(PRE_DEC expr)
334     |   ^(POST_INC expr)
335     |   ^(POST_DEC expr)
336     |   ^(TILDA expr)
337     |   ^(NOT expr)
338     |   ^(CAST_EXPR type expr)
339     |   primaryExpression
340     ;
341     
342 primaryExpression
343     :   ^(  '.' primaryExpression
344                 (   IDENT
345                 |   THIS
346                 |   SUPER
347                 )
348         )
349     |   parenthesizedExpression
350     |   IDENT
351     |   ^(METHOD_CALL primaryExpression genericTypeArgumentList? arguments)
352     |   explicitConstructorCall
353     |   ^(ARRAY_ELEMENT_ACCESS primaryExpression expression)
354     |   literal
355     |   newExpression
356     |   THIS
357     |   arrayTypeDeclarator
358     |   SUPER
359     ;
360     
361 explicitConstructorCall
362     :   ^(THIS_CONSTRUCTOR_CALL genericTypeArgumentList? arguments)
363     |   ^(SUPER_CONSTRUCTOR_CALL primaryExpression? genericTypeArgumentList? arguments)
364     ;
365
366 arrayTypeDeclarator
367     :   ^(ARRAY_DECLARATOR (arrayTypeDeclarator | qualifiedIdentifier | primitiveType))
368     ;
369
370 newExpression
371     :   ^(  STATIC_ARRAY_CREATOR
372             (   primitiveType newArrayConstruction
373             |   genericTypeArgumentList? qualifiedTypeIdent newArrayConstruction
374             )
375         )
376     |   ^(NEW qualifiedTypeIdent arguments)
377     ;
378
379 newArrayConstruction
380     :   arrayDeclaratorList arrayInitializer
381     |   expression+ arrayDeclaratorList?
382     ;
383
384 arguments
385     :   ^(ARGUMENT_LIST expression*)
386     ;
387
388 literal 
389     :   HEX_LITERAL
390     |   OCTAL_LITERAL
391     |   DECIMAL_LITERAL
392     |   FLOATING_POINT_LITERAL
393     |   CHARACTER_LITERAL
394     |   STRING_LITERAL          
395     |   TRUE
396     |   FALSE
397     |   NULL
398     ;
399