3

一直在和 Jison 一起玩,试图为一个非常简单的脚本语法创建一个“解释器”(这只是为了个人搞乱项目,没有商业案例!)

自从我不得不创建一个编译器已经过去了大约 20 年,我想我只是没有掌握一些概念。

我想做的是给 Jison 一个非常简单的语句程序,每行一个,然后返回一个 Javascript 语句流,然后执行这些操作。

我可能看错了 - 也许我需要在解析期间实际执行这些操作?不过这听起来不太对劲。

无论如何,我所拥有的是(我正在网上尝试这个http://zaach.github.io/jison/try/

/* lexical grammar */
%lex
%options case-insensitive
%%

\s+                        /* skip whitespace */
is\s+a\b                   return 'OCREATE'
is\s+some\b                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');

这种获得单一结果对我来说是有意义的,但我不知道如何才能在构建输出方面取得进展。

4

1 回答 1

4

问题出在您的第二次生产中program

program
    : expression
            { $$ = $1; }
    | program expression
            { $$ = $1; }

第二个产生式的意思基本上是“一个程序可以是一个(较短的)程序后跟一个表达式,但它的语义值是较短程序的值。”

您显然希望程序的值被表达式的值增加,所以您需要说:

program
    : expression
            { $$ = $1; }
    | program expression
            { $$ = $1.concat($2); }

(或者$$ = $1 + $2如果您愿意。并且您可能需要换行符以提高可读性。)

于 2014-05-28T15:34:58.860 回答