1 package Filter::Keyword::Parser;
4 use Scalar::Util qw(set_prototype);
6 has reader => (is => 'ro', required => 1);
8 has re_add => (is => 'ro', required => 1);
10 has keywords => (is => 'ro', default => sub { [] });
13 push @{$_[0]->keywords}, $_[1];
16 my ($self, $keyword) = @_;
17 my $keywords = $self->keywords;
18 for my $idx (0 .. $#$keywords) {
19 if ($keywords->[$idx] eq $keyword) {
20 splice @$keywords, $idx, 1;
26 has current_match => (is => 'rw');
28 has short_circuit => (is => 'rw');
30 has code => (is => 'rw', default => sub { '' });
34 if ($self->short_circuit) {
35 $self->short_circuit(0);
36 $self->${\$self->re_add};
39 for my $keyword (@{$self->keywords}) {
40 if ($keyword->have_match) {
41 $keyword->clear_globref;
42 return $keyword->parser->($keyword, $self);
45 return $self->check_match;
50 my $code = $self->code||'';
51 my ($extra_code, $not_eof) = $self->reader->();
58 my ($self, $first, $second) = @_;
59 $self->fetch_more while $self->code =~ /$first\s+\Z/;
60 if (my @match = ($self->code =~ /(.*?${first}\s+${second})(.*)\Z/)) {
61 $self->code(pop @match);
62 my $found = shift(@match);
63 return ($found, \@match);
70 unless ($self->code) {
74 for my $keyword (@{ $self->keywords }) {
76 my ($stripped, $matches)
77 = $self->match_source(
78 $keyword->keyword_name, qr/(\(|[A-Za-z][A-Za-z_0-9]*|{)/
82 set_prototype(\&$sub, '*;@') unless $matches->[0] eq '(';
83 { no warnings 'redefine', 'prototype'; *{$keyword->globref} = $sub; }
84 $keyword->save_refcount;
85 $self->current_match($matches);
86 $self->short_circuit(1);
87 return ($stripped, 1);
90 my $code = $self->code;