package Pugs::Runtime::Match::HsBridge; use utf8; use strict; use warnings; use Pugs::Grammar::Base (); use Pugs::Compiler::Regex (); use base 'Pugs::Grammar::Base'; BEGIN { local $@; eval { require 'utf8_heavy.pl' } } use ops ($ENV{PUGS_SAFEMODE} ? (':default', 'binmode', 'entereval') : ()); sub __RUN__ { my $self = shift; my $match_text = shift; my $rule_text = shift; my %subrules = @_; while (my ($name, $body) = each %subrules) { my %sub_opts = (grammar => __PACKAGE__); ($1 and $sub_opts{$1} = 1) while $body =~ s/^:(\w*)\(1?\)\[(.*)\]\z/$2/s; Pugs::Compiler::Regex->reinstall( $name => $body, \%sub_opts ); } my %opts = (grammar => __PACKAGE__); ($1 and $opts{$1} = 1) while $rule_text =~ s/^:(\w*)\(1?\)\[(.*)\]\z/$2/s; # L modifier also implies that the anchoring"> if ( $opts{ratchet} ) { $rule_text = "^$rule_text" unless $opts{p} or $opts{pos}; $rule_text .= '$' unless $opts{c} or $opts{continue}; } local $SIG{__WARN__} = sub { 1 }; my $rule = Pugs::Compiler::Regex->compile( $rule_text, \%opts ); my $match = $rule->match( $match_text ); return $match->dump_hs; } sub __CMD__ { local $| = 1; # Command line shell interface - compatible with run_pge.pir if ($] >= 5.007) { binmode STDIN, ':utf8'; binmode STDOUT, ':utf8'; } my @subrules; while () { #/^(\w+) (\d+) (\d+)/ or die "Unrecognized command: $_"; /^(\w+) \d+ \d+/ or die "Unrecognized command: $_"; my $cmd = $1; # my ($cmd, $sz1, $sz2) = ($1, $2, $3); my $line1 = ; chomp($line1); $line1 =~ s{\\(?:(\\)|(n))}{$1 ? $1 : "\n"}eg; my $line2 = ; chomp($line2); $line2 =~ s{\\(?:(\\)|(n))}{$1 ? $1 : "\n"}eg; if ($cmd eq 'add_rule') { push @subrules, $line1, $line2; } elsif ($cmd eq 'match') { if (my $rv = eval { __PACKAGE__->__RUN__($line1, $line2, @subrules) }) { my $len = bytes::length($rv)+1; print "OK $len\n"; print "$rv\n\n"; } else { my $err = $@; $err =~ s/([\\\n])/\\$1/g; print "$err\n"; } @subrules = (); } else { die "Unrecognized command: $cmd"; } } } 1;