File Coverage

blib/lib/Lingua/LinkParser/MatchPath/SM.pm
Criterion Covered Total %
statement 12 200 6.0
branch 0 114 0.0
condition 0 15 0.0
subroutine 4 19 21.0
pod 0 15 0.0
total 16 363 4.4


line stmt bran cond sub pod time code
1             package Lingua::LinkParser::MatchPath::SM;
2 1     1   6 use strict;
  1         2  
  1         31  
3              
4 1     1   5880 use Data::Dumper;
  1         13392  
  1         72  
5              
6 1     1   882 use Lingua::LinkParser::MatchPath::BuildSM;
  1         3  
  1         31  
7 1     1   610 use Lingua::LinkParser::MatchPath::SMContext;
  1         3  
  1         2292  
8             our @ISA =
9             qw(
10             Lingua::LinkParser::MatchPath::BuildSM
11             Lingua::LinkParser::MatchPath::SMContext
12             );
13              
14 0     0 0   sub print_stat {
15             # print @_;
16             }
17              
18             sub word_content_and_pos {
19 0     0 0   shift() =~ /^(.+?)(?:\[.\])?(?:\.([pavding]))?$/o;
20 0           print_stat "## $1 , $2\n";
21 0           ($1, $2);
22             }
23              
24              
25             sub check_wordmatch {
26 0     0 0   my ($wordpattern, $content_ref, $pos) = @_;
27 0           my $match = 0;
28              
29 0 0         if($wordpattern->[0] eq 'W'){
    0          
    0          
    0          
    0          
    0          
30 0 0         $match = 1 if $$content_ref eq $wordpattern->[1];
31             }
32             # word regexp
33             elsif($wordpattern->[0] eq 'WR'){
34 0 0         if( $$content_ref =~ /$wordpattern->[1]/ ){
35 0           $match = 1;
36 0 0         $$content_ref = $1 if $#+ >= 1;
37             }
38             }
39             # pos tag
40             elsif($wordpattern->[0] eq 'P'){
41 0 0         $match = 1 if $pos eq $wordpattern->[1];
42             }
43             # negative word
44             elsif ($wordpattern->[0] eq 'NW'){
45 0 0         $match = 1 if $$content_ref ne $wordpattern->[1];
46             }
47             # negative word regexp
48             elsif ($wordpattern->[0] eq 'NWR'){
49 0 0         if( $$content_ref !~ /$wordpattern->[1]/ ){
50 0           $match = 1;
51             }
52             }
53             # negative pos tag
54             elsif ($wordpattern->[0] eq 'NP'){
55 0 0         $match = 1 if $pos ne $wordpattern->[1];
56             }
57              
58 0           return $match;
59             }
60              
61             sub check_labelmatch {
62 0     0 0   my ($labelpattern, $content) = @_;
63 0           my $match = 0;
64 0 0         if($labelpattern->[0] eq 'L'){
    0          
65 0 0         return 1 if $content eq $labelpattern->[1];
66             }
67             elsif($labelpattern->[0] eq 'LR'){
68 0 0         return 1 if $content =~ /$labelpattern->[1]/;
69             }
70             }
71              
72              
73             sub get_arcs {
74 0     0 0   my $self = shift;
75 0           my $curr_state = shift;
76 0           return ref($self->{_arc}->{$curr_state}) ?
77 0 0         @{$self->{_arc}->{$curr_state}} : ();
78             }
79              
80             sub get_arctype {
81 0     0 0   my $self = shift;
82 0           my $arc = shift;
83 0 0         if($arc->{label}){
    0          
    0          
84 0           return 'L';
85             }
86             elsif($arc->{word}){
87 0           return 'W';
88             }
89             elsif($arc->{branch}){
90 0 0         return 'EB' if $arc->{branch} eq 'E';
91 0 0         return 'LB' if $arc->{branch} eq 'L';
92             }
93 0           return 'N';
94             }
95              
96             sub get_branchtype {
97 0     0 0   my $self = shift;
98 0           my $arc = shift;
99 0           $arc->{branch_type};
100             }
101              
102             sub match_first_word {
103 0     0 0   my $self = shift;
104 0           my $arc = shift;
105              
106 0           my $word_index = 0;
107              
108 0           foreach my $w ($self->{_linkage}->words){
109 0           $word_index++;
110 0           my ($content, $pos) = word_content_and_pos($w->text);
111              
112 0 0         if (check_wordmatch(
113             $arc->{word}, \$content, $pos
114             )){
115 0           print_stat "First Word: ", Dumper $w;
116 0           print_stat "($content, $pos)\n";
117             # word capturing
118 0 0         if($arc->{word}->[2]){
119 0           push @{$self->{_item}}, $content;
  0            
120             }
121 0           return $w;
122             }
123             }
124             }
125              
126             sub match_word {
127 0     0 0   my $self = shift;
128 0           my $arc = shift;
129              
130 0 0         if(!$self->{_wordptr}){
    0          
131 0           $self->{_wordptr} = $self->match_first_word($arc);
132 0 0         if($self->{_wordptr}){
133 0           return (1, $arc->{next_state});
134             }
135             else {
136 0           return (0, $arc->{next_state});
137             }
138             }
139             elsif($self->{_wordptr}) {
140 0           my $link = ($self->{_wordptr}->links)[$self->{_label_num}];
141 0           my ($content, $pos) = word_content_and_pos(
142             $link->linkword
143             );
144              
145 0 0 0       if($link &&
146             check_wordmatch ($arc->{word}, \$content, $pos)
147             ){
148 0           $self->{_wordptr} = ($self->{_linkage}->words)[$link->linkposition];
149 0           print_stat "WORD MATCH";
150 0           print_stat Dumper $self->{_wordptr};
151             # word capturing
152 0 0         if($arc->{word}->[2]){
153 0           push @{$self->{_item}}, $content;
  0            
154             }
155 0           return (1, $arc->{next_state});
156             }
157             else {
158 0           return (0, $arc->{next_state});
159             }
160             }
161             else {
162 0           return (0, $arc->{next_state});
163             }
164             }
165              
166             sub match_label {
167 0     0 0   my $self = shift;
168 0           my $arc = shift;
169              
170 0           my @links = $self->{_wordptr}->links;
171 0           my $match;
172 0           foreach my $link_num (0..$#links){
173 0           my $link = $links[$link_num];
174              
175             # skip visited labels
176 0 0         next if $self->{_visited}->{ $link->{index} };
177              
178 0 0         if(check_labelmatch($arc->{label}, $link->linklabel)){
179 0           print_stat "LABEL MATCH: ", Dumper $link_num,$/;
180 0           $self->{_label_num} = $link_num;
181 0           $self->{_visited}->{ $link->{index} } = 1;
182 0           $match = 1;
183 0           last;
184             }
185             }
186              
187 0           print_stat "VISITED: ", Dumper $self->{_visited},$/;
188 0 0         if($match){
189 0           (1, $arc->{next_state});
190             }
191             else {
192 0           (0, $arc->{next_state});
193             }
194             }
195              
196             sub go {
197 0     0 0   my $self = shift;
198 0           my $linkage = shift;
199              
200 0           my $curr_wordptr;
201 0           my $curr_state = 0;
202 0           my $next_state;
203             my @arc_stack;
204 0           my @arcs;
205 0           my $cnt;
206 0           my @state_stack;
207 0           my $result;
208 0           my @branchtype_stack;
209              
210 0           $self->{_linkage} = $linkage;
211              
212 0           while(1){
213 0           print_stat Dumper \@state_stack;
214 0 0         unless($self->{_built_arc_stack}->{$curr_state}){
215 0           print_stat "State: $curr_state\n";
216 0           my @arcs = $self->get_arcs($curr_state);
217 0 0         if( @arcs > 1 ){
218 0           print_stat scalar(@arcs)." MULTI-BRANCHES\n";
219 0           push @state_stack, $curr_state;
220             }
221 0           $self->{_arc_stack}->{$curr_state} = \@arcs;
222 0           $self->{_built_arc_stack}->{$curr_state} = 1;
223             }
224              
225 0           my $arc = shift @{$self->{_arc_stack}->{$curr_state}};
  0            
226 0 0         if(!$arc){
227 0           pop @state_stack;
228 0           $curr_state = $state_stack[-1];
229 0 0         if(!defined $curr_state){
230 0           $self->{_failed} = 1;
231 0           return 0;
232             }
233 0           next;
234             }
235 0           print_stat Dumper $arc;
236 0           my $arctype = $self->get_arctype($arc);
237 0           print_stat Dumper $arctype;
238              
239 0           $result = 1;
240 0 0         if($arctype eq 'W'){
    0          
    0          
    0          
    0          
241 0           ($result, $next_state) = $self->match_word($arc);
242 0           print_stat "($result, $next_state)\n";
243             }
244             elsif($arctype eq 'L'){
245 0           ($result, $next_state) = $self->match_label($arc);
246             }
247             elsif($arctype eq 'EB'){
248 0           my $branchtype = $self->get_branchtype($arc);
249 0 0 0       if($branchtype == 1 || $branchtype == 2){
250 0           push @{$self->{_branch_entrance}}, $curr_state;
  0            
251 0           push @{$self->{_wordptr_stack}}, $self->{_wordptr};
  0            
252 0           print_stat "PUSH BRANCHTYPE STACK";
253 0           push @branchtype_stack, $branchtype;
254             }
255 0           $next_state = $arc->{next_state};
256             }
257             elsif($arctype eq 'LB'){
258 0           my $branchtype = $self->get_branchtype($arc);
259 0 0 0       if($branchtype == 1 || $branchtype == 2){
260 0           $next_state = pop @{$self->{_branch_entrance}};
  0            
261 0           print_stat "POP BRANCHTYPE STACK";
262 0           pop @branchtype_stack;
263 0           print_stat "<<", Dumper($self->{_wordptr_stack}), ">>";
264 0           $self->{_wordptr} = pop @{$self->{_wordptr_stack}};
  0            
265             }
266 0           $next_state = $arc->{next_state};
267             }
268             elsif($arctype eq 'N') {
269 0           $next_state = $arc->{next_state};
270             }
271             else {
272 0           die;
273             }
274              
275 0 0         if(!$result){
276 0 0         if($branchtype_stack[-1] != 2){
277 0           $next_state = $state_stack[-1];
278 0 0         if(!defined $next_state){
279 0           $self->{_failed} = 1;
280             }
281 0           print_stat "=> MATCH FAILURE, go back to state $next_state\n\n";
282             }
283             else {
284 0           print_stat "SUCCESSFUL MATCHING IN NEGATIVE BRANCH\n";
285 0           print_stat "NEXT_STATE: $next_state\n";
286             }
287             }
288 0           $curr_state = $next_state;
289 0 0         return 1 if $self->accepted($curr_state);
290 0 0         return 0 if $self->failed;
291             }
292 0           1;
293             }
294              
295              
296              
297             our $PRINT_DIAGRAM;
298             our $PRINT_SUCCESSFUL_DIAGRAM;
299             our $PRINT_DIAGRAM_TO_FILE;
300             our $PRINT_SUCCESSFUL_DIAGRAM_TO_FILE;
301              
302             sub match($$) {
303 0     0 0   my $self = shift;
304 0           my $Lparser = $self->{parser};
305 0 0         my $sentence = ref($_[0]) ? shift() : $Lparser->create_sentence(shift);
306              
307 0           my $num_words;
308 0           my $linkage_count = 0;
309 0           $self->{_start_position} = 0;
310 0           $self->{_diagram_printed} = 0;
311              
312             # iterate through linkages
313 0           foreach my $linkage ($sentence->linkages){
314 0           $linkage_count++;
315 0 0         last if $linkage_count > 1;
316              
317 0           $num_words = $linkage->num_words;
318              
319 0 0         print_stat $Lparser->get_diagram($linkage) if $PRINT_DIAGRAM;
320              
321              
322 0 0 0       if( ref($self->{_fh}) && $PRINT_DIAGRAM_TO_FILE ){
323 0           $self->{_fh}->dump('DIAGRAM', $Lparser->get_diagram($linkage));
324 0           $self->{_diagram_printed} = 1;
325             }
326              
327             # clean up temporary state information
328 0           $self->reset;
329 0           my $cool = $self->go($linkage);
330            
331 0 0         if($cool){
332 0           print_stat "** COOL **\n";
333 0 0         print_stat $Lparser->get_diagram($linkage) if $PRINT_SUCCESSFUL_DIAGRAM;
334 0 0 0       print_stat $self->{_fh}->dump(
335             'SUCCESSFUL_DIAGRAM',
336             $Lparser->get_diagram($linkage)
337             )
338             if ref $self->{_fh} && $PRINT_SUCCESSFUL_DIAGRAM_TO_FILE;
339            
340 0           return 1;
341             }
342             else {
343 0           print_stat "FAILED\n";
344             }
345             }
346             }
347              
348              
349             sub accepted {
350 0     0 0   my $self = shift;
351 0           my $curr_state = shift;
352 0           print_stat "CURR_STATE: $curr_state, ACCEPT_STATE: $self->{_final_state}\n";
353 0           $curr_state == $self->{_final_state};
354             }
355              
356 0     0 0   sub failed { $_[0]->{_failed} }
357              
358              
359 0 0   0 0   sub item { @_ ? @{$_[0]->{_item}}[@_] : @{$_[0]->{_item}} }
  0            
  0            
360              
361             1;
362              
363              
364             __END__