向bison/jison计算器语言添加功能 [英] Adding functions to bison/jison calculator language

查看:150
本文介绍了向bison/jison计算器语言添加功能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用一些简单的功能来扩展 Jison计算器示例.我对解析和bison/jison还是比较陌生,但这只是到目前为止的内容:

I'm trying to expand the Jison calculator example with some simple functions. I'm rather new to parsing and bison/jison, but this is a bit of what I have so far:

/* lexical grammar */
%lex

%{
  var funcs = {
    pow: function(a, b) { return Math.pow(a, b); },
    test: function(a) { return a*2; }
  }
%}

%%

\s+                   /* skip whitespace */
[0-9]+("."[0-9]+)?\b  return 'NUMBER'
[a-zA-Z]+             return 'NAME'
","                   return ','
"*"                   return '*'
"("                   return '('
")"                   return ')'
<<EOF>>               return 'EOF'
.                     return 'INVALID'

/lex

%start expressions

%% /* language grammar */
expressions
    : e EOF
      { return $1; }
    ;

expression_list
    : expression_list ',' e
    | e
    ;

e
    : e '*' e
        {$$ = $1*$3;}
    | '(' e ')'
        {$$ = $2;}
    | NUMBER
        {$$ = Number(yytext);}
    | NAME '(' expression_list ')'
        {$$ = funcs[$NAME]($expression_list);}
    ;

问题在于,函数仅将一个参数传递给它们.例如:

The problem is that functions are only getting one argument passed to them. For example:

test(2) -> 4
pow(2,3) -> null

实际上,如果您console.log pow的参数,则似乎甚至没有定义b.为什么在将整个表达式列表发送到函数之前不解析整个表达式列表?

In fact, if you console.log the arguments of pow, it appears b isn't even defined. Why isn't it parsing the whole expression list before sending it to the function?

推荐答案

以下代码可满足您的要求.重点:

The following code does what you asked for. Salient points:

  1. expression_list的规则现在将建立一个实际值列表,以与要调用的函数一起使用.

  1. The rules for expression_list now build an actual list of values to be used with the functions being called.

expression_list构建的列表传递给apply,以便它们成为被调用函数的参数(undefined作为将this的值设置为<的第一个参数c6>).

The list built by expression_list are passed to apply so that they become the arguments of the function being called (undefined is there as the first argument to set the value of this to undefined).

我已经在expression的动作中添加了console.log指令,以便在命令行运行生成的解析器时可以看到发生了什么.

I've added a console.log instruction to the actions for expression so that I'd see what is going on when I run the resulting parser at the command line.

我已经将funcs的定义移到了最开始.吉森(Jison)只是没有将它放在最终文件中的正确位置.

I've moved the definition of funcs to the very start. Where it was jison was just not putting it in the right place in the final file.

这是最终文件:

%{var funcs = {
    pow: function(a, b) { return Math.pow(a, b); },
    test: function(a) { return a*2; }
  }
%}

/* lexical grammar */
%lex

%%

\s+                   /* skip whitespace */
[0-9]+("."[0-9]+)?\b  return 'NUMBER'
[a-zA-Z]+             return 'NAME'
","                   return ','
"*"                   return '*'
"("                   return '('
")"                   return ')'
<<EOF>>               return 'EOF'
.                     return 'INVALID'

/lex

%start expressions

%% /* language grammar */
expressions
    : e EOF
      { console.log($1); return $1; }
    ;

expression_list
    : expression_list ',' e
      { $$ = $1.concat([$3]); }
    | e
      { $$ = [$1]; }
    ;

e
    : e '*' e
        {$$ = $1*$3;}
    | '(' e ')'
        {$$ = $2;}
    | NUMBER
        {$$ = Number(yytext);}
    | NAME '(' expression_list ')'
        {$$ = funcs[$NAME].apply(undefined, $expression_list);}
    ;

这篇关于向bison/jison计算器语言添加功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆