| 677 | | |
| 678 | | $pat =~ s/\\x(\w\w)/chr(hex($1))/eg; |
| 679 | | $pat =~ s/\\x\{(\w+)\}/chr(hex($1))/eg; |
| 680 | | } |
| 681 | | |
| 682 | | my $pat = "^(?:(" . join(")|(",@pats) . '))'; |
| 683 | | 1 while $pat =~ s/\(\?:\)\??//; |
| 684 | | 1 while $pat =~ s/([^\\])\(((\?:)?)\)/$1($2 !!!OOPS!!! )/; |
| 685 | | 1 while $pat =~ s/\[\]/[ !!!OOPS!!! ]/; |
| 686 | | |
| 687 | | $self->deb("TRE: ", $pat) if $DEBUG & DEBUG::autolexer; |
| 688 | | |
| 689 | | $self->deb("#FATES: ", 0+@$fates) if $DEBUG & DEBUG::autolexer; |
| 690 | | |
| 691 | | for my $i (0..@$fates-1) { |
| 692 | | $self->deb("\t", $i, ': ', $fates->[$i][3]) if $DEBUG & DEBUG::autolexer; |
| | 671 | } |
| | 672 | |
| | 673 | if ($DEBUG & DEBUG::autolexer) { |
| | 674 | $self->deb("#FATES: ", 0+@$fates); |
| | 675 | |
| | 676 | for my $i (0..@$fates-1) { |
| | 677 | $self->deb("\t", $i, ': ', $fates->[$i][3]); |
| | 678 | } |
| 789 | | ########################################## |
| 790 | | # No normal p5 match/subst below here!!! # |
| 791 | | ########################################## |
| 792 | | use re::engine::TRE; |
| 793 | | |
| 794 | | |
| 795 | | $self->deb("/ running tre match at @{[ pos($::ORIG) ]} /") if $DEBUG & DEBUG::lexer; |
| 796 | | $pat =~ s/\$\.\?/\$(?:.?)/; # XXX egregious hack to not interpolate $. |
| 797 | | |
| 798 | | # Try Real Hard to prevent TRE from recompiling $pat |
| 799 | | state $matcher = eval(do { my $prog = <<"END" . |
| 800 | | sub { |
| 801 | | my \$C = shift; |
| 802 | | my \$P = \$C->{_pos}; |
| 803 | | pos(\$::ORIG) = \$P; |
| 804 | | |
| 805 | | my \$result; |
| 806 | | if (\$::ORIG =~ m\0$pat\0xgc) { |
| 807 | | END |
| 808 | | <<'END'; $prog; }); |
| 809 | | my $max = @+ - 1; |
| 810 | | my $last = @- - 1; # ignore '$0' |
| 811 | | $C->deb("LAST: $last\n") if $DEBUG & DEBUG::lexer; |
| 812 | | $result = $fates->[$last-1]; |
| 813 | | if ($DEBUG) { |
| 814 | | for my $x (1 .. $max) { |
| 815 | | my $beg = $-[$x]; |
| 816 | | next unless defined $beg; |
| 817 | | my $end = $+[$x]; |
| 818 | | # return if $stoplen >= $end - $beg; |
| 819 | | my $f = $fates->[$x-1][3]; |
| 820 | | no strict 'refs'; |
| 821 | | if ($DEBUG & DEBUG::fates or ($DEBUG & DEBUG::lexer and $x == $last)) { |
| 822 | | my $p = $pats[$x-1] // '<nopat>'; |
| 823 | | $self->deb("\$$x: $beg..$end\t$$x\t ", |
| 824 | | $x == $last ? "====>" : "---->", |
| 825 | | " $f\t/$p/"); |
| 826 | | } |
| 827 | | } |
| 828 | | $C->deb("success at '", substr($::ORIG,$C->{_pos},10), "'") if $DEBUG & DEBUG::lexer; |
| 829 | | } |
| 830 | | my $tried = ""; |
| 831 | | vec($tried,$last-1,1) = 1 if $last; |
| 832 | | $_[0] = [$tried, pos($::ORIG) - $P, []]; |
| 833 | | } |
| 834 | | $result; |
| 835 | | }; |
| 836 | | END |
| 837 | | if ($@) { |
| 838 | | die; |
| 839 | | } |
| 840 | | my $result = $matcher->($C, @_); |
| 841 | | if ($result) { |
| 842 | | return $result; |
| 843 | | } |
| 844 | | else { |
| 845 | | $self->deb("NO LEXER MATCH") if $DEBUG & DEBUG::lexer; |
| 846 | | return; |
| 847 | | } |