Skip to content

Commit 3bc9e5a

Browse files
committed
Perlito - misc - tree grammar - actions
1 parent fcea756 commit 3bc9e5a

File tree

1 file changed

+72
-35
lines changed

1 file changed

+72
-35
lines changed

misc/tree_grammar.pl

Lines changed: 72 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,28 @@ package main {
66
print Dumper $in;
77

88
my $rule = [ Ref => 'Perlito5::AST::Apply' ];
9-
TreeGrammar::scan( $rule, $in );
9+
my $result = TreeGrammar::scan( $rule, $in );
10+
print "result $result\n";
1011

1112
$rule = [
1213
Lookup => 'name',
1314
[ Value => 'a' ]
1415
];
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+
1631
}
1732

1833
package TreeGrammar {
@@ -26,23 +41,20 @@ package TreeGrammar {
2641
Lookup => \&Lookup, # Lookup => 'namespace'
2742
Index => \&Index, # Index => '0'
2843
Value => \&Value, # Value => '123'
44+
And => \&And,
45+
Or => \&Or,
46+
Action => \&Action,
2947
);
3048
}
3149

3250
sub render {
3351
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 );
4153
}
4254

4355
sub scan {
4456
my ( $rule, $node ) = @_;
45-
render( $rule, $node );
57+
render( $rule, $node ) if $rule;
4658
if ( ref($node) eq 'ARRAY' ) {
4759
scan( $rule, $_ ) for @$node;
4860
}
@@ -52,45 +64,70 @@ package TreeGrammar {
5264
return;
5365
}
5466

55-
sub Ref {
67+
sub Action {
5668
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 };
6272
}
6373

64-
sub Lookup {
74+
sub And {
6575
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;
7180
}
72-
return;
81+
print "fail\n";
82+
return $result;
7383
}
7484

75-
sub Index {
85+
sub Or {
7686
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;
8290
}
8391
return;
8492
}
8593

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+
86125
sub Value {
87126
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 };
94131
}
95132

96133
}

0 commit comments

Comments
 (0)