我一直在玩Jison,试图为一个非常简单的脚本语法创建一个"解释器"(这只是一个个人搞乱的项目,没有商业案例!)
我创建编译器已经有20年了,我想我只是没有掌握一些概念。
我想做的是给一个非常简单的语句程序,每行一个,到Jison,并得到Javascript语句流,然后执行动作。
我可能看错了-也许我需要在解析期间实际执行操作?这听起来不太对。
无论如何,我得到的是(我正在尝试这个在线顺便http://zaach.github.io/jison/try/)
/* lexical grammar */
%lex
%options case-insensitive
%%
s+ /* skip whitespace */
iss+ab return 'OCREATE'
iss+someb return 'ACREATE'
[_a-zA-Z]+[_a-zA-Z0-9]*b return 'IDENTIFIER'
<<EOF>> return 'EOF'
/lex
/* operator associations and precedence */
%start input
%% /* language grammar */
input
: /* empty */
| program EOF
{ return $1; }
;
program
: expression
{ $$ = $1; }
| program expression
{ $$ = $1; }
;
expression
: IDENTIFIER OCREATE IDENTIFIER
{ $$ = 'controller.createOne('' + $1 + '', '' + $3 + '');' }
| IDENTIFIER ACREATE IDENTIFIER
{ $$ = 'controller.createSeveral('' + $1 + '', '' + $3 + '');' }
;
输入:
basket is some apples
orange is a fruit
…我想:
controller.createSeveral('basket', 'apples');
controller.createOne('orange', 'fruit');
我得到的是:
controller.createSeveral('basket', 'apples');
这对我来说是有意义的,可以得到一个结果,但是我不知道该怎么做才能继续构建我的输出
问题出在program
的第二次生产中:
program
: expression
{ $$ = $1; }
| program expression
{ $$ = $1; }
第二个结果的意思是,基本上,"一个程序可以是一个(较短的)程序,后面跟着一个表达式,但它的语义值是较短程序的值。"
显然,您希望程序的值被表达式的值增广,因此您需要这样说:
program
: expression
{ $$ = $1; }
| program expression
{ $$ = $1.concat($2); }
(或$$ = $1 + $2
,如果你喜欢。)您可能需要一个换行符来提高可读性。)