File Coverage

blib/lib/Lingua/LinkParser/FindPath.pm
Criterion Covered Total %
statement 7 9 77.7
branch n/a
condition n/a
subroutine 3 3 100.0
pod n/a
total 10 12 83.3


line stmt bran cond sub pod time code
1             package Lingua::LinkParser::FindPath;
2              
3              
4 1     1   42404 use strict;
  1         3  
  1         57  
5              
6             our $VERSION = '0.01';
7              
8 1     1   875 use fields qw(parser sentence);
  1         1662  
  1         6  
9 1     1   1598 use Lingua::LinkParser;
  0            
  0            
10             sub new {
11             my $class = shift;
12             my %arg = @_;
13             if( ! ref $arg{parser} ){
14             require Lingua::LinkParser;
15             $arg{parser} = Lingua::LinkParser->new;
16             }
17             bless { parser => $arg{parser}, sentence => undef } => $class;
18             }
19              
20             sub sentence {
21             my $self = shift;
22             $self->{sentence} = ref $_[0] ? shift : $self->{parser}->create_sentence(shift);
23             return $self;
24             }
25              
26             sub clean_word {
27             $_[0] =~ s/(\[.\])?\..$//o;
28             $_[0];
29             }
30              
31              
32             sub find_start {
33             my $linkage = shift;
34             my $pattern = shift;
35             foreach ($linkage->words){
36             my $text = $_->text;
37             next if $text eq 'LEFT-WALL' || $text eq 'RIGHT-WALL';
38             $text = clean_word $text;
39             # print $text,$/;
40             if($text eq $pattern){
41             return $_;
42             }
43             }
44             }
45              
46             sub sig {
47             local $_ = shift;
48             if(ref($_) =~ /link$/i){
49             my $w = clean_word $_->linkword();
50             return $_->linkposition().':'.$w
51             }
52             else {
53             my $w = clean_word $_->text();
54             return $_->position().':'.$w
55             }
56             }
57              
58              
59              
60             sub find {
61             my $self = shift;
62             my ($start, $stop) = @_;
63             my $linkage = ($self->{sentence}->linkages)[0];
64             # print $self->{parser}->get_diagram($linkage);
65             my $found;
66             my @path;
67             my @stack;
68             my $link;
69             my $cur_ptr;
70             my $start = find_start($linkage, $start);
71             return unless ref $start;
72             push @stack, $start;
73             my %visited_word;
74             while(@stack and not $found){
75             if(not $cur_ptr){
76             $cur_ptr = $stack[-1];
77             # print "LINKS ", Dumper $cur_ptr;
78             $visited_word{$cur_ptr->position.':'.$cur_ptr->text} = 1;
79             push @{$link->{sig $cur_ptr}}, $cur_ptr->links;
80             push @path, $cur_ptr->text;
81             }
82             elsif($cur_ptr){
83             if(my $next_ptr = shift @{$link->{sig $cur_ptr}}){
84             ######################################################################
85             # Find label
86             ######################################################################
87             next if $next_ptr->linkword eq 'LEFT-WALL' || $next_ptr->linkword eq 'RIGHT-WALL';
88             push @path, $next_ptr->linklabel;
89             my $linkword = $next_ptr->linkword;
90             # print "WORDS ", Dumper $next_ptr;
91             $linkword = clean_word $linkword;
92             # print $next_ptr->linkposition.':'.$linkword,$/;
93             $visited_word{$next_ptr->linkposition.':'.$linkword} = 1;
94             push(@path, $linkword)&&last if $linkword eq $stop;
95              
96             ######################################################################
97             # Find word
98             ######################################################################
99             $next_ptr = $linkage->word($next_ptr->linkposition);
100             push @stack, $next_ptr;
101             my @links = $next_ptr->links;
102             # print Dumper \%visited_word;
103             @links =grep {!$visited_word{sig $_}} @links;
104             # print "LINKS ", Dumper \@links;
105             $cur_ptr = $stack[-1];
106             push @{$link->{sig $cur_ptr}}, @links;
107             push @path, $cur_ptr->text;
108             }
109             else {
110             pop @stack;
111             if(@path > 1){
112             pop @path;
113             pop @path;
114             }
115             $cur_ptr = $stack[-1];
116             }
117             }
118             if(!@stack){
119             last;
120             }
121             }
122             foreach my $i (reverse 1..$#path){
123             if($path[$i] eq $path[0]){
124             undef $path[$_] for 0..$i-1;
125             }
126             }
127              
128             @path = grep{$_} @path;
129             print Dumper \@path;
130             # @path = map{ clean_word $_} @path;
131             @path;
132             }
133              
134             sub find_as_string {
135             my $self = shift;
136             my $t = 0;
137             join q/ /, map{(++$t)%2 ? $_ : "<$_>"} $self->find(@_);
138             }
139              
140              
141             1;
142             __END__