Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?

Re^2: Operator Precedence Parser

by bart (Canon)
on Jun 11, 2006 at 16:28 UTC ( #554691=note: print w/replies, xml ) Need Help??

in reply to Re: Operator Precedence Parser
in thread Operator Precedence Parser

If your parser can easily be extended to handle function calls I'll have a go at adapting it for my application.
I said it would be easy, didn't I? Well I've got to put my money (er, code) where my mouth is, so I adapted it to process function calls. With this global spec, which defines 2 functions:
my %function = ( sumsq => sub { my $sum = 0; foreach(@_) { $sum += $_*$_; } return $ +sum; }, # sum of squares sqrt => sub { return sqrt shift; }, );
I added this piece in parse_value(), just in front of the code to handle variables:
if(/\G((?i:[a-z]\w*))\s*\(/gc) { # function '(' my $function = $1; $function{$function} or die sprintf "Undefined function '$func +tion' called at: \"%s\"", where(); my @arg; unless(/\G\s*(?=\))/gc) { while(1){ my($value) = parse_expr() or die sprintf "Expression e +xpected at: \"%s\"", where(); push @arg, $value; /\G\s*,/gc or last; } } /\G\s+/gc; /\G\)/gc or die sprintf "Parse error: ')' expected at: \"%s\"" +, where(); trace(sprintf "function '$function' called with %d argument%s" +, scalar @arg, @arg==1 ? "" : "s"); return $function{$function}->(@arg); }
and with the data string "sumsq(3,2+2)*sqrt(36)", the output is:
Line 29 "·sumsq(3,2+2)*sqrt(36)" Line 29 "sumsq(·3,2+2)*sqrt(36)" Line 31 "sumsq(3·,2+2)*sqrt(36)" value=3 Line 29 "sumsq(3,·2+2)*sqrt(36)" Line 31 "sumsq(3,2·+2)*sqrt(36)" value=2 Line 36 "sumsq(3,2+·2)*sqrt(36)" op=+ Line 29 "sumsq(3,2+·2)*sqrt(36)" Line 31 "sumsq(3,2+2·)*sqrt(36)" value=2 Line 43 "sumsq(3,2+2·)*sqrt(36)" popping 2 + Line 45 "sumsq(3,2+2·)*sqrt(36)" result = 4 Line 85 "sumsq(3,2+2)·*sqrt(36)" function 'sumsq' called with 2 argume +nts Line 31 "sumsq(3,2+2)·*sqrt(36)" value=25 Line 36 "sumsq(3,2+2)*·sqrt(36)" op=* Line 29 "sumsq(3,2+2)*·sqrt(36)" Line 29 "sumsq(3,2+2)*sqrt(·36)" Line 31 "sumsq(3,2+2)*sqrt(36·)" value=36 Line 85 "sumsq(3,2+2)*sqrt(36)·" function 'sqrt' called with 1 argumen +t Line 31 "sumsq(3,2+2)*sqrt(36)·" value=6 Line 43 "sumsq(3,2+2)*sqrt(36)·" popping 25 * Line 45 "sumsq(3,2+2)*sqrt(36)·" result = 150 150 Stack: This value is never affected

It seems to work fine, was finished in something like 1/4 hour, and it definitely doesn't take hundreds of lines of code. :)

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://554691]
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others chanting in the Monastery: (9)
As of 2017-12-14 17:49 GMT
Find Nodes?
    Voting Booth?
    What programming language do you hate the most?

    Results (400 votes). Check out past polls.