使用简单的jison语法解析错误

时间:2015-02-09 15:39:22

标签: javascript parsing grammar jison

我正在尝试创建一个简单的脚本语言。一开始我只想要像

这样的东西
i = 5;
i += 3;
out(i);

所以我为jison创建了以下语法:

%lex
%%

\s+                  { /* ignore */ }

"="                  { return '='; }
"+="                 { return '+='; }
"-="                 { return '-='; }
"*="                 { return '*='; }
"/="                 { return '/='; }

"."                  { return '.'; }
"("                  { return '('; }
")"                  { return ')'; }
"{"                  { return '{'; }
"}"                  { return '}'; }

[0-9]+               { return 'NUMBER'; }
[A-Z]*               { return 'CHAR_SEQUENCE'; }

<<EOF>>              { return 'EOF'; }

/lex

%%

Program
    : StatementList EOF
        {
            return function()
            {
                for(var i = 0; i < $1.length; i++)
                {
                    $1[i]();
                }
            };
        }
    ;

StatementList
    : StatementList Statement
        { $$ = $1.concat($2); }
    |
        { $$ = []; }
    ;

Statement
    : AssignStatement
    | VariableOutput
    ;

Operator
    : "="
        { $$ = function(left, right) { left.set(right); }; }
    | "+="
        { $$ = function(left, right) { left.add(right); }; }
    | "-="
        { $$ = function(left, right) { left.remove(right); }; }
    | "*="
        { $$ = function(left, right) { left.multiplicate(right); }; }
    | "/="
        { $$ = function(left, right) { left.divide(right); }; }
    ;


VariableOutput
    : 'out(' CHAR_SEQUENCE ')' ';'
        {
            $$ = function()
            {
                var t = new Tellraw("Output: ");
                t.extra.push(vars[$1].toTellrawExtra());
                t.tell(new Entities.Player("@a"));
            };
        }
    ;

AssignStatement
    : CHAR_SEQUENCE Operator CHAR_SEQUENCE ';'
        {
            $$ = function()
            {
                Util.assert(typeof vars[$3] != 'undefined', "Unknown identifier '"+$3+"'");

                if(typeof vars[$1] == 'undefined')
                    vars[$1] = vars[$3].constructor.call();

                $2(vars[$1], vars[$3]);
            };
        }
    | CHAR_SEQUENCE Operator '"' CHAR_SEQUENCE '"' ';'
        {
            $$ = function()
            {
                if(typeof vars[$1] == 'undefined')
                    vars[$1] = new Runtime.String($3);

                $2(vars[$1], $3);
            };
        }
    | CHAR_SEQUENCE Operator NUMBER ';'
        {
            $$ = function()
            {
                if(typeof vars[$1] == 'undefined')
                    vars[$1] = new Runtime.Integer($3);

                $2(vars[$1], $3);
            };
        }
    ;

它生成解析器而不会抱怨语法。我的问题是当我做的时候

parser.parse('i=5;out(i);')();

我收到此错误

Parse error on line 1:
i = 5;out(i);
^
Expecting '=', '+=', '-=', '*=', '/=', got 'CHAR_SEQUENCE'

这完全让我感到困惑:/没有规则首先要求运营商。期望运算符的唯一规则是AssignStatements,但它们都期望CHAR_SQUENCE作为第一个对象。

我做错了吗?或者为什么它不起作用? 如果您需要任何进一步的信息,请随时询问:)

2 个答案:

答案 0 :(得分:1)

您希望iCHAR_SEQUENCECHAR_SEQUENCE[A-Z]*,也就是说,只有大写字母。你可能想要像[A-Za-z_][A-Za-z_0-9]*这样的东西。因此,词法分析器根本无法识别i

但是,它正在识别空CHAR_SEQUENCE。在jison中,与flex不同,可以匹配空字符串的模式会这样做,并且应该几乎总是避免使用。

答案 1 :(得分:0)

使用时可能

[A-Z]*               { return 'CHAR_SEQUENCE'; }

使用*而不是+,您将空字符串视为CHAR_SEQUENCE,然后解析器找到两个CHAR_SEQUENCE而不只是一个?

相关问题