如何在JISON(Parser Generator)中创建用户定义的功能?

时间:2014-06-17 18:12:17

标签: javascript compiler-construction bison flex-lexer jison

我已经完成了具有赋值功能的抽象语法树计算器的编写 但我不知道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];}
    ;

0 个答案:

没有答案