用简单的jison语法解析错误

Parse error with simple jison grammar

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

这样的东西
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 < .length; i++)
                {
                    [i]();
                }
            };
        }
    ;

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

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[].toTellrawExtra());
                t.tell(new Entities.Player("@a"));
            };
        }
    ;

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

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

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

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

                (vars[], );
            };
        }
    ;

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

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

我收到这个错误

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

这让我很困惑:/没有一开始就需要操作员的规则。唯一期望运算符的规则是 AssignStatements,但它们都期望 CHAR_SQUENCE 作为第一个对象。

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

有没有可能当你使用

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

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

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

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