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

自创建编译器以来已经有20年了,我认为我只是不掌握某些概念。

我想做的是给Jison提供一个非常简单的语句程序(每行一个),并返回一串Javascript语句,然后执行 Action 。

我可能正在看这个错误-也许我需要在解析期间实际执行操作?这听起来不对。

无论如何,我得到的是(我正在网上尝试这个btw 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');

获得单个结果对我来说很有意义,但是我不知道该如何做才能建立输出。

最佳答案

问题出在您的第二个产品program中:

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

第二种说法基本上是“一个程序可以是一个(较短的)程序,后跟一个表达式,但是它的语义值(value)是较短的程序的值”。

您显然希望通过表达式的值来增加程序的值,所以您需要这样说:
program
    : expression
            { $$ = $1; }
    | program expression
            { $$ = $1.concat($2); }

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

09-25 15:39