4

我正在使用 Jison 编写解析器。这是我的语法:

{
    "program": [
        ["statements EOF", "return $1;"]
    ],
    "statements": [
        ["statement",            "$$ = $1;"],
        ["statements statement", "$$ = $1 + '\\n' + $2;"]
    ],
    "statement": [
        ["expression NEWLINE", "$$ = $1 + ';';"]
    ],
    "expression": [
        ["NUMBER",                "$$ = yytext;"],
        ["expression expression", "$$ = $1 + ', ' + $2;"]
    ]
}

但是,当我运行它时,我收到以下错误消息:

Conflict in grammar: multiple actions possible when lookahead token is NUMBER in
state 9
- reduce by rule: expression -> expression expression
- shift token (then go to state 5)

States with conflicts:
State 9
  expression -> expression expression . #lookaheads= NEWLINE NUMBER
  expression -> expression .expression
  expression -> .NUMBER
  expression -> .expression expression

我应该如何处理此调试消息?你会如何用简单的英语解释这条信息?中的期间expression -> expression expression .是什么意思?.expression和是什么.NUMBER?它们expression分别有什么不同NUMBER

4

1 回答 1

10

我应该如何处理此调试消息?

语法冲突意味着解析器可以达到可以遵循多个规则的状态,但是它没有足够的信息来确定要遵循哪个规则(或者更糟糕的是,语法是模棱两可的)。您必须调整语法以消除冲突。通常,这只是需要练习才能正确。

表达式中的句点 -> 表达式表达式。意思是?

句点代表解析器的位置。因此,在该规则中,解析器将只解析两个表达式,并且现在处于状态 9。当句点位于规则的末尾时,这意味着该规则可以“减少”,并分组为单个expression非在这种情况下是终端。但是,它只能在下一个标记(前瞻)是 aNEWLINE或 a时减少NUMBER

expression -> .NUMBER中,解析器刚刚遇到一个 NUMBER 标记,它可以“转移”它,然后转移到一个新状态。

NUMBER发生冲突是因为解析器在遇到令牌时可以减少或移位。

编辑:为了解决您的冲突,我们需要将该表达式规则拆分为不同的非终结符。序列中具有相同的非终结符必然会产生冲突。

例如

{
    "program": [
        ["statements EOF", "return $1;"]
    ],
    "statements": [
        ["statement",            "$$ = $1;"],
        ["statements statement", "$$ = $1 + '\\n' + $2;"]
    ],
    "statement": [
        ["expression NEWLINE", "$$ = $1 + ';';"]
    ],
    "expression": [
        ["expression expression_base", "$$ = $1 + ', ' + $2;"],
        ["expression_base", "$$ = $1;"]
    ],
    "expression_base": [
        ["NUMBER",                "$$ = yytext;"]
    ]
}

这是有关这些类型语法的更多背景信息的好资源

于 2013-04-05T08:21:11.193 回答