[英]Jison parser generator, shift reduce grammar conflict, how to solve?
I'm currently working on visual basic converter using jison, and I have these conflicts in my grammar:我目前正在使用 jison 开发 Visual Basic 转换器,并且我的语法中有这些冲突:
Conflict in grammar: multiple actions possible when lookahead token is ELSE in state 11
- reduce by rule: If -> IfBlock
- shift token (then go to state 16)
Conflict in grammar: multiple actions possible when lookahead token is ELSE_IF in state 11
- reduce by rule: If -> IfBlock
- shift token (then go to state 17)
Conflict in grammar: multiple actions possible when lookahead token is TERMINATOR in state 27
- reduce by rule: IfBlock -> IF Expression THEN Body
- shift token (then go to state 13)
Conflict in grammar: multiple actions possible when lookahead token is TERMINATOR in state 29
- reduce by rule: IfBlock -> IfBlock ELSE_IF Expression THEN Body
- shift token (then go to state 13)
States with conflicts:
State 11
If -> IfBlock . #lookaheads= $end TERMINATOR IF_END ELSE ELSE_IF SUB_END
If -> IfBlock .ELSE Body IF_END #lookaheads= $end TERMINATOR IF_END ELSE ELSE_IF SUB_END
IfBlock -> IfBlock .ELSE_IF Expression THEN Body #lookaheads= $end ELSE ELSE_IF TERMINATOR SUB_END IF_END
State 27
IfBlock -> IF Expression THEN Body . #lookaheads= $end ELSE ELSE_IF TERMINATOR SUB_END IF_END
Body -> Body .TERMINATOR Line
Body -> Body .TERMINATOR
State 29
IfBlock -> IfBlock ELSE_IF Expression THEN Body . #lookaheads= $end ELSE ELSE_IF TERMINATOR SUB_END IF_END
Body -> Body .TERMINATOR Line
Body -> Body .TERMINATOR
Here is simplified version of my grammar (actions deleted):这是我的语法的简化版本(已删除操作):
const grammar = {
Root: [
[
''
],
[
'Body'
]
],
Body: [
[
'Line'
],
[
'Body TERMINATOR Line'
],
[ 'Body TERMINATOR' ]
],
Line: [ [ 'Expression' ], [ 'Statement' ] ],
Statement: [ [ 'Return' ], [ 'If' ] ],
Expression: [ [ 'Code' ] ],
Return: [
[
'RETURN Expression'
],
[
'RETURN'
]
],
Code: [
[
'SUB_START Identifier PARAM_START ParamList PARAM_END TERMINATOR Body SUB_END'
]
],
IfBlock: [
[
'IF Expression THEN Body'
],
[
'IfBlock ELSE_IF Expression THEN Body'
]
],
If: [
[ 'IfBlock' ],
[
'IfBlock ELSE Body IF_END'
]
]
}
The conflict is happening when I'm trying to implement a rule for If statement, it seems to conflict with the Body rule.当我尝试为 If 语句实施规则时发生冲突,它似乎与 Body 规则发生冲突。
I spent almost a day trying to solve it, but I can't.我花了将近一天的时间试图解决它,但我不能。 I know that the parser can look only one token ahead, but I can't figure out solution by myself.
我知道解析器只能向前看一个标记,但我无法自己找出解决方案。 And I'm bound to jison so I cannot use another parser generator.
而且我必须使用 jison,所以我不能使用另一个解析器生成器。 Is there any workaround for my grammar?
我的语法有什么解决方法吗?
Looking at these these productions:看看这些作品:
If: [
[ 'IfBlock' ],
[ 'IfBlock ELSE Body IF_END ']
]
It seems to me like the grammar is saying that an if
statement must be terminated by IF_END
only if it includes an else
clause.在我看来,语法似乎是说
if
语句只有在包含else
子句时才必须由IF_END
终止。 An if
which lacks an else
clause cannot be terminated by IF_END
.一
if
缺少了else
条款不能被终止IF_END
。
That's not my understanding of the syntax of visual basic.这不是我对visual basic语法的理解。
END_IF
is mandatory in the multiline syntax and is not used in the single line syntax. END_IF
在多行语法中是强制性的,在单行语法中不使用。
So you have two conflicts, because your If
production accepts some statements with END_IF
and some without:所以你有两个冲突,因为你的
If
生产接受一些带有END_IF
语句,而END_IF
一些则没有:
For if
statements without END_IF
, you have the classic "dangling else" ambiguity.对于没有
END_IF
if
语句,您会遇到经典的“悬空 else”歧义。
In addition, for multiline if
statements without END_IF
, the grammar provides no way to tell whether a following statement is part of the last clause in the if
statement or a new statement.此外,对于没有
END_IF
多行if
语句,语法无法判断后面的语句是if
语句的最后一个子句还是新语句的一部分。 (That's why multiline if
statements need END_IF
. (这就是为什么多行
if
语句需要END_IF
。
The "dangling else" ambiguity is relatively benign -- that is, the normal resolution which prefers shift to reduce will produce the correct result. “dangling else”的歧义是相对良性的——也就是说,喜欢 shift 到 reduce 的正常分辨率会产生正确的结果。 If you want to eliminate the error message, you can make the resolution explicit using precedence rules, giving
ELSE
and ELSE_IF
higher precedence than IF
.如果您想消除错误消息,您可以使用优先级规则明确解析,给予
ELSE
和ELSE_IF
比IF
更高的优先级。 To use this technique, you must make the IF
visible in the rules which depend on precedence, which basically means removing IF
from IfBLock
to leave you with:要使用此技术,您必须使
IF
在依赖于优先级的规则中可见,这基本上意味着从IfBLock
删除IF
以留下:
IfBlock: [
[ 'Expression THEN Body' ],
[ 'IfBlock ELSE_IF Expression THEN Body' ]
],
If: [
[ 'IF IfBlock' ],
[ 'IF IfBlock ELSE Body' ] // IF_END removed
]
You'll also need the precedence relations:您还需要优先关系:
[ 'left', 'IF' ],
[ 'left', 'ELSE', 'ELSE_IF' ]
That will more or less get you going on single-line if statements, except that you'll need to replace Block
with something which does not allow a TERMINATOR
.这或多或少会让你使用单行 if 语句,除了你需要用不允许
TERMINATOR
东西替换Block
。
For multiline if
statements, though, you'll need a different syntax:但是,对于多行
if
语句,您需要不同的语法:
The END_IF
is mandatory END_IF
是强制性的
There must be a TERMINATOR
after THEN
and ELSE
, and before ELSE
and END_IF
. THEN
和ELSE
, ELSE
和END_IF
之前必须有一个TERMINATOR
。 In other words, the blocks of statements in a multiline if
must start at the beginning of a line and be terminated with TERMINATOR
.换句话说,多行
if
的语句块必须从一行的开头开始并以TERMINATOR
。
These restrictions aren't just cosmetic: They are there because otherwise it is impossible to put a statement after a multiline if
statement, since without the END_IF
, any following statement would be added to the last THEN
or ELSE
clause.这些限制不仅仅是装饰性的:它们存在是因为否则不可能在多行
if
语句之后放置语句,因为没有END_IF
,任何后续语句都将添加到最后一个THEN
或ELSE
子句。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.