1c582a8d6ba0a1af4c2b2642afe5e94738227995
[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     :   ^(TYPE primitiveType arrayDeclaratorList?)
175     ;
176     
177 objectType
178     :   ^(TYPE qualifiedTypeIdent arrayDeclaratorList?)
179     ;
180
181 qualifiedTypeIdent
182     :   ^(QUALIFIED_TYPE_IDENT typeIdent+) 
183     ;
184
185 typeIdent
186     :   ^(IDENT genericTypeArgumentList?)
187     ;
188
189 primitiveType
190     :   BOOLEAN     { $start.symbol = new Symbol(symtab, "bool_primitive", symtab.resolveBuiltinType("bool")); }
191     |   CHAR        { $start.symbol = new Symbol(symtab, "char_primitive", symtab.resolveBuiltinType("char")); }
192     |   BYTE        { $start.symbol = new Symbol(symtab, "byte_primitive", symtab.resolveBuiltinType("char")); }
193     |   SHORT       { $start.symbol = new Symbol(symtab, "short_primitive", symtab.resolveBuiltinType("short")); }
194     |   INT         { $start.symbol = new Symbol(symtab, "int_primitive", symtab.resolveBuiltinType("int")); }
195     |   LONG        { $start.symbol = new Symbol(symtab, "long_primitive", symtab.resolveBuiltinType("long")); }
196     |   FLOAT       { $start.symbol = new Symbol(symtab, "float_primitive", symtab.resolveBuiltinType("float")); }
197     |   DOUBLE      { $start.symbol = new Symbol(symtab, "double_primitive", symtab.resolveBuiltinType("double")); }
198     ;
199
200 genericTypeArgumentList
201     :   ^(GENERIC_TYPE_ARG_LIST genericTypeArgument+)
202     ;
203     
204 genericTypeArgument
205     :   type
206     |   '?'
207     ;
208
209 formalParameterList
210     :   ^(FORMAL_PARAM_LIST formalParameterStandardDecl* formalParameterVarargDecl?) 
211     ;
212     
213 formalParameterStandardDecl
214     :   ^(FORMAL_PARAM_STD_DECL localModifierList? type variableDeclaratorId)
215     ;
216     
217 formalParameterVarargDecl
218     :   ^(FORMAL_PARAM_VARARG_DECL localModifierList? type variableDeclaratorId)
219     ;
220     
221 // FIXME: is this rule right? Verify that this is ok, I expected something like:
222 // IDENT (^('.' qualifiedIdentifier IDENT))*
223 qualifiedIdentifier
224     :   IDENT
225     |   ^('.' qualifiedIdentifier IDENT)
226     ;
227     
228 block
229     :   ^(BLOCK (blockStatement)*)
230     ;
231     
232 blockStatement
233     :   localVariableDeclaration
234     |   statement
235     ;
236     
237 localVariableDeclaration
238     :   ^(PRIMITIVE_VAR_DECLARATION localModifierList? simpleType variableDeclaratorList)
239     |   ^(OBJECT_VAR_DECLARATION localModifierList? objectType variableDeclaratorList)
240     ;
241
242 statement
243     :   nonBlockStatement
244     |   block
245     ;
246
247 nonBlockStatement
248     :   ^(ASSERT expression expression?)
249     |   ^(IF parenthesizedExpression block block?)
250     |   ^(FOR forInit? FOR_EXPR expression? FOR_UPDATE expression* block)
251     |   ^(FOR_EACH localModifierList? type IDENT expression block) 
252     |   ^(WHILE parenthesizedExpression block)
253     |   ^(DO block parenthesizedExpression)
254     |   ^(SWITCH parenthesizedExpression switchCaseLabel*)
255     |   ^(RETURN expression?)
256     |   ^(THROW expression)
257     |   ^(BREAK IDENT?) {
258             if ($IDENT != null) {
259                 translator.error(this, "Labeled break not supported yet, ignoring.", $IDENT);
260             }
261         }
262     |   ^(CONTINUE IDENT?) {
263             if ($IDENT != null) {
264                 translator.error(this, "Labeled continue not supported yet, ignoring.", $IDENT);
265             }
266         }
267     |   ^(LABELED_STATEMENT IDENT statement)
268     |   expression
269     |   ^('delete' qualifiedIdentifier)
270     |   ^(EMBED STRING_LITERAL EMBED_BLOCK)
271     |   ';' // Empty statement.
272     ;
273         
274 switchCaseLabel
275     :   ^(CASE expression blockStatement*)
276     |   ^(DEFAULT blockStatement*)
277     ;
278     
279 forInit
280     :   localVariableDeclaration 
281     |   expression+
282     ;
283     
284 // EXPRESSIONS
285
286 parenthesizedExpression
287     :   ^(PAREN_EXPR expression)
288     ;
289     
290 expression
291     :   ^(EXPR expr)
292     ;
293
294 expr
295     :   ^(ASSIGNMENT expr expr)
296     |   ^(PLUS_EQUALS expr expr)
297     |   ^(MINUS_EQUALS expr expr)
298     |   ^(TIMES_EQUALS expr expr)
299     |   ^(DIVIDE_EQUALS expr expr)
300     |   ^(AND_EQUALS expr expr)
301     |   ^(OR_EQUALS expr expr)
302     |   ^(POWER_EQUALS expr expr)
303     |   ^(MOD_EQUALS expr expr)
304     |   ^('>>>=' expr expr)
305     |   ^('>>=' expr expr)
306     |   ^('<<=' expr expr)
307     |   ^('?' expr expr expr)
308     |   ^(OR expr expr)
309     |   ^(AND expr expr)
310     |   ^(BITWISE_OR expr expr)
311     |   ^(POWER expr expr)
312     |   ^(BITWISE_AND expr expr)
313     |   ^(EQUALS expr expr)
314     |   ^(NOT_EQUALS expr expr)
315     |   ^(INSTANCEOF expr type)
316     |   ^(LTE expr expr)
317     |   ^(GTE expr expr)
318     |   ^('>>>' expr expr)
319     |   ^('>>' expr expr)
320     |   ^(GT expr expr)
321     |   ^('<<' expr expr)
322     |   ^(LT expr expr)
323     |   ^(PLUS expr expr)
324     |   ^(MINUS expr expr)
325     |   ^(TIMES expr expr)
326     |   ^(DIVIDE expr expr)
327     |   ^(MOD expr expr)
328     |   ^(UNARY_PLUS expr)
329     |   ^(UNARY_MINUS expr)
330     |   ^(PRE_INC expr)
331     |   ^(PRE_DEC expr)
332     |   ^(POST_INC expr)
333     |   ^(POST_DEC expr)
334     |   ^(TILDA expr)
335     |   ^(NOT expr)
336     |   ^(CAST_EXPR type expr)
337     |   primaryExpression
338     ;
339     
340 primaryExpression
341     :   ^(  '.' primaryExpression
342                 (   IDENT
343                 |   THIS
344                 |   SUPER
345                 )
346         )
347     |   parenthesizedExpression
348     |   IDENT
349     |   ^(METHOD_CALL primaryExpression genericTypeArgumentList? arguments)
350     |   explicitConstructorCall
351     |   ^(ARRAY_ELEMENT_ACCESS primaryExpression expression)
352     |   literal
353     |   newExpression
354     |   THIS
355     |   arrayTypeDeclarator
356     |   SUPER
357     ;
358     
359 explicitConstructorCall
360     :   ^(THIS_CONSTRUCTOR_CALL genericTypeArgumentList? arguments)
361     |   ^(SUPER_CONSTRUCTOR_CALL primaryExpression? genericTypeArgumentList? arguments)
362     ;
363
364 arrayTypeDeclarator
365     :   ^(ARRAY_DECLARATOR (arrayTypeDeclarator | qualifiedIdentifier | primitiveType))
366     ;
367
368 newExpression
369     :   ^(  STATIC_ARRAY_CREATOR
370             (   primitiveType newArrayConstruction
371             |   genericTypeArgumentList? qualifiedTypeIdent newArrayConstruction
372             )
373         )
374     |   ^('new' qualifiedTypeIdent arguments)
375     ;
376
377 newArrayConstruction
378     :   arrayDeclaratorList arrayInitializer
379     |   expression+ arrayDeclaratorList?
380     ;
381
382 arguments
383     :   ^(ARGUMENT_LIST expression*)
384     ;
385
386 literal 
387     :   HEX_LITERAL
388     |   OCTAL_LITERAL
389     |   DECIMAL_LITERAL
390     |   FLOATING_POINT_LITERAL
391     |   CHARACTER_LITERAL
392     |   STRING_LITERAL          
393     |   TRUE
394     |   FALSE
395     |   NULL
396     ;
397