# -*- perl -*- # Copyright (C) 2002-2006, The Perl Foundation. # $Id: Regex.pm 21249 2007-09-13 06:33:24Z paultcochrane $ package Regex; use strict; use warnings; use base 'Exporter'; BEGIN { @Regex::EXPORT_OK = qw(expr_to_tree tree_to_list list_to_pasm compile); } use Regex::State; use Regex::Parse; use Regex::TreeOptimize; use Regex::Optimize; use Regex::Rewrite; use Regex::CodeGen::IMCC; # Class method to get a global state object use vars qw($GLOBAL_STATE); sub global_state { return $GLOBAL_STATE ||= Regex::State->new(); } sub expr_to_tree { my ( $expr, $ctx, %options ) = @_; $options{state} ||= global_state(); my $parser = Regex::Parse->new(%options); return $parser->compile( $expr, $ctx ); } sub tree_to_list { my ( $tree, $ctx, $pass_label, $fail_label, %options ) = @_; $options{state} ||= global_state(); # Tree optimizations unless ( $options{'no-tree-optimize'} ) { my $opt1 = Regex::TreeOptimize->new(); $tree = $opt1->optimize_tree( $tree, $ctx ); } my $rewrite = Regex::Rewrite->new(%options); my $code = $rewrite->run( $tree, $ctx, $pass_label, $fail_label ); return $code if $options{'no-list-optimize'}; $ctx->{external_labels}{$pass_label} = 1; $ctx->{external_labels}{$fail_label} = 1; my $opt2 = Regex::Optimize->new(%options); $code->{code} = [ $opt2->optimize( $code->{code}, $ctx ) ]; return $code; } sub list_to_pasm { my ( $list_regex, $ctx, %options ) = @_; my $cgen; $options{state} ||= global_state(); $options{module} ||= "Regex::CodeGen::IMCC"; if ( $options{module} ne 'Regex::CodeGen::IMCC' ) { eval "use $options{module}"; die $@ if $@; } $cgen = $options{module}->new(%options); $cgen->init_context($ctx); return $cgen->output( $list_regex->{code}, $ctx ); } sub compile { my ( $expr, $ctx, $pass_label, $fail_label, %options ) = @_; $options{state} ||= global_state(); my $trees = expr_to_tree( $expr, $ctx, %options ); for my $tree (@$trees) { my $code = tree_to_list( $tree, $ctx, $pass_label, $fail_label, %options ); return list_to_pasm( $code, $ctx, %options ); } # Heh. Fixme. } 1; # Local Variables: # mode: cperl # cperl-indent-level: 4 # fill-column: 100 # End: # vim: expandtab shiftwidth=4: