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