Front page | perl.perl6.language |
Postings from July 2006
Re: Using Rules Today
From: Paul Seamons
July 3, 2006 16:13
Re: Using Rules Today
Message ID: firstname.lastname@example.org
> In any case, I was wondering if someone could provide me with an example of
> a mathematical expression parser (and evaluator).
> To properly compare to the others, it would need to handle the following
> +, - (left associative)
> *, /, % (left associative)
> ^ (right associative)
> handle parens 12 - (3 + 4)
> handle two functions sqrt() and abs() both of which must include the
> If someone has time to do this for me, I would be appreciative. It might
> also serve as example documentation or cookbook ideas.
> I am specifically interested in examples that can be run in Perl 5 today
> without needing Pugs or Parrot.
It isn't specifically a parser designed for general language parsing, but
CGI::Ex::Template does have a mathematical expression parser. The parser is
located near the end of the parse_expr method. The output of the parse_expr
is an opcode data structure that can be played out through the play_expr
The basic functionality is that a chain of operators is tokenized into a
single array. The apply_precedence method is then used to split the array
into the optree based upon the precedence and associativity of the operators.
The following is a sampling of the resulting "optrees" for the given
expressions (taken from the perldoc):
1 + 2 => [ \ [ '+', 1, 2 ], 0]
a + b => [ \ [ '+', ['a', 0], ['b', 0] ], 0 ]
a * (b + c) => [ \ [ '*', ['a', 0], [ \ ['+', ['b', 0], ['c', 0]], 0 ]],
(a + b) => [ \ [ '+', ['a', 0], ['b', 0] ]], 0 ]
(a + b) * c => [ \ [ '*', [ \ [ '+', ['a', 0], ['b', 0] ], 0 ], ['c',
0] ], 0 ]
perl -e 'use CGI::Ex::Template; $s=CGI::Ex::Template::dump_parse("3 * 4 ** 2 +
5"); $s =~ s/\s+/ /g; print "$s\n"'
$VAR1 = [ \[ '+', [ \[ '*', '3', [ \[ '**', '4', '2' ], 0 ] ], 0 ], '5' ],
I apologize that the expression parsing isn't a little more abstracted for
you, but the result should be usable. Also, the parse_expr is designed for
also parsing variable names in the TT2 language, so the first portion of the
method applies variable names. The entire thing could be cut down
considerably if all you want to parse is math (no variables).