File Coverage

blib/lib/Pugs/Compiler/RegexPerl5.pm
Criterion Covered Total %
statement 62 66 93.9
branch 5 16 31.2
condition 1 8 12.5
subroutine 17 17 100.0
pod 0 1 0.0
total 85 108 78.7


line stmt bran cond sub pod time code
1             package Pugs::Compiler::RegexPerl5;
2              
3             # Version in Pugs::Compiler::Rule
4             # Documentation in the __END__
5 17     17   460 use 5.006;
  17         60  
  17         715  
6 17     17   100 use strict;
  17         34  
  17         645  
7 17     17   109 use warnings;
  17         31  
  17         9697  
8              
9             #use base 'Pugs::Compiler::Regex';
10              
11             #use Pugs::Compiler::Regex;
12             #sub code { (+shift)->Pugs::Compiler::Regex::code( @_ ) }
13              
14             # http://www.foo.be/docs/tpj/issues/vol2_3/tpj0203-0002.html
15             # is a good reference on the use of pos()
16              
17             sub _quote_rule {
18 483     483   620 my $rule_source = shift;
19 483 50       3397 return 'm/' . $rule_source . '/' unless $rule_source =~ m{/};
20 0 0 0     0 return 'm{' . $rule_source . '}' unless $rule_source =~ m/{/ || $rule_source =~ m/}/;
21 0 0       0 return 'm!' . $rule_source . '!' unless $rule_source =~ m/!/;
22 0 0 0     0 return 'm[' . $rule_source . ']' unless $rule_source =~ m/\[/ || $rule_source =~ m/\]/;
23 0 0       0 return 'm^' . $rule_source . '^' unless $rule_source =~ m/^/;
24             }
25              
26             sub compile {
27 161     161 0 436 my ( $class, $rule_source, $param ) = @_;
28 161         490 my $self = { source => $rule_source };
29 161 100       594 $param = ref $param ? { %$param } : {};
30 161         370 delete $param->{P5};
31 161         211 delete $param->{Perl5};
32 161   50     1258 $self->{continue} = delete $param->{continue} ||
33             delete $param->{c} ||
34             0;
35 161         252 my $compile_only = delete $param->{compile_only};
36             warn "Error in rule: unknown parameter '$_'"
37 161         600 for keys %$param;
38            
39             # TODO - set "prior"
40            
41 161         556 my $captures = q'
42             for ( 1 .. $#+ ) {
43             push @match, Pugs::Runtime::Match->new({
44             str => $_[1], from => \\(0+$-[$_]), to => \\(0+$+[$_]),
45             bool => \\1, match => [], named => {}, capture => undef,
46             });
47             }
48             ' .
49             #print "POS $bool ",(0+$-[0]),"-",(0+$+[0]),"\n";select(undef, undef, undef, 0.1);
50             'return Pugs::Runtime::Match->new({
51             str => $_[1], from => \\(0+$-[0]), to => \\(0+$+[0]),
52             bool => \\$bool, match => \\@match, named => {}, capture => undef,
53             });
54             ';
55 161         1001 $self->{perl5} =
56             q!do {
57             my $rule;
58             $rule = sub { # grammar, string, state, args
59             no warnings 'uninitialized';
60             my $bool;
61             my @match;
62            
63             return $rule->($_[0], \\$_[1], $_[2], $_[3])
64             unless ref( $_[1] ); # backwards compatibility
65            
66             #print "POS ${$_[1]} ",pos(${$_[1]}),"\n";
67             #print "p5 $_[3]{p} \n";
68            
69             if( $_[3]{continue} ) {
70             pos(${$_[1]}) = $_[3]{p}
71             if defined $_[3]{p};
72             $bool = ( ${$_[1]} =~ !
73             . _quote_rule( $rule_source )
74             . q(g \) ? 1 : 0; )
75             . $captures
76             . q!
77             }
78            
79             if ( defined $_[3]{p} ) {
80             pos(${$_[1]}) = $_[3]{p};
81             $bool = ( ${$_[1]} =~ !
82             . _quote_rule(
83             q(\\G\(?:) . $rule_source . ')'
84             )
85             . ' ) ? 1 : 0; '
86             . $captures
87             . q!
88             }
89             else {
90             $bool = ( ${$_[1]} =~ !
91             . _quote_rule( $rule_source )
92             . q( \) ? 1 : 0; )
93             . $captures . q(
94             }
95             };
96             }
97             );
98             # print 'rule perl5: ', do{use Data::Dumper; Dumper($self->{perl5})};
99              
100 161 50       523 unless ( $compile_only ) {
101 161         215 local $@;
102 14     14   114 $self->{code} = eval
  14     14   33  
  14     14   9838  
  14     14   99  
  14     14   31  
  14     13   9611  
  14     13   100  
  14     13   38  
  14     13   6921773  
  14     13   135  
  14     13   34  
  14     13   9418  
  14         91  
  14         31  
  14         15642  
  13         89  
  13         32  
  13         9795  
  13         85  
  13         31  
  13         12119  
  13         95  
  13         29  
  13         90104  
  13         137  
  13         43  
  13         11441  
  13         91  
  13         32  
  13         17936  
  13         90  
  13         365  
  13         9861  
  13         83  
  13         31  
  13         8856  
  161         26534  
103             $self->{perl5};
104 161 50       822 die "Error in evaluation: $@\nSource:\n$self->{perl5}\n" if $@;
105             }
106            
107 161         1842 bless $self, 'Pugs::Compiler::Regex';
108             }
109              
110             1;
111              
112             __END__