15120b65ebd6e659654edfef0e0ab7a747281f0a
[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 }
15
16 @header {
17 package charj.translator;
18 }
19
20 @members {
21     SymbolTable symtab = null;
22     PackageScope currentPackage = null;
23     ClassSymbol currentClass = null;
24     MethodSymbol currentMethod = null;
25     LocalScope currentLocalScope = null;
26     Translator translator;
27 }
28
29 // Replace default ANTLR generated catch clauses with this action, allowing early failure.
30 @rulecatch {
31     catch (RecognitionException re) {
32         reportError(re);
33         throw re;
34     }
35 }
36
37
38 // Starting point for parsing a Charj file.
39 charjSource[SymbolTable _symtab] returns [ClassSymbol cs]
40 @init {
41     symtab = _symtab;
42 }
43     // TODO: go back to allowing multiple type definitions per file, check that
44     // there is exactly one public type and return that one.
45     :   ^(CHARJ_SOURCE 
46         (packageDeclaration)? 
47         (importDeclarations) 
48         (typeDeclaration[$importDeclarations.packageNames]))
49         { $cs = $typeDeclaration.sym; }
50     ;
51
52 packageDeclaration
53     :   ^('package' (ids+=IDENT)+)  
54     ;
55     
56 importDeclarations returns [List<CharjAST> packageNames]
57     :   (^('import' qualifiedIdentifier '.*'?))*
58     ;
59
60 typeDeclaration[List<CharjAST> imports] returns [ClassSymbol sym]
61     :   ^(TYPE ('class' | chareType) IDENT (^('extends' parent=type))? (^('implements' type+))? classScopeDeclaration*)
62     |   ^('interface' IDENT (^('extends' type+))?  interfaceScopeDeclaration*)
63     |   ^('enum' IDENT (^('implements' type+))? enumConstant+ classScopeDeclaration*)
64     ;
65
66 chareType
67     :   'chare'
68     |   'group'
69     |   'nodegroup'
70     |   ^('chare_array' ARRAY_DIMENSION)
71     ;
72
73 enumConstant
74     :   ^(IDENT arguments?)
75     ;
76     
77 classScopeDeclaration
78     :   ^(FUNCTION_METHOD_DECL m=modifierList? g=genericTypeParameterList? 
79             ty=type IDENT f=formalParameterList a=arrayDeclaratorList? 
80             b=block?)
81
82     |   ^(PRIMITIVE_VAR_DECLARATION modifierList? simpleType variableDeclaratorList)
83     |   ^(OBJECT_VAR_DECLARATION modifierList? objectType variableDeclaratorList)
84     |   ^(CONSTRUCTOR_DECL m=modifierList? g=genericTypeParameterList? IDENT f=formalParameterList 
85             b=block)
86     ;
87     
88 interfaceScopeDeclaration
89     :   ^(FUNCTION_METHOD_DECL modifierList? genericTypeParameterList? 
90             type IDENT formalParameterList arrayDeclaratorList?)
91         // Interface constant declarations have been switched to variable
92         // declarations by Charj.g; the parser has already checked that
93         // there's an obligatory initializer.
94     |   ^(PRIMITIVE_VAR_DECLARATION modifierList? simpleType variableDeclaratorList)
95     |   ^(OBJECT_VAR_DECLARATION modifierList? objectType variableDeclaratorList)
96     ;
97
98 variableDeclaratorList
99     :   ^(VAR_DECLARATOR_LIST variableDeclarator+)
100     ;
101
102 variableDeclarator
103     :   ^(VAR_DECLARATOR variableDeclaratorId variableInitializer?)
104     ;
105     
106 variableDeclaratorId
107     :   ^(IDENT arrayDeclaratorList?)
108     ;
109
110 variableInitializer
111     :   arrayInitializer
112     |   expression
113     ;
114
115 arrayDeclaratorList
116     :   ^(ARRAY_DECLARATOR_LIST ARRAY_DECLARATOR*)  
117     ;
118     
119 arrayInitializer
120     :   ^(ARRAY_INITIALIZER variableInitializer*)
121     ;
122
123 genericTypeParameterList
124     :   ^(GENERIC_TYPE_PARAM_LIST genericTypeParameter+)
125     ;
126
127 genericTypeParameter
128     :   ^(IDENT bound?)
129     ;
130         
131 bound
132     :   ^(EXTENDS_BOUND_LIST type+)
133     ;
134
135 modifierList
136     :   ^(MODIFIER_LIST modifier+)
137     ;
138
139 modifier
140     :   'public'
141     |   'protected'
142     |   'private'
143     |   'entry'
144     |   'abstract'
145     |   'native'
146     |   localModifier
147     ;
148
149 localModifierList
150     :   ^(LOCAL_MODIFIER_LIST localModifier+)
151     ;
152
153 localModifier
154     :   'final'
155     |   'static'
156     |   'volatile'
157     ;
158
159 type
160     :   simpleType
161     |   objectType 
162     |   'void'
163     ;
164
165 simpleType
166     :   ^(TYPE primitiveType arrayDeclaratorList?)
167     ;
168     
169 objectType
170     :   ^(TYPE qualifiedTypeIdent arrayDeclaratorList?)
171     ;
172
173 qualifiedTypeIdent
174     :   ^(QUALIFIED_TYPE_IDENT typeIdent+) 
175     ;
176
177 typeIdent
178     :   ^(IDENT genericTypeArgumentList?)
179     ;
180
181 primitiveType
182     :   'boolean'     { $start.symbol = new Symbol(symtab, "bool_primitive", symtab.resolveBuiltinType("bool")); }
183     |   'char'        { $start.symbol = new Symbol(symtab, "char_primitive", symtab.resolveBuiltinType("char")); }
184     |   'byte'        { $start.symbol = new Symbol(symtab, "byte_primitive", symtab.resolveBuiltinType("char")); }
185     |   'short'       { $start.symbol = new Symbol(symtab, "short_primitive", symtab.resolveBuiltinType("short")); }
186     |   'int'         { $start.symbol = new Symbol(symtab, "int_primitive", symtab.resolveBuiltinType("int")); }
187     |   'long'        { $start.symbol = new Symbol(symtab, "long_primitive", symtab.resolveBuiltinType("long")); }
188     |   'float'       { $start.symbol = new Symbol(symtab, "float_primitive", symtab.resolveBuiltinType("float")); }
189     |   'double'      { $start.symbol = new Symbol(symtab, "double_primitive", symtab.resolveBuiltinType("double")); }
190     ;
191
192 genericTypeArgumentList
193     :   ^(GENERIC_TYPE_ARG_LIST genericTypeArgument+)
194     ;
195     
196 genericTypeArgument
197     :   type
198     |   '?'
199     ;
200
201 formalParameterList
202     :   ^(FORMAL_PARAM_LIST formalParameterStandardDecl* formalParameterVarargDecl?) 
203     ;
204     
205 formalParameterStandardDecl
206     :   ^(FORMAL_PARAM_STD_DECL localModifierList? type variableDeclaratorId)
207     ;
208     
209 formalParameterVarargDecl
210     :   ^(FORMAL_PARAM_VARARG_DECL localModifierList? type variableDeclaratorId)
211     ;
212     
213 // FIXME: is this rule right? Verify that this is ok, I expected something like:
214 // IDENT (^('.' qualifiedIdentifier IDENT))*
215 qualifiedIdentifier
216     :   IDENT
217     |   ^('.' qualifiedIdentifier IDENT)
218     ;
219     
220 block
221     :   ^(BLOCK (blockStatement)*)
222     ;
223     
224 blockStatement
225     :   localVariableDeclaration
226     |   statement
227     ;
228     
229 localVariableDeclaration
230     :   ^(PRIMITIVE_VAR_DECLARATION localModifierList? simpleType variableDeclaratorList)
231     |   ^(OBJECT_VAR_DECLARATION localModifierList? objectType variableDeclaratorList)
232     ;
233
234 statement
235     :   block
236     |   ^('assert' expression expression?)
237     |   ^('if' parenthesizedExpression statement statement?)
238     |   ^('for' forInit? FOR_EXPR expression? FOR_UPDATE expression* statement)
239     |   ^(FOR_EACH localModifierList? type IDENT expression statement) 
240     |   ^('while' parenthesizedExpression statement)
241     |   ^('do' statement parenthesizedExpression)
242     |   ^('switch' parenthesizedExpression switchCaseLabel*)
243     |   ^('return' expression?)
244     |   ^('throw' expression)
245     |   ^('break' IDENT?) {
246             if ($IDENT != null) {
247                 translator.error(this, "Labeled break not supported yet, ignoring.", $IDENT);
248             }
249         }
250     |   ^('continue' IDENT?) {
251             if ($IDENT != null) {
252                 translator.error(this, "Labeled continue not supported yet, ignoring.", $IDENT);
253             }
254         }
255     |   ^(LABELED_STATEMENT IDENT statement)
256     |   expression
257     |   ^('embed' STRING_LITERAL EMBED_BLOCK)
258     |   ';' // Empty statement.
259     ;
260         
261 switchCaseLabel
262     :   ^('case' expression blockStatement*)
263     |   ^('default' blockStatement*)
264     ;
265     
266 forInit
267     :   localVariableDeclaration 
268     |   expression+
269     ;
270     
271 // EXPRESSIONS
272
273 parenthesizedExpression
274     :   ^(PAREN_EXPR expression)
275     ;
276     
277 expression
278     :   ^(EXPR expr)
279     ;
280
281 expr
282     :   ^('=' expr expr)
283     |   ^('+=' expr expr)
284     |   ^('-=' expr expr)
285     |   ^('*=' expr expr)
286     |   ^('/=' expr expr)
287     |   ^('&=' expr expr)
288     |   ^('|=' expr expr)
289     |   ^('^=' expr expr)
290     |   ^('%=' expr expr)
291     |   ^('>>>=' expr expr)
292     |   ^('>>=' expr expr)
293     |   ^('<<=' expr expr)
294     |   ^('?' expr expr expr)
295     |   ^('||' expr expr)
296     |   ^('&&' expr expr)
297     |   ^('|' expr expr)
298     |   ^('^' expr expr)
299     |   ^('&' expr expr)
300     |   ^('==' expr expr)
301     |   ^('!=' expr expr)
302     |   ^('instanceof' expr type)
303     |   ^('<=' expr expr)
304     |   ^('>=' expr expr)
305     |   ^('>>>' expr expr)
306     |   ^('>>' expr expr)
307     |   ^('>' expr expr)
308     |   ^('<<' expr expr)
309     |   ^('<' expr expr)
310     |   ^('+' expr expr)
311     |   ^('-' expr expr)
312     |   ^('*' expr expr)
313     |   ^('/' expr expr)
314     |   ^('%' expr expr)
315     |   ^(UNARY_PLUS expr)
316     |   ^(UNARY_MINUS expr)
317     |   ^(PRE_INC expr)
318     |   ^(PRE_DEC expr)
319     |   ^(POST_INC expr)
320     |   ^(POST_DEC expr)
321     |   ^('~' expr)
322     |   ^('!' expr)
323     |   ^(CAST_EXPR type expr)
324     |   primaryExpression
325     ;
326     
327 primaryExpression
328     :   ^(  '.' primaryExpression
329                 (   IDENT
330                 |   'this'
331                 |   'super'
332                 )
333         )
334     |   parenthesizedExpression
335     |   IDENT
336     |   ^(METHOD_CALL primaryExpression genericTypeArgumentList? arguments)
337     |   explicitConstructorCall
338     |   ^(ARRAY_ELEMENT_ACCESS primaryExpression expression)
339     |   literal
340     |   newExpression
341     |   'this'
342     |   arrayTypeDeclarator
343     |   'super'
344     ;
345     
346 explicitConstructorCall
347     :   ^(THIS_CONSTRUCTOR_CALL genericTypeArgumentList? arguments)
348     |   ^(SUPER_CONSTRUCTOR_CALL primaryExpression? genericTypeArgumentList? arguments)
349     ;
350
351 arrayTypeDeclarator
352     :   ^(ARRAY_DECLARATOR (arrayTypeDeclarator | qualifiedIdentifier | primitiveType))
353     ;
354
355 newExpression
356     :   ^(  STATIC_ARRAY_CREATOR
357             (   primitiveType newArrayConstruction
358             |   genericTypeArgumentList? qualifiedTypeIdent newArrayConstruction
359             )
360         )
361     ;
362
363 newArrayConstruction
364     :   arrayDeclaratorList arrayInitializer
365     |   expression+ arrayDeclaratorList?
366     ;
367
368 arguments
369     :   ^(ARGUMENT_LIST expression*)
370     ;
371
372 literal 
373     :   HEX_LITERAL
374     |   OCTAL_LITERAL
375     |   DECIMAL_LITERAL
376     |   FLOATING_POINT_LITERAL
377     |   CHARACTER_LITERAL
378     |   STRING_LITERAL          
379     |   'true'
380     |   'false'
381     |   'null'
382     ;
383