我正在使用 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
有何不同?
最佳答案
What am I supposed to make of this debug message?
语法冲突意味着解析器可以达到一种状态,它可以遵循多个规则,但它没有足够的信息来确定要遵循哪一个(或者更糟的是,语法有歧义)。您必须调整语法以消除冲突。通常,这只需要练习即可。
What does the period in expression -> expression expression . mean?
句点代表解析器的位置。因此,在该规则中,解析器将刚刚解析了两个表达式,现在处于状态 9。当句点位于规则末尾时,这意味着可以“减少”规则,并将其分组为单个 expression
在这种情况下是非终结符。但是,它只能在下一个标记(前瞻)是 NEWLINE
或 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;"]
]
}
这是一个 nice resource有关这些类型的语法的更多背景信息。
关于javascript - 在Jison中调试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15825195/