1grammar t022scopes; 2 3options { 4 language=Python3; 5} 6 7/* global scopes */ 8 9scope aScope { 10names 11} 12 13a 14scope aScope; 15 : {$aScope::names = [];} ID* 16 ; 17 18 19/* rule scopes, from the book, final beta, p.147 */ 20 21b[v] 22scope {x} 23 : {$b::x = v;} b2 24 ; 25 26b2 27 : b3 28 ; 29 30b3 31 : {$b::x}?=> ID // only visible, if b was called with True 32 | NUM 33 ; 34 35 36/* rule scopes, from the book, final beta, p.148 */ 37 38c returns [res] 39scope { 40 symbols 41} 42@init { 43 $c::symbols = set(); 44} 45 : '{' c1* c2+ '}' 46 { $res = $c::symbols; } 47 ; 48 49c1 50 : 'int' ID {$c::symbols.add($ID.text)} ';' 51 ; 52 53c2 54 : ID '=' NUM ';' 55 { 56 if $ID.text not in $c::symbols: 57 raise RuntimeError($ID.text) 58 } 59 ; 60 61/* recursive rule scopes, from the book, final beta, p.150 */ 62 63d returns [res] 64scope { 65 symbols 66} 67@init { 68 $d::symbols = set(); 69} 70 : '{' d1* d2* '}' 71 { $res = $d::symbols; } 72 ; 73 74d1 75 : 'int' ID {$d::symbols.add($ID.text)} ';' 76 ; 77 78d2 79 : ID '=' NUM ';' 80 { 81 for s in reversed(range(len($d))): 82 if $ID.text in $d[s]::symbols: 83 break 84 else: 85 raise RuntimeError($ID.text) 86 } 87 | d 88 ; 89 90/* recursive rule scopes, access bottom-most scope */ 91 92e returns [res] 93scope { 94 a 95} 96@after { 97 $res = $e::a; 98} 99 : NUM { $e[0]::a = int($NUM.text); } 100 | '{' e '}' 101 ; 102 103 104/* recursive rule scopes, access with negative index */ 105 106f returns [res] 107scope { 108 a 109} 110@after { 111 $res = $f::a; 112} 113 : NUM { $f[-2]::a = int($NUM.text); } 114 | '{' f '}' 115 ; 116 117 118/* tokens */ 119 120ID : ('a'..'z')+ 121 ; 122 123NUM : ('0'..'9')+ 124 ; 125 126WS : (' '|'\n'|'\r')+ {$channel=HIDDEN} 127 ; 128