2013-04-05 217 views
4

我正在使用Jison編寫解析器。這是我的語法:在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?它們分別與expressionNUMBER分別有什麼不同?

回答

10

我該怎麼做這個調試信息?

文法衝突意味着解析器可以到達那裏可以遵循多個規則的狀態,但它沒有足夠的信息來確定遵循哪一個(或更糟的是,語法是不明確的)。你必須調整語法來消除衝突。通常,這需要練習才能正確。

在表達式 - >表達式表達式中的時間段是什麼。意思?

該時間段表示解析器的位置。因此,在這個規則中,解析器只會解析兩個表達式,現在處於狀態9.當該週期在規則的末尾時,這意味着規則可以被「減少」,並且分組爲非單個的非expression非在這種情況下終端。但是,如果下一個令牌(向前看)是NEWLINENUMBER,它只能減少。

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關於這些類型的語法的更多背景。

+0

謝謝Zach。有什麼方法可以明確指定生產的關聯性嗎?我創建了一個優先級'[「left」,「COMMA」],然後試圖將生成'expression expression'設置爲'{「prec」:「COMMA」}'。然而,這並沒有奏效。你會如何建議我重寫這部作品?我希望能夠輸入一個字符串,例如'2 3 5 7',並將其解析爲一個表達式'((((2 3)5)7)'。我一直在這裏呆了一段時間,我似乎無法繞過這個問題。 – 2013-04-05 13:48:08