2010-07-19 40 views
4

我使用檸檬作爲解析器生成器,其錯誤處理與yacc和野牛的相同,如果您不知道檸檬。在解析(檸檬)中恢復錯誤標記

檸檬有一個選項可以在一組規則中定義錯誤標記以捕獲分析錯誤。生成的解析器的默認行爲是銷燬導致錯誤的令牌;有什麼方法可以重寫這種行爲,以便我可以保持令牌?

下面就來展示一下發生的事情爲例:基本上我追加令牌每個規則一起改革輸入字符串,這裏是一個例子語法:

input ::= string(A) { printf("%s", A); } // Print the result 
string(A) ::= string(B) part(C). { A = append(B, C); } 
string(A) ::= part(B). { A = B; } 
part(A) ::= NUMBER(B) NAME(C). { A = append(C, B); } // Rearrange the number and name 
part(A) ::= error(B). { A = B; } // On error keep the token anyways 

對於輸入:

"Username 1234Joseph" 

我得到的輸出:

"Joseph1234" 

因爲文本「用戶名」是由解析器中的部分(A):: =錯誤(B)規則,但我確實想要:

"Username Joseph1234" 

作爲輸出。

如果你能解決野牛或此問題的另一個解析器發生器我會接受,作爲一個答案:)

回答

2

使用yacc/bison時,如果可能,解析錯誤會將工具降至錯誤恢復模式。它將嘗試放棄令牌進入「乾淨」狀態。

我無法找到檸檬的參考,所以我不能顯示一些檸檬代碼來解決這個問題,但與yacc /野牛,人們會使用規則here

即,您需要調整您的錯誤規則,以表明解析器可以與yyerrok一起使用,以防止其丟棄令牌。接下來,它將嘗試重讀「壞」標記,因此您需要使用yyclearin清除它。最後,由於附加到您的錯誤代碼的規則包含您的令牌的內容,您需要設置一個函數來調整您的輸入堆棧,方法是獲取當前令牌內容並創建一個具有相同內容的新(正確)令牌。

作爲一個例子,如果定義爲MyOther MyOther語法看見MyTok MyOther:

stack 
MyTok: "the text" 
MyOther: "new text" 

stack 
MyOther: "the text" 
MyOther: "new text" 

爲了實現這一點,考慮使用yybackup。我無法找到一種替代方法,但yybackup皺起了眉頭。

+0

如果有人感興趣,我最終轉換到RE2C [[link](http://re2c.org/)]。用RE2C宏獲取行爲要容易得多。我編寫了宏,以便任何不匹配的子字符串都是簡單的輸出,而任何匹配的子字符串都是由RE2C修改的。 – 2015-05-05 17:29:15

2

這是一箇舊的,但爲什麼不......

語法必須包括空格。目前,語法只允許一系列NUMBER NAME標記(在標記之間沒有任何空格)。

+1

有回覆舊問題和選票的徽章(死靈法師和復興),所以有充足的理由回答老問題沒有答案(或沒有一個很好的答案)。 – 2011-05-28 00:07:15

+0

詞法分析器可能處理標記之間的空間等。這是標準的分工 - 詞法分析器處理註釋和空白和字符串;語法處理由詞法分析器發現的不被它吃的令牌。 – 2011-05-28 00:09:11

+0

@Jonathan Leffler,我不能根據這個問題做出這個假設。令牌序列NUMBER NAME預計會捕獲1234Joseph,但通常情況並非如此(1234Joseph不會是合法令牌)。我希望你看到我的意思是空間。 – 2011-05-28 18:49:22

相關問題