我正在尝试生成一个小型JavaScript解析器,它还包含一个小项目的类型变量。
幸运的是,jison已经提供了一个jscore.js,我只是根据自己的需要进行了调整。添加类型后,我遇到了reduce冲突。我把问题最小化到这个最小的JISON:
Jison:
%start SourceElements
%%
// This is up to become more complex soon
Type
: VAR
| IDENT
;
// Can be a list of statements
SourceElements
: Statement
| SourceElements Statement
;
// Either be a declaration or an expression
Statement
: VariableStatement
| ExprStatement
;
// Parses something like: MyType hello;
VariableStatement
: Type IDENT ";"
;
// Parases something like hello;
ExprStatement
: PrimaryExprNoBrace ";"
;
// Parses something like hello;
PrimaryExprNoBrace
: IDENT
;
实际上这个脚本除了解析两个语句之外什么也没做:
VariableStatement
IDENT IDENT ";"
ExpStatement
IDENT ";"
由于这是一个极度最小化的JISON脚本,我不能简单地替换" Type" be" IDENT" (顺便说一句。工作)。
生成解析器会引发以下冲突:
Conflict in grammar: multiple actions possible when lookahead token is IDENT in state 8
- reduce by rule: PrimaryExprNoBrace -> IDENT
- reduce by rule: Type -> IDENT
Conflict in grammar: multiple actions possible when lookahead token is ; in state 8
- reduce by rule: PrimaryExprNoBrace -> IDENT
- reduce by rule: Type -> IDENT
States with conflicts:
State 8
Type -> IDENT . #lookaheads= IDENT ;
PrimaryExprNoBrace -> IDENT . #lookaheads= IDENT ;
有没有办法解决这个冲突?
先谢谢你! 〜本杰明
答案 0 :(得分:1)
对我来说这看起来像是一个Jison bug。它抱怨这两个令牌序列的模糊性:
有问题的状态是在转移第一个IDENT令牌后达到的状态。 Jison观察到它需要减少该令牌,而且(它声称)它不知道是减少到Type还是PrimaryExpressionNoBrace。
但是Jison应该能够基于下一个标记进行区分:如果它是第二个IDENT,那么只有减少到一个类型可以导致有效的解析,而如果它是“;”那么只有减少到PrimaryExpressionNoBrace才能导致有效的解析。
你确定给定的输出符合给定的语法吗?可以添加规则或修改给定规则以产生诸如所描述的歧义之类的歧义。这看起来就像是一个简单的案例,我很惊讶杰森弄错了。但是,如果确实如此,那么您应该考虑提交错误报告。