我已经完成了具有赋值功能的抽象语法树计算器的编写 但我不知道UDF是如何完成的。
我计划添加一个名为“funcasgn”的新功能 并通过定义函数进行解析。
但是定义函数中的参数(名称和大小)是任意的,当用户调用函数时,解析器必须为这些参数赋值。
有什么想法吗?
/* description: Parses end executes mathematical expressions. */
/* lexical grammar */
%lex
%%
\s+ /* skip whitespace */
\n /* skip newline */
[lL][eE][tT] return 'LET'
[a-zA-Z]+(_[a-zA-Z]+)?\b return 'NAME'
[0-9]+("."[0-9]+)?\b return 'NUMBER'
"*" return '*'
"/" return '/'
"-" return '-'
"+" return '+'
"^" return '^'
"(" return '('
")" return ')'
"," return ','
"{" return '{'
"}" return '}'
";" return ';'
"=" return '='
<<EOF>> return 'EOF'
. return 'INVALID'
/lex
/* operator associations and precedence */
%{
var refarray = new Array();
function valasgn(ast){
refarray.push({"name":ast[1],"value":eval(ast[2])});
return;
}
function eval(ast){
var v = 0;
switch(ast[0]){
case 'NUMBER':
v = ast[1];
break;
case '+':
v = eval(ast[1])+eval(ast[2]);
break;
case '-':
v = eval(ast[1])+eval(ast[2]);
break;
case '*':
v = eval(ast[1])*eval(ast[2]);
break;
case '/':
v = eval(ast[1])/eval(ast[2]);
break;
case 'REF':
var found = Boolean(false);
for(i=0;i<refarray.length;i++){
if (ast[1] == refarray[i].name) {
v = refarray[i].value; found = Boolean(true); break;
}
}
if (found == false) {
v = yyerror;
}
break;
}
return v;
}
%}
%ebnf
%left '+' '-'
%left '*' '/'
%left '^'
%right '='
%start calclist
%% /* language grammar */
calclist
: /* nothing */
| calclist valasgn ';'
{ valasgn($2);}
| calclist e EOF
{ typeof console !== 'undefined' ? console.log(eval($2)) : print(eval($2));
return eval($2);}
;
valasgn
: 'LET' nameasgn '=' e
{$$ = ['ASSIGN', $2, $4];}
;
nameasgn
: 'NAME'
{$$ = yytext;}
;
e
: e '+' e
{$$ = ['+', $1, $3];}
| e '-' e
{$$ = ['-', $1, $3];}
| e '*' e
{$$ = ['*', $1, $3];}
| e '/' e
{$$ = ['/', $1, $3];}
| e '^' e
{$$ = ['^', $1, $3];}
| '(' e ')'
{$$ = $2;}
| 'NUMBER'
{$$ = ['NUMBER', Number(yytext)];}
| 'NAME'
{$$ = ['REF', yytext];}
;