Reduce/reduce jison clike语法冲突
Reduce/reduce conflict in clike grammar in jison
我正在使用 Jison 包开发 clike 语言编译器。在我介绍 类 之前,我的表现非常好,因此 Type
现在可以成为 LITERAL
。这是一个简化的语法:
%lex
%%
\s+ /* skip whitespace */
int return 'INTEGER'
string return 'STRING'
boolean return 'BOOLEAN'
void return 'VOID'
[0-9]+ return 'NUMBER'
[a-zA-Z_][0-9a-zA-Z_]* return 'LITERAL'
"--" return 'DECR'
<<EOF>> return 'EOF'
"=" return '='
";" return ';'
/lex
%%
Program
: EOF
| Stmt EOF
;
Stmt
: Type Ident ';'
| Ident '=' NUMBER ';'
;
Type
: INTEGER
| STRING
| BOOLEAN
| LITERAL
| VOID
;
Ident
: LITERAL
;
和jison冲突:
Conflict in grammar: multiple actions possible when lookahead token is LITERAL in state 10
- reduce by rule: Ident -> LITERAL
- reduce by rule: Type -> LITERAL
Conflict in grammar: multiple actions possible when lookahead token is = in state 10
- reduce by rule: Ident -> LITERAL
- reduce by rule: Type -> LITERAL
States with conflicts:
State 10
Type -> LITERAL . #lookaheads= LITERAL =
Ident -> LITERAL . #lookaheads= LITERAL =
我发现了相当多的 similar question 没有答案,有人知道如何解决这个问题吗?
这显然是 jison 中的一个错误,因为语法肯定是 LALR(1),并且 bison 可以毫无问题地处理它。显然,jison 错误地计算了发生冲突的状态的前瞻性。 (更新:好像是bug 205,2014年1月报道的。)
如果您要求 jison 生成 LR(1) 解析器而不是 LALR(1) 语法,那么它会正确计算前瞻并且语法在没有警告的情况下通过。但是,我认为这不是一个可持续的解决方案。
这是另一个解决方法。 Decl
和 Assign
产品不是必需的; "fix" 是从 Type
中删除 LITERAL
并为其添加单独的作品。
Program
: EOF
| Stmt EOF
;
Decl
: Type Ident ';'
| LITERAL Ident ';'
;
Assign
: Ident '=' NUMBER ';'
;
Stmt
: Decl
| Assign
;
Type
: INTEGER
| STRING
| BOOLEAN
| VOID
;
Ident
: LITERAL
;
您可能要考虑识别多个语句:
Program
: EOF
| Stmts EOF
;
Stmts
: Stmt
| Stmts Stmt
;
我正在使用 Jison 包开发 clike 语言编译器。在我介绍 类 之前,我的表现非常好,因此 Type
现在可以成为 LITERAL
。这是一个简化的语法:
%lex
%%
\s+ /* skip whitespace */
int return 'INTEGER'
string return 'STRING'
boolean return 'BOOLEAN'
void return 'VOID'
[0-9]+ return 'NUMBER'
[a-zA-Z_][0-9a-zA-Z_]* return 'LITERAL'
"--" return 'DECR'
<<EOF>> return 'EOF'
"=" return '='
";" return ';'
/lex
%%
Program
: EOF
| Stmt EOF
;
Stmt
: Type Ident ';'
| Ident '=' NUMBER ';'
;
Type
: INTEGER
| STRING
| BOOLEAN
| LITERAL
| VOID
;
Ident
: LITERAL
;
和jison冲突:
Conflict in grammar: multiple actions possible when lookahead token is LITERAL in state 10
- reduce by rule: Ident -> LITERAL
- reduce by rule: Type -> LITERAL
Conflict in grammar: multiple actions possible when lookahead token is = in state 10
- reduce by rule: Ident -> LITERAL
- reduce by rule: Type -> LITERAL
States with conflicts:
State 10
Type -> LITERAL . #lookaheads= LITERAL =
Ident -> LITERAL . #lookaheads= LITERAL =
我发现了相当多的 similar question 没有答案,有人知道如何解决这个问题吗?
这显然是 jison 中的一个错误,因为语法肯定是 LALR(1),并且 bison 可以毫无问题地处理它。显然,jison 错误地计算了发生冲突的状态的前瞻性。 (更新:好像是bug 205,2014年1月报道的。)
如果您要求 jison 生成 LR(1) 解析器而不是 LALR(1) 语法,那么它会正确计算前瞻并且语法在没有警告的情况下通过。但是,我认为这不是一个可持续的解决方案。
这是另一个解决方法。 Decl
和 Assign
产品不是必需的; "fix" 是从 Type
中删除 LITERAL
并为其添加单独的作品。
Program
: EOF
| Stmt EOF
;
Decl
: Type Ident ';'
| LITERAL Ident ';'
;
Assign
: Ident '=' NUMBER ';'
;
Stmt
: Decl
| Assign
;
Type
: INTEGER
| STRING
| BOOLEAN
| VOID
;
Ident
: LITERAL
;
您可能要考虑识别多个语句:
Program
: EOF
| Stmts EOF
;
Stmts
: Stmt
| Stmts Stmt
;