76 lines
1.2 KiB
Plaintext
76 lines
1.2 KiB
Plaintext
grammar SymbolTable;
|
|
|
|
/* Scope of symbol names. Both globals and block rules need to push a new
|
|
* symbol table upon entry and they must use the same stack. So, I must
|
|
* define a global scope and say that globals and block use this by saying
|
|
* 'scope Symbols;' in those rule definitions.
|
|
*/
|
|
|
|
options {
|
|
language=ObjC;
|
|
}
|
|
|
|
scope Symbols {
|
|
PtrBuffer *names;
|
|
}
|
|
|
|
@memVars {
|
|
int level;
|
|
}
|
|
|
|
@init {
|
|
level = 0;
|
|
}
|
|
|
|
prog
|
|
// scope Symbols;
|
|
: globals (method)*
|
|
;
|
|
|
|
globals
|
|
scope Symbols;
|
|
@init {
|
|
level++;
|
|
$Symbols::names = [PtrBuffer newPtrBufferWithLen:10];
|
|
}
|
|
: (decl)*
|
|
{
|
|
NSLog( @"globals: \%@", [$Symbols::names toString] );
|
|
level--;
|
|
}
|
|
;
|
|
|
|
method
|
|
: 'method' ID '(' ')' block
|
|
;
|
|
|
|
block
|
|
scope Symbols;
|
|
@init {
|
|
level++;
|
|
$Symbols::names = [PtrBuffer newPtrBufferWithLen:10];
|
|
}
|
|
: '{' (decl)* (stat)* '}'
|
|
{
|
|
NSLog( @"level \%d symbols: \%@", level, [$Symbols::names toString] );
|
|
level--;
|
|
}
|
|
;
|
|
|
|
stat: ID '=' INT ';'
|
|
| block
|
|
;
|
|
|
|
decl: 'int' ID ';'
|
|
{[$Symbols::names addObject:$ID];} // add to current symbol table
|
|
;
|
|
|
|
ID : ('a'..'z')+
|
|
;
|
|
|
|
INT : ('0'..'9')+
|
|
;
|
|
|
|
WS : (' '|'\n'|'\r')+ {$channel=HIDDEN;}
|
|
;
|