I have a modified version of an ActionScript parser (written in AS, not parses AS) that supports custom functions, but not strings. It would probably be easy to add string support though. I'll upload it somewhere so you can get it at http://silentmatt.com/parser2.js http://silentmatt.com/parser3.js.
Edit: I added basic support for strings pretty easily. It doesn't support escape sequences and toJSFunction doesn't work, but it only took a few minutes to get it working. Changing the concatenation operator to "||" should be pretty easy too.
Here's how you would evaluate your example expressions:
js> var parser = new Parser();
js> parser.parse("3 * (2 + 1) - 1").evaluate();
8
js> parser.parse("2 * func(2; 2)").evaluate({ func:Math.pow });
8
js> function substr(s, start, end) { return s.substring(start, end); }
js> parser.parse("func('hello world'; 0; 5) + ' you'").evaluate({ func:substr });
hello you
I don't remember why I used semicolons as argument separators; I think it has something to do with differentiating between functions and built-in "operator" functions.
Another edit:
I've been playing with this a little, and now there's a version with better string support at http://silentmatt.com/parser3.js (toJSFunction works, and you can use standard JavaScript escape sequences). It also uses commas to separate arguments for all functions and ||
as the string concatenation operator instead of +
, which only does addition.