Affix-Infix2Postfix

 view release on metacpan or  search on metacpan

Infix2Postfix.pm  view on Meta::CPAN

package Affix::Infix2Postfix;

use strict;
use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);

#use Data::Dumper;

require Exporter;
require AutoLoader;

@ISA = qw(Exporter AutoLoader);
# Items to export into callers namespace by default. Note: do not export
# names by default without a very good reason. Use EXPORT_OK instead.
# Do not simply export all your public functions/methods/constants.
@EXPORT = qw(
	
);
$VERSION = '0.03';


sub new { 
    my $class = shift;
    my %hsh=@_;
    my $self=\%hsh; 
    my $op;

# add some check code here

# create regular expressions
# combined lists insert defaults etc.

    for $op (@{$self->{'ops'}}) {
      if (!exists( $op->{'type'} )) { $op->{'type'}='binary'; }
      if (!exists( $op->{'assoc'} )) { $op->{'assoc'}='left'; }
      if (!exists( $op->{'trans'} )) { $op->{'trans'}=$op->{'op'}; }
    }

    @{$self->{'opr'}}=map { $_->{'op'} } @{$self->{'ops'}};

    @{$self->{'tokens'}}=(@{$self->{'opr'}},@{$self->{'func'}},@{$self->{'vars'}},@{$self->{'grouping'}});

    $self->{'varre'}=join('|',map { quotemeta($_) } @{$self->{'vars'}});
    $self->{'funcre'}=join('|',map { quotemeta($_) } @{$self->{'func'}});

    $self->{'numre'}='[+-]?(?:\d+\.?\d*|\.\d+)(?:[eE][+-]?\d+)?';

    $self->{'re'}=join('|',(map { quotemeta($_).'(?!'.quotemeta($_).')' } @{$self->{'tokens'}}),$self->{'numre'});
    $self->{'ree'}=$self->{'re'}.'|.+?';
    $self->{ERRSTR}='';
    bless $self,$class;
    return $self;
}

sub tokenize {
    my $self=shift;
    my $str=shift;
    my $ree=$self->{'ree'};
#    print "ree: $ree\n";
    return ( $str =~ m/($ree)/g ); # tokenize
#    return ( $str =~ m/($ree)/xg ); # tokenize
}

# Returns the indices of non recognized tokens

sub verify {
    my $self=shift;
    my $re=$self->{'re'};
    my @matches=@_;
    return grep { $matches[$_] !~ /^$re$/ } 0..$#matches;
}

sub translate {
    my $self=shift;
    my $str=shift;
    my (@matches,@errors,@res);
    
    @matches=$self->tokenize($str);
    @errors=$self->verify(@matches);

    if (@errors) {
      $self->{ERRSTR}='Bad tokens: '.join(' ',@matches[@errors]);
      return undef;
    }

    @res=$self->elist(@matches);
    return @res;
}


sub elist {
  my $self=shift;
  my (@poss,$i,$cop); # possible breaks
  my $b=0;
  my $numre=$self->{'numre'};
  my $varre=$self->{'varre'};
  my (%func,@func,@ops,$un,$fn,$as,$rop,$op,$bi,$bd,$las,@trlist);
  @func=@{$self->{'func'}};
  @func{@func}=1..@func;
  @ops=@{$self->{'ops'}};

#    print Dumper(\%func);
#    print "elist: ",join(" ",map { "$_" } @_ ),"\n";

#    the only single elements should be numbers or vars 

  if ($#_ == 0) {
    if ( $_[0] =~ m/^($numre|$varre)$/ ) {
      return $_[0];
    } else {
      die "Single element '$_[0]' wrong\n";



( run in 3.551 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )