2009-03-01 16 views
2

在解決移位/減少錯誤方面肯定有很多文檔和howtos。野牛文檔建議正確的解決方案通常只是期待他們並處理它。什麼時候模棱兩可的語法或生產規則好? (野牛移位/減少警告)

當你有這樣的事情:

S: S 'b' S | 't' 

您可以輕鬆地解決這些問題是這樣的:

S: S 'b' T | T 
T: 't' 

我的問題是:是否有更好的離開語法觸摸曖昧和%預計轉移/減少問題還是嘗試調整語法以避免它們會更好?我懷疑有一個平衡點,它是基於作者的需求,但我不知道。

+0

你是不是指T:'t'? – MSalters 2009-04-01 10:50:06

+0

是。不知道它改變了這個問題。 – jettero 2009-04-01 17:53:43

回答

2

當我看到它時,你的問題是「什麼時候模棱兩可的語法或生產規則可以嗎?」

首先考慮您描述的語言。允許將不明確的生產規則納入該語言的含義是什麼?

你的例子描述語言可能包括像一個表達式:t b t b t b t

的表達,在你的第二個例子解析爲將((((t) b t) b t) b t)但曖昧語法它也可能成爲(t b (t b (t b (t))))甚至(t b t) b (t b t)。這可能是有效的可能取決於語言。如果b運算符模型減法,它確實不應該是模糊的,但如果它是加法,它可能是好的。這真的取決於語言。

第二個需要考慮的問題是在衝突解決後,生成的語法源文件最終會變成什麼樣子。與其他源代碼一樣,語法意味着被人讀取,其次也由計算機讀取。首選一種符號,可以更清晰地說明解析器試圖從語法中做些什麼。也就是說,如果解析器正在執行一些可能未定義的行爲,例如,以渴望的語言評估函數參數的順序,則語法看起來不明確。

2

您可以使用運算符優先級指導衝突解決。將'b'聲明爲左或右關聯運算符,並且至少覆蓋了這種情況。

對於更復雜的模式,只要最終解析器在所有情況下都能產生正確的結果,警告就不用擔心了。雖然如果你不能用聲明給出正確的結果,你將不得不重寫語法。

1

在我上個學期的編譯器課程中,我們使用了bison,併爲pascal的一個子集構建了一個編譯器。

如果語言足夠複雜,則會出現一些錯誤。只要你明白他們爲什麼在那裏,以及你需要做些什麼來消除他們,我們發現它是沒問題的。如果有什麼東西存在,但由於行爲會按照我們的想法工作,並且需要大量的思考和努力才能使其值得(同時也使語法複雜化),我們將其放在一邊。只要確保你完全理解了錯誤,並在某處(甚至爲自己)記錄它,以便你始終知道它發生了什麼。

一旦事情真正涉及,這是一個成本/收益分析,但恕我直言,修復它應該被認爲是第一,然後真正弄清楚工作將是什麼(如果該工作打破別的東西,或使別的更難) ,然後從那裏出發。永遠不要把它們作爲普通的東西去掉

1

當我需要證明一個語法是明確的時,我傾向於先將它編寫爲Parsing Expression Grammar,然後將其手動轉換爲我用於項目需要的工具集的任何語法類型。以我的經驗來看,這種證明水平的需求是非常罕見的,但是,因爲我所遇到的大多數轉變/減少衝突都是相當微不足道的,以顯示正確性(按照您的示例)。