向bison/jison计算器语言添加功能 [英] Adding functions to bison/jison calculator language
问题描述
我正在尝试使用一些简单的功能来扩展 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:
-
expression_list
的规则现在将建立一个实际值列表,以与要调用的函数一起使用.
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屋!