用简单的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 而不是一个?
您期望 i
是 CHAR_SEQUENCE
但 CHAR_SEQUENCE
是 [A-Z]*
,也就是说,只有大写字母。你可能想要像 [A-Za-z_][A-Za-z_0-9]*
这样的东西。所以词法分析器根本无法识别 i
。
但是,它正在识别一个空 CHAR_SEQUENCE
。在 jison
中,与 flex
不同,可以匹配空字符串的模式会这样做,并且几乎应该始终避免。
我正在尝试创建一种简单的脚本语言。一开始我只想要
这样的东西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 而不是一个?
您期望 i
是 CHAR_SEQUENCE
但 CHAR_SEQUENCE
是 [A-Z]*
,也就是说,只有大写字母。你可能想要像 [A-Za-z_][A-Za-z_0-9]*
这样的东西。所以词法分析器根本无法识别 i
。
但是,它正在识别一个空 CHAR_SEQUENCE
。在 jison
中,与 flex
不同,可以匹配空字符串的模式会这样做,并且几乎应该始终避免。