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:[az]\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. :)
Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
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
You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)

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.