javascript-将功能添加到bison / jison计算器语言
作者:互联网
我正在尝试通过一些简单的功能来扩展Jison calculator example.我对解析和bison / jison相当陌生,但这是到目前为止的内容:
/* 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);}
;
问题在于,函数只会传递一个参数给它们.例如:
test(2) -> 4
pow(2,3) -> null
实际上,如果您用console.log记录pow的参数,似乎b甚至都没有定义.为什么在将整个表达式列表发送到函数之前不解析整个表达式列表?
解决方法:
以下代码完成了您所要求的.重点:
>现在,expression_list的规则将构建一个实际的值列表,以与要调用的函数一起使用.
>由expression_list构建的列表将传递给应用,以便它们成为被调用函数的参数(未定义是将其值设置为undefined的第一个参数).
>我在表达操作中添加了console.log指令,以便在命令行运行生成的解析器时可以看到发生了什么.
>我已经将funcs的定义移到了最开始.吉森只是没有将其放在最终文件中的正确位置.
这是最终文件:
%{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,javascript,parsing,jison 来源: https://codeday.me/bug/20191121/2049213.html