eb6ca0690f1ad5e7178fc5a44170945c1d78e5e0
[charm.git] / src / langs / charj / src / charj / translator / CharjSemantics.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 CharjSemantics;
8
9 options {
10     backtrack = true; 
11     memoize = true;
12     tokenVocab = Charj;
13     ASTLabelType = CharjAST;
14 }
15
16 scope ScopeStack {
17     Scope current;
18 }
19
20 @header {
21 package charj.translator;
22 }
23
24 @members {
25     SymbolTable symtab = null;
26     PackageScope currentPackage = null;
27     ClassSymbol currentClass = null;
28     MethodSymbol currentMethod = null;
29     LocalScope currentLocalScope = null;
30     Translator translator;
31
32     /**
33      *  Test a list of CharjAST nodes to see if any of them has the given token
34      *  type.
35      */
36     public boolean listContainsToken(List<CharjAST> list, int tokenType) {
37         for (CharjAST node : list) {
38             if (node.token.getType() == tokenType) {
39                 return true;
40             }
41         }
42         return false;
43     }
44
45     public void importPackages(ClassSymbol cs, List<CharjAST> imports) {
46         if (imports == null) {
47             return;
48         }
49
50         for (CharjAST pkg : imports) {
51             String pkgName = input.getTokenStream().toString(
52                     pkg.getTokenStartIndex(),
53                     pkg.getTokenStopIndex());
54             // find imported class and add to cs.imports
55             PackageScope p = cs.importPackage(pkgName);
56             if (p == null) {
57                 translator.error(
58                     this, 
59                     "package " + pkgName + " not found.",
60                     pkg);
61             }
62         }
63     }
64 }
65
66
67 // Replace default ANTLR generated catch clauses with this action, allowing early failure.
68 @rulecatch {
69     catch (RecognitionException re) {
70         reportError(re);
71         throw re;
72     }
73 }
74
75
76 // Starting point for parsing a Charj file.
77 charjSource[SymbolTable _symtab] returns [ClassSymbol cs]
78 scope ScopeStack; // default scope
79 @init {
80     symtab = _symtab;
81     $ScopeStack::current = symtab.getDefaultPkg();
82 }
83     // TODO: go back to allowing multiple type definitions per file, check that
84     // there is exactly one public type and return that one.
85     :   ^(CHARJ_SOURCE 
86         (packageDeclaration)? 
87         (importDeclarations) 
88         (typeDeclaration[$importDeclarations.packageNames]))
89         //(typeDeclaration)*)
90         { $cs = $typeDeclaration.sym; }
91     ;
92
93 // note: no new scope here--this replaces the default scope
94 packageDeclaration
95 @init { 
96     List<String> names = null; 
97 }
98     :   ^(PACKAGE qualifiedIdentifier)  {
99             String packageName = $qualifiedIdentifier.text;
100             PackageScope ps = symtab.resolvePackage(packageName);
101             if (ps == null) {
102                 ps = symtab.definePackage(packageName);
103                 symtab.addScope(ps);
104             }
105             currentPackage = ps;
106             $ScopeStack::current = ps;
107             $qualifiedIdentifier.start.symbol = ps;
108         }
109     ;
110     
111 importDeclarations returns [List<CharjAST> packageNames]
112 @init {
113         packageNames = new ArrayList<CharjAST>();
114 }
115     :   (^(IMPORT STATIC? qualifiedIdentifier DOTSTAR?)
116                 { packageNames.add($qualifiedIdentifier.start); })*
117     ;
118
119
120 typeDeclaration[List<CharjAST> imports] returns [ClassSymbol sym]
121 scope ScopeStack; // top-level type scope
122     :   ^(CLASS m=modifierList IDENT g=genericTypeParameterList? 
123                 e=classExtendsClause? i=implementsClause? c=classTopLevelScope) 
124         {
125             Scope outerScope = $ScopeStack[-1]::current;
126             $sym = new ClassSymbol(symtab, $IDENT.text, null, outerScope);
127             outerScope.define($sym.name, $sym);
128             currentClass = $sym;
129             $sym.definition = $typeDeclaration.start;
130             $sym.definitionTokenStream = input.getTokenStream();
131             $IDENT.symbol = $sym;
132             $ScopeStack::current = $sym;
133             importPackages($sym, $imports);
134         }
135     |   ^(INTERFACE modifierList IDENT genericTypeParameterList? 
136                 interfaceExtendsClause? interfaceTopLevelScope)
137     |   ^(ENUM modifierList IDENT implementsClause? enumTopLevelScope)
138     ;
139
140
141 classExtendsClause
142     :   ^(EXTENDS_CLAUSE t=type) 
143     ;   
144
145 interfaceExtendsClause 
146     :   ^(EXTENDS_CLAUSE (type)+) 
147     ;   
148     
149 implementsClause
150     :   ^(IMPLEMENTS_CLAUSE type+)
151     ;
152         
153 genericTypeParameterList
154     :   ^(GENERIC_TYPE_PARAM_LIST genericTypeParameter+)
155     ;
156
157 genericTypeParameter
158     :   ^(IDENT bound?)
159     ;
160         
161 bound
162     :   ^(EXTENDS_BOUND_LIST type+)
163     ;
164
165 enumTopLevelScope
166     :   ^(ENUM_TOP_LEVEL_SCOPE enumConstant+ classTopLevelScope?)
167     ;
168     
169 enumConstant
170     :   ^(IDENT arguments? classTopLevelScope?)
171     ;
172     
173     
174 classTopLevelScope
175     :   ^(CLASS_TOP_LEVEL_SCOPE (classScopeDeclarations)*) 
176     ;
177     
178 classScopeDeclarations
179     :   ^(CLASS_INSTANCE_INITIALIZER block)
180     |   ^(CLASS_STATIC_INITIALIZER block)
181     |   ^(FUNCTION_METHOD_DECL m=modifierList g=genericTypeParameterList? 
182             ty=type IDENT f=formalParameterList a=arrayDeclaratorList? 
183             tc=throwsClause? b=block?)
184     |   ^(VOID_METHOD_DECL m=modifierList g=genericTypeParameterList? IDENT 
185             f=formalParameterList t=throwsClause? b=block?)
186     |   ^(PRIMITIVE_VAR_DECLARATION modifierList simpleType variableDeclaratorList)
187     |   ^(OBJECT_VAR_DECLARATION modifierList objectType variableDeclaratorList)
188     |   ^(CONSTRUCTOR_DECL m=modifierList g=genericTypeParameterList? IDENT f=formalParameterList 
189             t=throwsClause? b=block)
190     |   d=typeDeclaration[null]
191     ;
192     
193 interfaceTopLevelScope
194     :   ^(INTERFACE_TOP_LEVEL_SCOPE interfaceScopeDeclarations*)
195     ;
196     
197 interfaceScopeDeclarations
198     :   ^(FUNCTION_METHOD_DECL modifierList genericTypeParameterList? 
199             type IDENT formalParameterList arrayDeclaratorList? throwsClause?)
200     |   ^(VOID_METHOD_DECL modifierList genericTypeParameterList? IDENT formalParameterList throwsClause?)
201         // Interface constant declarations have been switched to variable
202         // declarations by Charj.g; the parser has already checked that
203         // there's an obligatory initializer.
204     |   ^(PRIMITIVE_VAR_DECLARATION modifierList simpleType variableDeclaratorList)
205     |   ^(OBJECT_VAR_DECLARATION modifierList objectType variableDeclaratorList)
206     |   typeDeclaration[null]
207     ;
208
209 variableDeclaratorList
210     :   ^(VAR_DECLARATOR_LIST variableDeclarator+)
211     ;
212
213 variableDeclarator
214     :   ^(VAR_DECLARATOR variableDeclaratorId variableInitializer?)
215     ;
216     
217 variableDeclaratorId
218     :   ^(IDENT arrayDeclaratorList?)
219     ;
220
221 variableInitializer
222     :   arrayInitializer
223     |   expression
224     ;
225
226 arrayDeclarator
227     :   LBRACK RBRACK
228     ;
229
230 arrayDeclaratorList
231     :   ^(ARRAY_DECLARATOR_LIST ARRAY_DECLARATOR*)  
232     ;
233     
234 arrayInitializer
235     :   ^(ARRAY_INITIALIZER variableInitializer*)
236     ;
237
238 throwsClause
239     :   ^(THROWS_CLAUSE qualifiedIdentifier+)
240     ;
241
242 modifierList
243     :   ^(MODIFIER_LIST (modifier)*)
244     ;
245
246 modifier
247     :   PUBLIC
248     |   PROTECTED
249     |   PRIVATE
250     |   ENTRY
251     |   STATIC
252     |   ABSTRACT
253     |   NATIVE
254     |   SYNCHRONIZED
255     |   TRANSIENT
256     |   VOLATILE
257     |   localModifier
258     ;
259
260 localModifierList
261     :   ^(LOCAL_MODIFIER_LIST localModifier*)
262     ;
263
264 localModifier
265     :   FINAL
266     ;
267
268 type
269     :   simpleType
270     |   objectType 
271     ;
272
273 simpleType
274     :   ^(TYPE primitiveType arrayDeclaratorList?)
275     ;
276     
277 objectType
278     :   ^(TYPE qualifiedTypeIdent arrayDeclaratorList?)
279     ;
280
281 qualifiedTypeIdent
282     :   ^(QUALIFIED_TYPE_IDENT typeIdent+) 
283     ;
284
285 typeIdent
286     :   ^(IDENT genericTypeArgumentList?)
287     ;
288
289 primitiveType
290     :   BOOLEAN     { $start.symbol = new Symbol(symtab, "bool_primitive", symtab.resolveBuiltinType("bool")); }
291     |   CHAR        { $start.symbol = new Symbol(symtab, "char_primitive", symtab.resolveBuiltinType("char")); }
292     |   BYTE        { $start.symbol = new Symbol(symtab, "byte_primitive", symtab.resolveBuiltinType("char")); }
293     |   SHORT       { $start.symbol = new Symbol(symtab, "short_primitive", symtab.resolveBuiltinType("short")); }
294     |   INT         { $start.symbol = new Symbol(symtab, "int_primitive", symtab.resolveBuiltinType("int")); }
295     |   LONG        { $start.symbol = new Symbol(symtab, "long_primitive", symtab.resolveBuiltinType("long")); }
296     |   FLOAT       { $start.symbol = new Symbol(symtab, "float_primitive", symtab.resolveBuiltinType("float")); }
297     |   DOUBLE      { $start.symbol = new Symbol(symtab, "double_primitive", symtab.resolveBuiltinType("double")); }
298     ;
299
300 genericTypeArgumentList
301     :   ^(GENERIC_TYPE_ARG_LIST genericTypeArgument+)
302     ;
303     
304 genericTypeArgument
305     :   type
306     |   ^(QUESTION genericWildcardBoundType?)
307     ;
308
309 genericWildcardBoundType                                                                                                                      
310     :   ^(EXTENDS type)
311     |   ^(SUPER type)
312     ;
313
314 formalParameterList
315     :   ^(FORMAL_PARAM_LIST formalParameterStandardDecl* formalParameterVarargDecl?) 
316     ;
317     
318 formalParameterStandardDecl
319     :   ^(FORMAL_PARAM_STD_DECL localModifierList type variableDeclaratorId)
320     ;
321     
322 formalParameterVarargDecl
323     :   ^(FORMAL_PARAM_VARARG_DECL localModifierList type variableDeclaratorId)
324     ;
325     
326 qualifiedIdentifier
327     :   IDENT
328     |   ^(DOT qualifiedIdentifier IDENT)
329     ;
330     
331 block
332     :   ^(BLOCK_SCOPE (blockStatement)*)
333     ;
334     
335 blockStatement
336     :   localVariableDeclaration
337     |   typeDeclaration[null]
338     |   statement
339     ;
340     
341 localVariableDeclaration
342     :   ^(PRIMITIVE_VAR_DECLARATION localModifierList simpleType variableDeclaratorList)
343     |   ^(OBJECT_VAR_DECLARATION localModifierList objectType variableDeclaratorList)
344     ;
345
346
347 statement
348     :   block
349     |   ^(ASSERT expression expression?)
350     |   ^(IF parenthesizedExpression statement statement?)
351     |   ^(FOR forInit forCondition forUpdater statement)
352     |   ^(FOR_EACH localModifierList type IDENT expression statement) 
353     |   ^(WHILE parenthesizedExpression statement)
354     |   ^(DO statement parenthesizedExpression)
355     |   ^(TRY block catches? block?)  // The second optional block is the optional finally block.
356     |   ^(SWITCH parenthesizedExpression switchBlockLabels)
357     |   ^(SYNCHRONIZED parenthesizedExpression block)
358     |   ^(RETURN expression?)
359     |   ^(THROW expression)
360     |   ^(BREAK IDENT?)
361     |   ^(CONTINUE IDENT?)
362     |   ^(LABELED_STATEMENT IDENT statement)
363     |   expression
364     |   ^(EMBED STRING_LITERAL EMBED_BLOCK)
365     |   SEMI // Empty statement.
366     ;
367         
368 catches
369     :   ^(CATCH_CLAUSE_LIST catchClause+)
370     ;
371     
372 catchClause
373     :   ^(CATCH formalParameterStandardDecl block)
374     ;
375
376 switchBlockLabels
377     :   ^(SWITCH_BLOCK_LABEL_LIST switchCaseLabel* switchDefaultLabel? switchCaseLabel*)
378     ;
379         
380 switchCaseLabel
381     :   ^(CASE expression blockStatement*)
382     ;
383     
384 switchDefaultLabel
385     :   ^(DEFAULT blockStatement*)
386     ;
387     
388 forInit
389     :   ^(FOR_INIT (localVariableDeclaration | expression*)?)
390     ;
391     
392 forCondition
393     :   ^(FOR_CONDITION expression?)
394     ;
395     
396 forUpdater
397     :   ^(FOR_UPDATE expression*)
398     ;
399     
400 // EXPRESSIONS
401
402 parenthesizedExpression
403     :   ^(PARENTESIZED_EXPR expression)
404     ;
405     
406 expression
407     :   ^(EXPR expr)
408     ;
409
410 expr
411     :   ^(ASSIGN expr expr)
412     |   ^(PLUS_ASSIGN expr expr)
413     |   ^(MINUS_ASSIGN expr expr)
414     |   ^(STAR_ASSIGN expr expr)
415     |   ^(DIV_ASSIGN expr expr)
416     |   ^(AND_ASSIGN expr expr)
417     |   ^(OR_ASSIGN expr expr)
418     |   ^(XOR_ASSIGN expr expr)
419     |   ^(MOD_ASSIGN expr expr)
420     |   ^(BIT_SHIFT_RIGHT_ASSIGN expr expr)
421     |   ^(SHIFT_RIGHT_ASSIGN expr expr)
422     |   ^(SHIFT_LEFT_ASSIGN expr expr)
423     |   ^(QUESTION expr expr expr)
424     |   ^(LOGICAL_OR expr expr)
425     |   ^(LOGICAL_AND expr expr)
426     |   ^(OR expr expr)
427     |   ^(XOR expr expr)
428     |   ^(AND expr expr)
429     |   ^(EQUAL expr expr)
430     |   ^(NOT_EQUAL expr expr)
431     |   ^(INSTANCEOF expr type)
432     |   ^(LESS_OR_EQUAL expr expr)
433     |   ^(GREATER_OR_EQUAL expr expr)
434     |   ^(BIT_SHIFT_RIGHT expr expr)
435     |   ^(SHIFT_RIGHT expr expr)
436     |   ^(GREATER_THAN expr expr)
437     |   ^(SHIFT_LEFT expr expr)
438     |   ^(LESS_THAN expr expr)
439     |   ^(PLUS expr expr)
440     |   ^(MINUS expr expr)
441     |   ^(STAR expr expr)
442     |   ^(DIV expr expr)
443     |   ^(MOD expr expr)
444     |   ^(UNARY_PLUS expr)
445     |   ^(UNARY_MINUS expr)
446     |   ^(PRE_INC expr)
447     |   ^(PRE_DEC expr)
448     |   ^(POST_INC expr)
449     |   ^(POST_DEC expr)
450     |   ^(NOT expr)
451     |   ^(LOGICAL_NOT expr)
452     |   ^(CAST_EXPR type expr)
453     |   primaryExpression
454     ;
455     
456 primaryExpression
457     :   ^(  DOT
458             (   primaryExpression
459                 (   IDENT
460                 |   THIS
461                 |   SUPER
462                 |   innerNewExpression
463                 |   CLASS
464                 )
465             |   primitiveType CLASS
466             |   VOID CLASS
467             )
468         )
469     |   parenthesizedExpression
470     |   IDENT
471     |   ^(METHOD_CALL primaryExpression genericTypeArgumentList? arguments)
472     |   explicitConstructorCall
473     |   ^(ARRAY_ELEMENT_ACCESS primaryExpression expression)
474     |   literal
475     |   newExpression
476     |   THIS
477     |   arrayTypeDeclarator
478     |   SUPER
479     ;
480     
481 explicitConstructorCall
482     :   ^(THIS_CONSTRUCTOR_CALL genericTypeArgumentList? arguments)
483     |   ^(SUPER_CONSTRUCTOR_CALL primaryExpression? genericTypeArgumentList? arguments)
484     ;
485
486 arrayTypeDeclarator
487     :   ^(ARRAY_DECLARATOR (arrayTypeDeclarator | qualifiedIdentifier | primitiveType))
488     ;
489
490 newExpression
491     :   ^(  STATIC_ARRAY_CREATOR
492             (   primitiveType newArrayConstruction
493             |   genericTypeArgumentList? qualifiedTypeIdent newArrayConstruction
494             )
495         )
496     |   ^(CLASS_CONSTRUCTOR_CALL genericTypeArgumentList? qualifiedTypeIdent arguments classTopLevelScope?)
497     ;
498
499 innerNewExpression // something like 'InnerType innerType = outer.new InnerType();'
500     :   ^(CLASS_CONSTRUCTOR_CALL genericTypeArgumentList? IDENT arguments classTopLevelScope?)
501     ;
502     
503 newArrayConstruction
504     :   arrayDeclaratorList arrayInitializer
505     |   expression+ arrayDeclaratorList?
506     ;
507
508 arguments
509     :   ^(ARGUMENT_LIST expression*)
510     ;
511
512 literal 
513     :   HEX_LITERAL
514     |   OCTAL_LITERAL
515     |   DECIMAL_LITERAL
516     |   FLOATING_POINT_LITERAL
517     |   CHARACTER_LITERAL
518     |   STRING_LITERAL          
519     |   TRUE
520     |   FALSE
521     |   NULL
522     ;
523