# # This software is Copyright 2005 by Elsevier Inc. You may use it # under the terms of the license at http://perl.plover.com/hop/LICENSE.txt . # ### ### DFSParser.pm ### ## Chapter 8 section 2.2 require "make-dfs-search"; sub make_parser_for_grammar { my ($start, $grammar, $target) = @_; my $is_nonterminal = sub { my $symbol = shift; exists $grammar->{$symbol}; }; my $is_interesting = sub { my $sentential_form = shift; my $i; for ($i=0; $i < @$sentential_form; $i++) { return 1 if $is_nonterminal->($sentential_form->[$i]); return if $i > $#$target; return if $sentential_form->[$i] ne $target->[$i]; } return @$sentential_form == @$target ; }; my $children = sub { my $sentential_form = shift; my $leftmost_nonterminal; my @children; for my $i (0 .. $#$sentential_form) { if ($is_nonterminal->($sentential_form->[$i])) { $leftmost_nonterminal = $i; last; } else { return if $i > $#$target; return if $target->[$i] ne $sentential_form->[$i]; } } return unless defined $leftmost_nonterminal; # no nonterminal symbols for my $production (@{$grammar->{$sentential_form->[$leftmost_nonterminal]}}) { my @child = @$sentential_form; splice @child, $leftmost_nonterminal, 1, @$production; push @children, \@child; } @children; }; return sub { make_dfs_search([$start], $children, $is_interesting ); }; } 1;