#!/usr/bin/perl use Template::Alloy; my $ta = Template::Alloy->new; $ta->_vars->{'func'} = sub { local $" = ', '; "You passed me (@_)" }; $ta->_vars->{'a'} = 3; $ta->_vars->{'b'} = 4; $ta->define_operator({ type => 'left', # actually associativiy precedence => 85, # same as '+' in $Template::Alloy::OPERATORS table symbols => ['+++'], play_sub => sub { int($_[0]) + int($_[1]) }, }); for my $expr ( '1 + 2', '1 + 2 * 3', '(1 + 2) * 3', '2.7e+10 * 3.0e-9', # scientific 'a + b', # variables 'func(1 + 2, 3)', # functions '1.2 +++ 3.4 * 2', # custom ops '1 ? 2 : 3', 'a + (b', '3 + 4 foobar', ) { my $copy = $expr; print "--------------------\n"; print "- expr: $expr\n"; print "- outp: ".eval{ $ta->play_expr($ta->parse_expr(\$copy)) }."\n"; if ($@) { print "- err : $@\n"; } else { print "- err : Failed to consume entire string\n" if pos $copy != length $expr; print "- tree: ".Template::Alloy->dump_parse_expr(\$expr)."\n"; } } #### -------------------- - expr: 1 + 2 - outp: 3 - tree: [[undef, '+', 1, 2], 0] -------------------- - expr: 1 + 2 * 3 - outp: 7 - tree: [[undef, '+', 1, [[undef, '*', 2, 3], 0]], 0] -------------------- - expr: (1 + 2) * 3 - outp: 9 - tree: [[undef, '*', [[undef, '+', 1, 2], 0], 3], 0] -------------------- - expr: 2.7e+10 * 3.0e-9 - outp: 81 - tree: [[undef, '*', 27000000000, '3e-09'], 0] -------------------- - expr: a + b - outp: 7 - tree: [[undef, '+', ['a', 0], ['b', 0]], 0] -------------------- - expr: func(1 + 2, 3) - outp: You passed me (3, 3) - tree: ['func', [[[undef, '+', 1, 2], 0], 3]] -------------------- - expr: 1.2 +++ 3.4 * 2 - outp: 7 - tree: [[undef, '+++', '1.2', [[undef, '*', '3.4', 2], 0]], 0] -------------------- - expr: 1 ? 2 : 3 - outp: 2 - tree: [[undef, '?', 1, 2, 3], 0] -------------------- - expr: a + (b - outp: - err : parse.missing.paren error - Missing close ) in group (At char 6) -------------------- - expr: 3 + 4 foobar - outp: 7 - err : Failed to consume entire string - tree: [[undef, '+', 3, 4], 0]