1
1
package main {
2
2
use Data::Dumper;
3
3
use strict;
4
+ use Perlito5::TreeGrammar;
4
5
5
6
my $in = eval join ( ' ' , <> );
6
7
print Dumper $in ;
7
8
8
9
my ( $rule , $result );
9
10
10
11
$rule = TreeGrammar::AST::is_sub(
11
- [
12
- Action => sub {
12
+ [ Action => sub {
13
13
my $sub = $_ [0];
14
14
my $stmts ;
15
15
my $var ;
16
- TreeGrammar::render(
17
- [
18
- Lookup => ' block' ,
19
- [
20
- Progn => [ Action => sub { $stmts = $_ [0] } ],
21
- [
22
- Star => [
23
- Index => 0,
24
- TreeGrammar::AST::operator_eq(
25
- ' infix:<=>' ,
26
- [
27
- Lookup => ' arguments' ,
28
- [
29
- And => [
30
- Index => 0,
31
- TreeGrammar::AST::my_var(
32
- [
33
- Action => sub {
34
- $var = $_ [0]-> {var };
35
- }
36
- ]
37
- )
38
- ],
39
- [
40
- Index => 1,
41
- TreeGrammar::AST::shift_arg()
42
- ],
43
- [
44
- Action => sub {
45
- push @{ $sub -> {args } }, $var ;
46
- shift @$stmts ;
47
- }
48
- ]
49
- ]
50
- ]
51
- )
52
- ]
53
- ]
16
+ Perlito5::TreeGrammar::render(
17
+ [ Lookup => ' block' ,
18
+ [ Progn => [ Action => sub { $stmts = $_ [0] } ],
19
+ [ Star => [
20
+ Index => 0,
21
+ TreeGrammar::AST::operator_eq( ' infix:<=>' ,
22
+ [ Lookup => ' arguments' ,
23
+ [ And => [ Index => 0,
24
+ TreeGrammar::AST::my_var(
25
+ [ Action => sub {
26
+ $var = $_ [0]-> {var };
27
+ }
28
+ ]
29
+ )
30
+ ],
31
+ [ Index => 1,
32
+ TreeGrammar::AST::shift_arg()
33
+ ],
34
+ [ Action => sub {
35
+ push @{ $sub -> {args } }, $var ;
36
+ shift @$stmts ;
37
+ }
38
+ ]
39
+ ]
40
+ ]
41
+ )
42
+ ]
43
+ ]
54
44
]
55
45
],
56
46
$sub
@@ -59,7 +49,7 @@ package main {
59
49
]
60
50
);
61
51
62
- $result = TreeGrammar::scan( $rule , $in );
52
+ $result = Perlito5:: TreeGrammar::scan( $rule , $in );
63
53
print " result $result \n " ;
64
54
print Dumper $in ;
65
55
@@ -69,48 +59,39 @@ package TreeGrammar::AST {
69
59
use strict;
70
60
71
61
sub is_sub {
72
- [
73
- Ref => ' Perlito5::AST::Sub' ,
62
+ [ Ref => ' Perlito5::AST::Sub' ,
74
63
( @_ ? [ Progn => @_ ] : () )
75
64
];
76
65
}
77
66
78
67
sub named_sub {
79
- [
80
- Ref => ' Perlito5::AST::Sub' ,
81
- [
82
- And => [ Lookup => ' name' , [ Not => [ Value => ' ' ] ] ],
68
+ [ Ref => ' Perlito5::AST::Sub' ,
69
+ [ And => [ Lookup => ' name' , [ Not => [ Value => ' ' ] ] ],
83
70
( @_ ? [ Progn => @_ ] : () )
84
71
]
85
72
];
86
73
}
87
74
88
75
sub operator_eq {
89
76
my $name = shift ;
90
- [
91
- Ref => ' Perlito5::AST::Apply' ,
92
- [
93
- And => [ Lookup => ' code' , [ Value => $name ] ],
77
+ [ Ref => ' Perlito5::AST::Apply' ,
78
+ [ And => [ Lookup => ' code' , [ Value => $name ] ],
94
79
( @_ ? [ Progn => @_ ] : () )
95
80
]
96
81
];
97
82
}
98
83
99
84
sub my_var {
100
- [
101
- Ref => ' Perlito5::AST::Decl' ,
102
- [
103
- And => [ Lookup => ' decl' , [ Value => ' my' ] ],
85
+ [ Ref => ' Perlito5::AST::Decl' ,
86
+ [ And => [ Lookup => ' decl' , [ Value => ' my' ] ],
104
87
( @_ ? [ Progn => @_ ] : () )
105
88
]
106
89
];
107
90
}
108
91
109
92
sub shift_arg {
110
- [
111
- Ref => ' Perlito5::AST::Apply' ,
112
- [
113
- And => [ Lookup => ' code' , [ Value => ' shift' ] ],
93
+ [ Ref => ' Perlito5::AST::Apply' ,
94
+ [ And => [ Lookup => ' code' , [ Value => ' shift' ] ],
114
95
115
96
# TODO - bareword => 1, arguments => [], namespace => ''
116
97
# or arguments => [ @_ ]
@@ -121,123 +102,4 @@ package TreeGrammar::AST {
121
102
122
103
}
123
104
124
- package TreeGrammar {
125
- use Data::Dumper;
126
- use strict;
127
-
128
- my %dispatch ;
129
- INIT {
130
- %dispatch = (
131
- Ref => \&Ref, # Ref => 'Perlito5::AST::Apply'
132
- Lookup => \&Lookup, # Lookup => 'namespace'
133
- Index => \&Index, # Index => '0'
134
- Value => \&Value, # Value => '123'
135
- And => \&And,
136
- Or => \&Or,
137
- Not => \&Not,
138
- Action => \&Action,
139
- Progn => \&Progn, # same as in Lisp
140
- Star => \&Star, # same as in regex
141
- );
142
- }
143
-
144
- sub render {
145
- my ( $rule , $node ) = @_ ;
146
- return $dispatch { $rule -> [0] }-> ( $rule , $node );
147
- }
148
-
149
- sub scan {
150
- my ( $rule , $node ) = @_ ;
151
- render( $rule , $node ) if $rule ;
152
- if ( ref ($node ) eq ' ARRAY' ) {
153
- scan( $rule , $_ ) for @$node ;
154
- }
155
- elsif ( ref ($node ) ) {
156
- scan( $rule , $_ ) for values %$node ;
157
- }
158
- return ;
159
- }
160
105
161
- sub Action {
162
- my ( $rule , $node ) = @_ ;
163
- $rule -> [1]-> ($node );
164
- return 1;
165
- }
166
-
167
- sub Not {
168
- my ( $rule , $node ) = @_ ;
169
- my $result ;
170
- render( $rule -> [1], $node ) && return ;
171
- return 1;
172
- }
173
-
174
- sub Star {
175
- my ( $rule , $node ) = @_ ;
176
- my $result ;
177
- while (1) {
178
- render( $rule -> [1], $node ) || return ;
179
- }
180
- }
181
-
182
- sub Progn {
183
- my ( $rule , $node ) = @_ ;
184
- my $result ;
185
- for ( @$rule [ 1 .. $# $rule ] ) {
186
- $result = render( $_ , $node );
187
- }
188
- return $result ;
189
- }
190
-
191
- sub And {
192
- my ( $rule , $node ) = @_ ;
193
- my $result ;
194
- for ( @$rule [ 1 .. $# $rule ] ) {
195
- $result = render( $_ , $node ) or return ;
196
- }
197
- return $result ;
198
- }
199
-
200
- sub Or {
201
- my ( $rule , $node ) = @_ ;
202
- my $result ;
203
- for ( @$rule [ 1 .. $# $rule ] ) {
204
- $result = render( $_ , $node ) and return $result ;
205
- }
206
- return ;
207
- }
208
-
209
- sub Ref {
210
- my ( $rule , $node ) = @_ ;
211
- return if ref ($node ) ne $rule -> [1];
212
- return 1 if !$rule -> [2];
213
- return render( $rule -> [2], $node );
214
- }
215
-
216
- sub Lookup {
217
- my ( $rule , $node ) = @_ ;
218
- return
219
- if !ref ($node )
220
- || ref ($node ) eq ' ARRAY'
221
- || !exists ( $node -> { $rule -> [1] } );
222
- return 1 if !$rule -> [2];
223
- return render( $rule -> [2], $node -> { $rule -> [1] } );
224
- }
225
-
226
- sub Index {
227
- my ( $rule , $node ) = @_ ;
228
- return
229
- if !ref ($node )
230
- || ref ($node ) ne ' ARRAY'
231
- || !exists ( $node -> [ $rule -> [1] ] );
232
- return 1 if !$rule -> [2];
233
- return render( $rule -> [2], $node -> [ $rule -> [1] ] );
234
- }
235
-
236
- sub Value {
237
- my ( $rule , $node ) = @_ ;
238
- return if ref ($node ) || $node ne $rule -> [1];
239
- return 1 if !$rule -> [2];
240
- return render( $rule -> [2], $node );
241
- }
242
-
243
- }
0 commit comments