###########################################
package MathLexer;
###########################################
use strict;
use Regexp::Common;
use Parse::Lex;

my @token = (
  OPPOW  => "[*][*]",
  OPSUB  => "[-]",
  OPADD  => "[+]",
  OPMULT => "[*]",
  OPDIV  => "[/]",
  FUNC   => "[a-zA-Z]\\w*\\(",
  ID     => "[a-zA-Z]\\w*",
  LEFTP  => "\\(",
  RIGHTP => "\\)",
  NUM    => "$RE{num}{real}",
  ERROR  => ".*", sub { 
               die qq(Can't lex "$_[1]") },
);

###########################################
sub new {
###########################################
    my($class, $string) = @_;

    my $lexer = Parse::Lex->new(@token);
    $lexer->skip("[\\s]");
    $lexer->from($string);

    my $self = { 
        lexer  => $lexer,
    };

    bless $self, $class;
}

###########################################
sub next {
###########################################
    my($self) = @_;

    my $tok = $self->{lexer}->next();
    return undef if $self->{lexer}->eoi();

    return $tok->name(), $tok->text();
}

1;
