How would Chomsky categorise this? (Update: Corrected c&p typo per Erez post below.)
#! perl -slw
use strict;
$|++;
my %ops = (
'+' => sub{ $_[ 0 ] + $_[ 1 ] },
'-' => sub{ $_[ 0 ] - $_[ 1 ] },
'*' => sub{ $_[ 0 ] * $_[ 1 ] },
'/' => sub{ $_[ 0 ] / $_[ 1 ] },
'**'=> sub{ $_[ 0 ] ** $_[ 1 ] },
);
my @presedence = (
qr[\*\*],
qr[\*|/],
qr[\+|-],
);
my $reVar = qr[[a-z]+];
my $reConst = qr[ [+-]? (?:\d+\.)? \d+ (?: [eE] [+-]? \d+ )? ]x;
my $reArg = qr[$reVar|$reConst];
my $reOps = qr[@{[ join '|', map{ quotemeta } keys %ops ]}];
my $reTokenise = qr[\s*($reArg)(?:\s*($reOps))?];
sub parseEvalExpr {
my $expr = shift;
if( $expr =~ m[$reOps \s+ $reArg \s+ $reOps]x ) {
for my $opset ( @presedence ) {
return "($expr)"
if $expr =~ s[ ( $reArg \s+ $opset \s+ $reArg ) ]{($1)
+}x;
}
}
my @tokens = $expr =~ m[$reTokenise]g;
pop @tokens unless defined $tokens[ $#tokens ];
while( @tokens > 1 ) {
( my( $arg1, $op, $arg2 ), @tokens ) = @tokens;
unshift @tokens, $ops{ $op }->( $arg1, $arg2 );
}
return $tokens[ 0 ];
}
while( <DATA> ) {
chomp;
my $testResult = eval;
printf "'$_' = ";
warn "Unbalanced parens '$_'" and next unless tr[(][] == tr[)][];
while( m[[()\s]] ) {
s[ \( ( [^()]+ ) \) ]{ parseEvalExpr( $1 ) }xe while m[[()]];
$_ = parseEvalExpr( $_ );
}
print;
printf STDERR "*** Discrepancy! Eval gets: %s\n", $testResult
unless $_ eq $testResult;
}
__DATA__
1 + 2
2 - 1
2 * 1
1 / 2
(((7 + 5) * (9 + 13)) / ((4 + 3) * (17 - 2 + 3)))
23 ** 2
1.1e10 ** -10
1 + 2 * 3
3 + 2 ** 2 ** 2 * 3
Output c:\test>expr_parser.pl
'1 + 2' = 3
'2 - 1' = 1
'2 * 1' = 2
'1 / 2' = 0.5
'(((7 + 5) * (9 + 13)) / ((4 + 3) * (17 - 2 + 3)))' = 2.0952380952381
'23 ** 2' = 529
'1.1e10 ** -10' = 3.85543289429532e-101
'1 + 2 * 3' = 7
'3 + 2 ** 2 ** 2 * 3' = 51
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
Read Where should I post X? if you're not absolutely sure you're posting in the right place.
Please read these before you post! —
Posts may use any of the Perl Monks Approved HTML tags:
- a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
Outside of code tags, you may need to use entities for some characters:
| |
For: |
|
Use: |
| & | | & |
| < | | < |
| > | | > |
| [ | | [ |
| ] | | ] |
Link using PerlMonks shortcuts! What shortcuts can I use for linking?
See Writeup Formatting Tips and other pages linked from there for more info.
|
|