2013-04-10 57 views
3

我有一個使用括號和方括號作爲分隔符的語法。當由野牛產生的解析器給定的輸入與不平衡定界符,在YYLTYPE*傳遞給yyerror錯誤位置是輸入的結束。所以,例如,在輸入xx(yyvoid yyerror(YYLTYPE* yylloc, Context* ctx, const char* msg)我有那yylloc->first_column == yylloc->last_column == 5。不幸的是,輸入的結束並不是用於指示不匹配的分隔符的最顯着的位置。更有用的是左側括號或左側方括號中沒有匹配的位置。 (在這個例子中,這將是偏移量爲2的左括號。)我收集到,這個信息在解析堆棧中是可用的 - 必須有一些n,使得$-n是無與倫比的([令牌和@-nYYLTYPE結構保持自己的立場---但沒有出現,可購自yyerror。我知道我可以保留一堆自己的追蹤分隔符的偏移量,並將其保存在Context我已經傳遞到yyerror,但這看起來不雅觀和重複性,因爲野牛必須跟蹤這個。如何找到yacc/bison中的錯誤報告的不平衡分隔符?

所以:如何能一個獎開出野牛第一不平衡定界符遇到的輸入,使得對於分析錯誤產生的消息時,這是可用的位置的?

+0

你能分享你的語法(它至少部分被處理括號)? – Josh 2013-04-11 13:58:07

+0

這是[這裏](https://github.com/uckelman/liblightgrep/blob/ccsetops/src/lib/parser.ypp)。括號在第187行處理。 – uckelman 2013-04-11 18:43:38

回答

6

你應該能夠添加兩種規則:

atom: '(' error { /* unmatched left paren at @1 */ } 

atom: '(' alt error { /* unmatched left paren at @1 */ } 

獲取有關無法匹配的左括號的信息。不同的是第一條規則將匹配一個無與倫比的括號後面沒有被任何東西可解析(比如在輸入的結束),而第二個將只匹配,如果它後面的東西,看起來像一個有效alt

有可能是一個問題,如果你在你的語法任何其他錯誤作品(你在鏈接的語法不行),在這種情況下,不同的錯誤生產可能首先觸發。由於沒有其他錯誤規則,所以第一種選擇更好。

請注意,使用yacc/bison錯誤恢復規則不會以任何方式抑制語法錯誤,它只是在嘗試恢復語法錯誤後運行一些代碼。該代碼可以打印其他錯誤消息,然後中止而不是嘗試恢復,但這些消息將在語法錯誤消息之後打印。

+2

你解決問題的答案是「注意,使用yacc/bison錯誤恢復規則不會以任何方式抑制語法錯誤,它只是在嘗試恢復語法錯誤後運行一些代碼。」這讓我意識到,與錯誤規則相關的操作從未被運行,因爲我在'yyerror'中拋出了一個異常。經過調整後,我可以看到,我*做*在錯誤規則上得到匹配。 – uckelman 2013-04-19 21:54:07

+0

謝謝@ chris-dodd和@uckelman!我也犯了同樣的錯誤。 – Canella 2014-03-14 15:06:16

1

退房野牛誤差記號:http://www.gnu.org/software/bison/manual/html_node/Error-Recovery.html#Error-Recovery

我想象這樣的事情會的工作(我沒有測試):

atom: '(' alt ')'  { $$ = $2; } 
    | '(' alt error '\n' { /* this handles an extra left paren */ } 
    | error alt ')'  { /* this handles an extra right paren */ } 
    | literal 
    ; 
+0

嗯。我不能以換行符結束,因爲我的輸入都沒有。當我添加'| '('alt error',那個生產從來沒有匹配過,無法匹配的左側的parens最終會像以前一樣經常出現解析錯誤 – uckelman 2013-04-11 20:14:58

+0

當您遇到無與倫比的左側paren時,您想要什麼行爲?您只是在尋找乾淨的錯誤報告,你想要忽略一些輸入並保持解析的能力嗎? – Josh 2013-04-11 20:49:52

+0

我沒有用於實際恢復---我不會在錯誤發生後繼續解析。我想要的是知道無與倫比的左派paren的偏移。 (順便說一下,我已經閱讀了錯誤恢復部分並試過了,看看我是否可以通過這種方式獲得偏移量。) – uckelman 2013-04-12 09:22:27