#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;

my $input = $ARGV[0] // "2 * 3 + 4 # and a comment\n";

my @tokens;

$^R and push @tokens, [$^R, $1] while $^R = undef,
  $input =~ /( \#.*$
  | \s+
  | [+-] (?{'AddOp'})
  | [*\/] (?{'MulOp'})
  | \d+ (?{'Number'})
  | \( (?{'OpenParen'})
  | \) (?{'CloseParen'})
  | . (?{ die "Syntax error at position $-[0]\n" })
  )/gmx;

print Dumper \@tokens;