1grammar SymbolTable;
2
3/* Scope of symbol names.  Both globals and block rules need to push a new
4 * symbol table upon entry and they must use the same stack.  So, I must
5 * define a global scope and say that globals and block use this by saying
6 * 'scope Symbols;' in those rule definitions.
7 */
8
9options {
10	language=ObjC;
11}
12
13scope Symbols {
14  PtrBuffer *names;
15}
16
17@memVars {
18int level;
19}
20
21@init {
22level = 0;
23}
24
25prog
26// scope Symbols;
27    :   globals (method)*
28    ;
29
30globals
31scope Symbols;
32@init {
33    level++;
34    $Symbols::names = [PtrBuffer newPtrBufferWithLen:10];
35}
36    :   (decl)*
37        {
38            NSLog( @"globals: \%@", [$Symbols::names toString] );
39            level--;
40        }
41    ;
42
43method
44    :   'method' ID '(' ')' block
45    ;
46
47block
48scope Symbols;
49@init {
50    level++;
51    $Symbols::names = [PtrBuffer newPtrBufferWithLen:10];
52}
53    :   '{' (decl)* (stat)* '}'
54        {
55            NSLog( @"level \%d symbols: \%@", level, [$Symbols::names toString] );
56            level--;
57        }
58    ;
59
60stat:   ID '=' INT ';'
61    |   block
62    ;
63
64decl:   'int' ID ';'
65        {[$Symbols::names addObject:$ID];} // add to current symbol table
66    ;
67
68ID  :   ('a'..'z')+
69    ;
70
71INT :   ('0'..'9')+
72    ;
73
74WS  :   (' '|'\n'|'\r')+ {$channel=HIDDEN;}
75    ;
76