File Coverage

blib/lib/Wraith.pm
Criterion Covered Total %
statement 99 100 99.0
branch 13 16 81.2
condition n/a
subroutine 33 33 100.0
pod 0 14 0.0
total 145 163 88.9


line stmt bran cond sub pod time code
1 2     2   59864 use strict;
  2         5  
  2         69  
2 2     2   10 use warnings;
  2         3  
  2         364  
3              
4             require Exporter;
5              
6             our $VERSION = 0.12;
7              
8             {
9             package Wraith;
10              
11             our @ISA = qw( Exporter );
12             our @EXPORT_OK = qw( $literal $literals $token $many $succeed $fail $many_g $opt $satisfy );
13              
14             {
15             package inner_lazy;
16              
17             sub TIESCALAR {
18 32     32   46 my ($class, $val) = @_;
19 32         86 bless $_[1], $class
20             }
21              
22             sub FETCH {
23 28     28   33 my ($self) = @_;
24 28         57 $self->()
25             }
26             }
27              
28             use overload
29 2         12 '>>' => "then_impl",
30             '|' => "alt_impl",
31 2     2   3402 '**' => "using_impl";
  2         2359  
32              
33             sub deref {
34 473     473 0 708 my @args = @_;
35 473         724 for my $elt (@args) {
36 572 100       1379 if (ref($elt) eq "Wraith_rule") {
37 66         141 $elt = $$elt;
38             }
39             }
40             @args
41 473         1148 }
42              
43             sub concat_impl {
44 202     202 0 303 my @list_of_lists = @_;
45 202         211 my @list;
46              
47 202         233 for my $elt (@list_of_lists) {
48 405         1077 push @list, $_ for @$elt;
49             }
50             \@list
51 202         805 };
52             our $concat = \&concat_impl;
53              
54             sub succeed_impl {
55 89     89 0 140 my $v = $_[0];
56             bless
57             sub {
58 105 100   105   282 my $u = (ref($v) eq "ARRAY") ? $v : [ $v ];
59 105         349 [ [ $u, $_[0] ] ]
60             }
61 89         359 };
62             our $succeed = bless \&succeed_impl;
63              
64             sub fail_impl {
65 96     96 0 197 []
66             };
67             our $fail = bless \&fail_impl;
68              
69             sub satisfy_impl {
70 25     25 0 40 my ($p, $m) = @_;
71 25 100   13   67 $m = sub { $_[0] =~ /(.)(.*)/s } if not $m;
  13         63  
72             bless
73             sub {
74 152 100   152   348 if (my ($x, $xs) = $m->($_[0])) {
75 61 100       122 if ($p->($x)) {
76 56         109 return $succeed->($x)->($xs);
77             } else {
78 5         12 return $fail->($xs);
79             }
80             } else {
81 91         204 return $fail->( [] );
82             }
83             }
84 25         224 };
85             our $satisfy = bless \&satisfy_impl;
86              
87             sub literal_impl {
88 11     11 0 4632 my $y = $_[0];
89             $satisfy->(
90             sub {
91 12     12   31 $y eq $_[0]
92             }
93             )
94 11         49 };
95             our $literal = bless \&literal_impl;
96              
97             sub literals_impl {
98 1     1 0 1474 my $y = $_[0];
99             $satisfy->(
100             sub {
101 1     1   5 index($y, $_[0]) != -1
102             }
103             )
104 1         7 };
105             our $literals = bless \&literals_impl;
106              
107             sub token_impl {
108 13     13 0 2422 my ($tok, $skip) = @_;
109 13 50       30 $skip = '\s*' if not $skip;
110             $satisfy->(
111 48     48   92 sub { 1 },
112             sub {
113 139     139   2359 $_[0] =~ /^$skip($tok)(.*)/s
114             }
115             )
116 13         67 };
117             our $token = bless \&token_impl;
118              
119             sub alt_impl {
120 38     38 0 60 my ($p1_, $p2_, $discard) = @_;
121             bless
122             sub {
123 99     99   166 my ($p1, $p2) = deref($p1_, $p2_);
124 99         133 my $inp = $_[0];
125 99         196 $concat->($p1->($inp), $p2->($inp))
126             }
127 38         171 }
128             our $alt = bless \&alt_impl;
129              
130             sub then_impl {
131 44     44 0 60 my $arglist = \@_;
132             bless
133             sub {
134 169     169   289 my ($p1) = deref($arglist->[0]);
135 169         220 my $inp = $_[0];
136 169         276 my $reslist1 = $p1->($inp);
137 169         360 my $finlist = [];
138 169         297 for my $respair (@$reslist1) {
139 88         906 my ($p2) = deref($arglist->[1]);
140 88         186 my $reslist2 = $p2->($respair->[1]);
141 88         288 for my $finpair (@$reslist2) {
142 102         196 push @$finlist, [ $concat->($respair->[0], $finpair->[0]), $finpair->[1] ];
143             }
144             }
145             $finlist
146 169         420 }
147 44         448 }
148             our $then = bless \&then_impl;
149              
150             sub using_impl {
151 9     9 0 22 my ($p_, $f, $discard) = @_;
152             bless
153             sub {
154 115     115   211 my ($p) = deref($p_);
155 115         154 my $inp = $_[0];
156 115         190 my $reslist = $p->($inp);
157 115         234 my $finlist = [];
158 115         165 for my $respair (@$reslist) {
159 102         416 push @$finlist, [ $f->($respair->[0]), $respair->[1] ];
160             }
161             $finlist
162 115         594 }
163 9         65 }
164             our $using = bless \&using_impl;
165              
166             sub many_impl {
167 32     32 0 130 my $p = $_[0];
168 32         30 my $f;
169 32     28   162 tie $f, "inner_lazy", sub { many_impl($p) };
  28         43  
170 32         63 $alt->($then->($p, $f), $succeed->( [] ))
171             }
172             our $many = bless \&many_impl;
173              
174             sub many_g_impl {
175 1     1 0 3 my $arglist = \@_;
176             bless
177             sub {
178 1     1   3 my ($p) = deref($arglist->[0]);
179 1         2 my $inp = $_[0];
180 1         2 my $finlist = [];
181 1         2 while (1) {
182 4         7 my $reslist = $p->($inp);
183 4 100       18 last if (not @$reslist);
184 3         5 my $respair = shift @$reslist;
185 3         6 for my $elt (@$reslist) {
186 0 0       0 $respair = $elt if (length($respair->[1]) < length($elt->[1]));
187             }
188 3         5 push @$finlist, $respair->[0];
189 3         8 $inp = $respair->[1];
190             }
191 1         3 [ [ $concat->(@$finlist), $inp ] ]
192             }
193 1         7 }
194             our $many_g = bless \&many_g_impl;
195              
196             sub opt_impl {
197 1     1 0 4 my ($p) = deref($_[0]);
198 1         4 $alt->($p, $succeed->( [] ))
199             }
200             our $opt = bless \&opt_impl;
201             }
202              
203             {
204             package Wraith_rule;
205              
206             our @ISA = qw( Exporter Wraith );
207             our @EXPORT_OK = qw( );
208              
209             sub makerule {
210 6     6   14 bless $_[0]
211             }
212              
213             sub makerules {
214 1     1   24 my ($class, @args) = @_;
215 1         4 for my $elt (@args) {
216 6         11 $elt = makerule($elt);
217             }
218             @args
219 1         4 }
220             }
221              
222             1;
223              
224             __END__