/[webpac2]/trunk/lib/WebPAC/Parser.pm
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Contents of /trunk/lib/WebPAC/Parser.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 690 - (show annotations)
Sun Sep 24 19:00:56 2006 UTC (17 years, 7 months ago) by dpavlin
File size: 5367 byte(s)
 r975@llin:  dpavlin | 2006-09-24 20:58:49 +0200
 report invalid databases and inputs for lookups

1 package WebPAC::Parser;
2
3 use warnings;
4 use strict;
5
6 use base qw/WebPAC::Common WebPAC::Normalize/;
7
8 use PPI;
9 use PPI::Dumper;
10 use Data::Dump qw/dump/;
11 use File::Slurp;
12
13
14 =head1 NAME
15
16 WebPAC::Parser - parse perl normalization configuration files and mungle it
17
18 =head1 VERSION
19
20 Version 0.02
21
22 =cut
23
24 our $VERSION = '0.02';
25
26 =head1 SYNOPSIS
27
28 FIXME
29
30 =head1 FUNCTIONS
31
32 =head2 new
33
34 Create new parser object.
35
36 my $parser = new WebPAC::Parser(
37 config => new WebPAC::Config(),
38 base_path => '/optional/path/to/conf',
39 );
40
41 =cut
42
43 sub new {
44 my $class = shift;
45 my $self = {@_};
46 bless($self, $class);
47
48 my $log = $self->_get_logger();
49
50 $log->logdie("config isn't WebPAC::Config") unless ($self->{config} && $self->{config}->isa('WebPAC::Config'));
51
52 $log->logdie("can't iterate_inputs over this config object") unless ($self->{config}->can('iterate_inputs'));
53
54 my $source;
55
56 $self->{config}->iterate_inputs( sub {
57 my ($input, $database) = @_;
58 my $path = $input->{normalize}->{path} || return;
59 my $full = $self->{base_path} ? $self->{base_path} . '/' . $path : $path;
60 $log->logdie("normalization input $full doesn't exist") unless (-e $full);
61 my $s = read_file( $full ) || $log->logdie("can't read $full: $!");
62 my $input_name = $input->{name} || $log->logdie("can't deduce name of input: ", dump( $input ));
63 $log->debug("$database/$input_name: adding $path to parser [",length($s)," bytes]");
64 $source .= $s;
65 $self->{valid_inputs}->{$database}->{$input_name}++;
66 } );
67
68 $log->debug("collected ", length($source), " bytes of source");
69
70 $self->{source} = $source;
71
72 $self ? return $self : return undef;
73 }
74
75 =head2 parse
76
77 =cut
78
79 sub parse {
80 my $self = shift;
81
82 my $log = $self->_get_logger();
83
84 $log->logdie('no source found in object') unless ($self->{source});
85
86 $log->debug("valid_inputs = ", dump( $self->{valid_inputs} ));
87
88 my $Document = PPI::Document->new( \$self->{source} ) || $log->logdie("can't parse source:\n", $self->{source});
89
90 $Document->prune('PPI::Token::Whitespace');
91 #$Document->prune('PPI::Token::Operator');
92
93 # Find all the named subroutines
94
95 my $eval_create;
96 my @errors;
97
98 sub error {
99 my $msg = shift || $log->logconfess("error without message?");
100 push @errors, $msg;
101 return '';
102 }
103
104 $Document->find( sub {
105 my ($Document,$Element) = @_;
106
107 $Element->isa('PPI::Token::Word') or return '';
108 $Element->content eq 'lookup' or return '';
109
110 $log->debug("expansion: ", $Element->snext_sibling);
111
112 my $args = $Element->snext_sibling;
113
114 my @e = $args->child(0)->elements;
115 $log->logdie("hum, expect at least 8 elements, got ", scalar @e, " in $args") if ($#e < 8);
116
117 if ($log->is_debug) {
118 my $report = "found " . scalar @e . " elements:\n";
119
120 foreach my $i ( 0 .. $#e ) {
121 $report .= sprintf("# %-2d: %-30s %s\n", $i, ( $e[$i] || 'undef' ), $e[$i]->class );
122 }
123
124 $log->debug($report);
125 }
126
127 my $key_element = $e[8]->clone;
128
129 $log->logdie("key element must be PPI::Structure::Block") unless $key_element->isa('PPI::Structure::Block');
130
131 $log->debug("key part: ", $key_element);
132
133 my @key;
134
135 $key_element->find( sub {
136 my $e = $_[1] || die "no element?";
137 $e->isa('PPI::Token::Word') or return '';
138 $e->content eq 'rec' or return '';
139
140 my $kf = $e->snext_sibling;
141
142 $log->debug("key fragment = $kf");
143
144 push @key, eval $kf;
145 $log->logdie("can't eval { $kf }: $@") if ($@);
146
147 return 1;
148 });
149
150 my $key = join('-', @key ) || $log->logdie("no key found!");
151
152 $log->debug("key = $key");
153
154 my $create = '
155 $coderef = ' . $e[7] . $e[8] . ';
156 foreach my $v ($coderef->()) {
157 next unless (defined($v) && $v ne \'\');
158 push @{ $lookup->{\'' . $key . '\'}->{$v} }, $mfn;
159 }
160 ';
161
162 $log->debug("create: $create");
163
164 return error("invalid database $e[3]" ) unless $self->valid_database( $e[3] );
165 return error("invalid input $e[5] of database $e[3]", ) unless $self->valid_database_input( $e[3], $e[5] );
166
167 $eval_create->{ $e[3] }->{ $e[5] } .= $create;
168
169 if ($#e < 10) {
170 $e[8]->insert_after( $e[8]->clone );
171 $e[8]->insert_after( $e[7]->clone );
172 $e[8]->insert_after( $e[6]->clone );
173 }
174
175 $e[7]->remove;
176 $e[8]->insert_before( new PPI::Token::Quote::Single( "'$key'" ) );
177 $e[8]->remove;
178
179
180 $log->debug(">>> ", $Element->snext_sibling);
181 });
182
183 $log->info("create: ", dump($eval_create) );
184 $log->info("lookup: ", $Document->serialize );
185
186 if ($self->{debug}) {
187 my $Dumper = PPI::Dumper->new( $Document );
188 $Dumper->print;
189 }
190
191 $log->error("Parser errors: ", join("\n",@errors) ) if (@errors);
192
193 return 1;
194 }
195
196 =head2 valid_database
197
198 my $ok = $parse->valid_database('key');
199
200 =cut
201
202 sub valid_database {
203 my $self = shift;
204
205 my $database = shift || return;
206 $database =~ s/['"]//g;
207
208 return defined($self->{valid_inputs}->{$database});
209 }
210
211 =head2 valid_database_input
212
213 my $ok = $parse->valid_database('database_key','input_name');
214
215 =cut
216
217 sub valid_database_input {
218 my $self = shift;
219
220 my ($database,$input) = @_;
221 $database =~ s/['"]//g;
222 $input =~ s/['"]//g;
223
224 return defined($self->{valid_inputs}->{$database}->{$input});
225 }
226
227 =head1 AUTHOR
228
229 Dobrica Pavlinusic, C<< <dpavlin@rot13.org> >>
230
231 =head1 COPYRIGHT & LICENSE
232
233 Copyright 2006 Dobrica Pavlinusic, All Rights Reserved.
234
235 This program is free software; you can redistribute it and/or modify it
236 under the same terms as Perl itself.
237
238 =cut
239
240 1; # End of WebPAC::Parser

  ViewVC Help
Powered by ViewVC 1.1.26