@@ -6,13 +6,28 @@ package main {
6
6
print Dumper $in ;
7
7
8
8
my $rule = [ Ref => ' Perlito5::AST::Apply' ];
9
- TreeGrammar::scan( $rule , $in );
9
+ my $result = TreeGrammar::scan( $rule , $in );
10
+ print " result $result \n " ;
10
11
11
12
$rule = [
12
13
Lookup => ' name' ,
13
14
[ Value => ' a' ]
14
15
];
15
- TreeGrammar::scan( $rule , $in );
16
+ $result = TreeGrammar::scan( $rule , $in );
17
+ print " result $result \n " ;
18
+
19
+ $rule = [
20
+ And => [
21
+ Lookup => ' name' ,
22
+ [ Value => ' a' ]
23
+ ],
24
+ [ Lookup => ' namespace' ],
25
+ [ Action => sub { $_ [0]-> {HERE } = 1 } ],
26
+ ];
27
+ $result = TreeGrammar::scan( $rule , $in );
28
+ print " result $result \n " ;
29
+ print Dumper $in ;
30
+
16
31
}
17
32
18
33
package TreeGrammar {
@@ -26,23 +41,20 @@ package TreeGrammar {
26
41
Lookup => \&Lookup, # Lookup => 'namespace'
27
42
Index => \&Index, # Index => '0'
28
43
Value => \&Value, # Value => '123'
44
+ And => \&And,
45
+ Or => \&Or,
46
+ Action => \&Action,
29
47
);
30
48
}
31
49
32
50
sub render {
33
51
my ( $rule , $node ) = @_ ;
34
- if ( ref ($rule ) ) {
35
-
36
- # print "Rule ", Dumper $rule;
37
- # print Dumper \%dispatch;
38
- return $dispatch { $rule -> [0] }-> ( $rule , $node );
39
- }
40
- return ;
52
+ return $dispatch { $rule -> [0] }-> ( $rule , $node );
41
53
}
42
54
43
55
sub scan {
44
56
my ( $rule , $node ) = @_ ;
45
- render( $rule , $node );
57
+ render( $rule , $node ) if $rule ;
46
58
if ( ref ($node ) eq ' ARRAY' ) {
47
59
scan( $rule , $_ ) for @$node ;
48
60
}
@@ -52,45 +64,70 @@ package TreeGrammar {
52
64
return ;
53
65
}
54
66
55
- sub Ref {
67
+ sub Action {
56
68
my ( $rule , $node ) = @_ ;
57
- if ( ref ($node ) eq $rule -> [1] ) {
58
- print " match: Ref $node \n " ;
59
- return { pos => $node };
60
- }
61
- return ;
69
+ print " match: Action $node \n " ;
70
+ $rule -> [1]-> ( $node );
71
+ return { pos => $node };
62
72
}
63
73
64
- sub Lookup {
74
+ sub And {
65
75
my ( $rule , $node ) = @_ ;
66
- return if !ref ($node ) || ref ($node ) eq ' ARRAY' ;
67
- if ( exists ( $node -> { $rule -> [1] } ) ) {
68
- print " match: Lookup $node \n " ;
69
- return render( $rule -> [2], $node -> { $rule -> [1] } ) if $rule -> [2];
70
- return { pos => $node };
76
+ my $result ;
77
+ print " match: And $node \n " ;
78
+ for ( @$rule [ 1 .. $# $rule ] ) {
79
+ $result = render( $_ , $node ) or return ;
71
80
}
72
- return ;
81
+ print " fail\n " ;
82
+ return $result ;
73
83
}
74
84
75
- sub Index {
85
+ sub Or {
76
86
my ( $rule , $node ) = @_ ;
77
- return if !ref ($node ) || ref ($node ) ne ' ARRAY' ;
78
- if ( exists ( $node -> [ $rule -> [1] ] ) ) {
79
- print " match: Index $node \n " ;
80
- return render( $rule -> [2], $node -> [ $rule -> [1] ] ) if $rule -> [2];
81
- return { pos => $node };
87
+ my $result ;
88
+ for ( @$rule [ 1 .. $# $rule ] ) {
89
+ $result = render( $_ , $node ) and return $result ;
82
90
}
83
91
return ;
84
92
}
85
93
94
+ sub Ref {
95
+ my ( $rule , $node ) = @_ ;
96
+ return if ref ($node ) ne $rule -> [1];
97
+ print " match: Ref $node \n " ;
98
+ return render( $rule -> [2], $node ) if $rule -> [2];
99
+ print " true\n " ;
100
+ return { pos => $node };
101
+ }
102
+
103
+ sub Lookup {
104
+ my ( $rule , $node ) = @_ ;
105
+ return
106
+ if !ref ($node )
107
+ || ref ($node ) eq ' ARRAY'
108
+ || !exists ( $node -> { $rule -> [1] } );
109
+ print " match: Lookup $node \n " ;
110
+ return render( $rule -> [2], $node -> { $rule -> [1] } ) if $rule -> [2];
111
+ return { pos => $node };
112
+ }
113
+
114
+ sub Index {
115
+ my ( $rule , $node ) = @_ ;
116
+ return
117
+ if !ref ($node )
118
+ || ref ($node ) ne ' ARRAY'
119
+ || !exists ( $node -> [ $rule -> [1] ] );
120
+ print " match: Index $node \n " ;
121
+ return render( $rule -> [2], $node -> [ $rule -> [1] ] ) if $rule -> [2];
122
+ return { pos => $node };
123
+ }
124
+
86
125
sub Value {
87
126
my ( $rule , $node ) = @_ ;
88
- return if ref ($node );
89
- if ( $node eq $rule -> [1] ) {
90
- print " match: Value $node \n " ;
91
- return { pos => $node };
92
- }
93
- return ;
127
+ return if ref ($node ) || $node ne $rule -> [1];
128
+ print " match: Value $node \n " ;
129
+ return render( $rule -> [2], $node ) if $rule -> [2];
130
+ return { pos => $node };
94
131
}
95
132
96
133
}
0 commit comments