-
Notifications
You must be signed in to change notification settings - Fork 48
/
Copy pathSymtabTest.g
executable file
·68 lines (56 loc) · 1.11 KB
/
SymtabTest.g
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
grammar SymtabTest;
options{language=JavaScript;}
/* 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.
*/
scope Symbols {
var names;
}
@header {
}
@members {
this.level = 0;
}
prog: globals (method)*
;
globals
scope Symbols;
@init {
this.level++;
$Symbols::names = [];
}
: (decl)*
{
print("globals: "+$Symbols::names);
this.level--;
}
;
method
: 'method' ID '(' ')' block
;
block
scope Symbols;
@init {
this.level++;
$Symbols::names = [];
}
: '{' (decl)* (stat)* '}'
{
print("level "+this.level+" symbols: "+$Symbols::names);
this.level--;
}
;
stat: ID '=' INT ';'
| block
;
decl: 'int' ID ';'
{$Symbols::names.push($ID);} // add to current symbol table
;
ID : ('a'..'z')+
;
INT : ('0'..'9')+
;
WS : (' '|'\n'|'\r')+ {$channel=HIDDEN;}
;