I have started playing with ANTL3, I found it very cool, it's support for multiple languages is awesome.
Right now I am experimenting with Javascript. I've extended the grammar found @ antlr3 - Generating a Parse Tree
I would allow my user to call the functions defined by him in javascript such as:
function sum(args){
    var s=0;
    for(var i=0;i<args.length;i++)
        s+=args[i];
    return s;
}
function avg(args){
    var s=sum(args);
    return s/args.length;
}
Please find my grammar:
grammar Excel;
options {
  output=AST;
  language=JavaScript;
}
tokens {
    // define pseudo-operations
    FUNC;
    CALL;
}
parse
  :  exp EOF -> exp
  ;
exp
  :  orExp
  ;
orExp
  :  andExp (OR^ andExp)*
  ;
andExp
  :  eqExp (AND^ eqExp)*
  ;
eqExp
    : relExp (( EQUALS | NOTEQUALS)^ relExp)*
    ;
relExp
: addExp ( (LT^|LTEQ^|GT^|GTEQ^) addExp)*
;
addExp
: multExp ( (PLUS^| MINUS^) multExp)*
;
multExp 
: unaryExp (( MULT^ | DIV^ | MOD^ |POW^| IS^) unaryExp)*
;
unaryExp
  :  NOT atom -> ^(NOT atom)
  |  atom
  ;
atom
  :  TRUE
  |  FALSE
  |  INT
  |  FLOAT
  |  function
  |  '(' exp ')' -> exp
  ;
POW : '^';
DIV : '/';
MOD : '%';
MULT : '*';
PLUS : '+';
MINUS : '-';
LT   : '<';
LTEQ : '<=';
GT   : '>';
GTEQ : '>=';
EQUALS : '==';
NOTEQUALS : '<>';
INT    : '0'..'9'+;
FLOAT   :   ('0'..'9')* '.' ('0'..'9')+;
OR     : 'or' ;
AND    : 'and' ;
IS     : 'is' ;
NOT    : 'not' ;
TRUE   : 'true' ;
FALSE  : 'false' ;
function
    :   IDENT '(' ( exp (',' exp)* )? ')' -> ^(FUNC IDENT exp*)
;
IDENT
:   ('a'..'z' | 'A'..'Z') ('a'..'z' | 'A'..'Z' |'0'..'9')*
;   
SPACE  : (' ' | '\t' | '\r' | '\n') {$channel=HIDDEN;} ;
Tree Grammar:
tree grammar ExcelWalker;
options {
  tokenVocab=Excel;
  ASTLabelType=CommonTree;
  language=JavaScript;
}
// `walk` returns a string
walk returns [expr]
  :  exp {expr = $exp.expr;} //($exp.expr == 1) ? 'True' : 'False';}
  //|  ^(FUNC IDENT a=exp*)
 ;
// `exp` returns either 1 (true) or 0 (false)
exp returns [expr]
  :  ^(OR  a=exp b=exp) {expr = ($a.expr == 1 || $b.expr == 1) ? true : false;}
  |  ^(AND a=exp b=exp) {expr = ($a.expr == 1 && $b.expr == 1) ? true : false;}
  |  ^(IS  a=exp b=exp) {expr = ($a.expr == $b.expr) ? true : false;}
  |  ^(NOT a=exp)       {expr = ($a.expr == 1) ? false : true;}
  |  ^(LT a=exp b=exp) { expr = a<b;}
  |  ^(LTEQ a=exp b=exp) { expr = a<=b;}
  |  ^(GT a=exp b=exp) { expr = a>b;}
  |  ^(GTEQ a=exp b=exp) { expr = a>=b;}  
  |  ^(PLUS a=exp b=exp) { expr = a+b;}
  |  ^(MINUS a=exp b=exp) { expr = a-b;}
  |  ^(MULT a=exp b=exp){ expr = a*b;}
  |  ^(DIV a=exp b=exp) { expr = a/b;}
  |  ^(MOD a=exp b=exp) { expr = a \% b;}
  |  ^(POW a=exp b=exp) { expr = Math.pow(a,b); }  
  |  call               { expr=$call.value;}
  |  TRUE               {expr = true;}
  |  FALSE              {expr = false;}
  |  INT                { expr = $INT.text-0;}
  |  FLOAT              { expr = $FLOAT.text-0;}
  ;
call returns [value]
: ^(FUNC IDENT a=exp*) { 
    console.info($FUNC.toStringTree());
    var fn=$IDENT.text;
    var params=[];
    for(var i=1;i<$FUNC.getChildCount();i++)
        params.push($FUNC.getChild(i));
    var method=fn+'(['+params+'])';
    alert(method);
    var evalResult=eval(method);
    value=evalResult;
    alert(value);
    //alert('function '+fn+' with params '+params.length+' will be called');
    //alert($FUNC.getChildCount());alert($IDENT.text);alert(a.toString());
}
;
My Test Rig:
sum(2,3) produces 5
avg(1,2,3) produces 2
however when I am trying to evaluate:
sum(2+3,4+7,sum(4,5,6),avg(4,4,4,4))
It's getting failed.
Please help me to write proper AST walker to evaluate mutli-value functions.
Thanks in Advance.