來自我的qq空間:
我的編輯器源**:
p-51的最大速度幾乎已經達到活塞式戰鬥機的極限了!
要想再提高速度,活塞式引擎已經無能為力。
於是乎,世界上第一架超音速飛機出現了!
突破音障的關鍵是要找到方法!
關於語法分析器中first的求解演算法,同樣有著兩種截然不同的實現方法,一種是經典教材中提供的類似於活塞式發動機的老爺車演算法,一種則是我根據詞法分析器中的演算法改進出來的相當於噴氣式發動機的高速演算法!
首先,看一下教材上的經典演算法:
對於乙個給定的語言,其中包含了多個非終結符,而每個非終結符可以匯出0個或者多個產生式,如果根據以上演算法來設計給定語言的資料結構,我們至少需要鍊錶1——產生式鍊錶;鍊錶2——產生式頭結點鍊錶,用於串起乙個非終結符的所有產生式;鍊錶3——非終結符鍊錶。基於這三個鍊錶,以上演算法可以工作,但這個演算法在數學上太不美觀了。其實,剛接觸到這個first演算法的時候,我就想起了詞法分析器中的firstpos演算法,它們之間是很類似的。
兩個演算法都是為了求解先導元素的,只是乙個基於二叉樹,乙個基於鍊錶,顯然firstpos要比first簡單且高效,但是firstpos無法簡單的替代first,如何才能構造出在語法分析器生成器中使用的firstpos呢?
第一,文法產生式必須用二叉樹表示,當然這沒什麼難度啦,需要實現的**與詞法分析器生成器中生成二叉樹的**十分類似,稍加修改就可以使用了。
第二,在構造二叉樹的時候需要注意的就是文法左遞迴的問題,這個問題,困擾了我好久,當初沒有堅持自己的想法而改用書上的演算法也是因為這個問題沒有想明白,不過這兩天我終於想明白了,當然我並沒有進行嚴格的數學證明,而是進行不全面的證明和大膽的假設,基於lr語法分析器的定義檔案允許左遞迴文法,如果將左遞迴的產生式包含到建立的二叉樹中,firstpos演算法將會永遠的遞迴下去,直到堆疊溢位,因此,在當前掃瞄記號為「|」的時候,需要檢查當前非終結符名字是否與下乙個記號的名字相同,若相同則表示乙個左遞迴產生式,該產生式中的所有元素均不被加入到二叉樹中。
第三,允許左遞迴文法的潛台詞是只允許直接左遞迴文法而不允許間接左遞迴文法的存在!因為間接的左遞迴文法同樣會導致堆疊溢位!這就是說間接左遞迴文法應該能夠被變換成等價的直接左遞迴文法。
下面是乙個簡單的等價變換:
間接左遞迴文法:
a->b*c|id
b->a+f
c->constant
f->float
變換後等價的直接左遞迴文法:
a->a+f|a*c|id
c->constant
f->float
基於以上三點,很容易就可以實現乙個在語法分析器生成器中使用的firstpos。
成功就是堅實的基礎
成功就是堅實的基礎,或者是自己精通的技能。學而不精 老想著學點新的東西貪心不足蛇吞象,到時候一事無成。或許是條件受限,或許是自己技術不行 嗯!這樣否定自己不好 亦或者是自己的性格太弱,這都是藉口!其實還是自己沒有充分磨礪。哈哈!現在處於乙個不上不下的地步,和有幾年開發經驗的程式設計師來比自己經驗不足...
正確的CRM選型奠定堅實的客戶基礎
隨著計算機和網路技術的發展,顧客購買方式 企業銷售模式發生了巨大的改變。對於任何企業而言,客戶是企業發展的基礎,是企業實現贏利的關鍵。企業在市場競爭中不斷提高自身核心競爭力的同時,也越來越關注客戶滿意度與客戶忠誠度的提公升。客戶的滿意和忠誠不是通過簡單的 競爭可以得來,而是要靠資料庫和客戶關係管理 ...
創新源於模仿之三 實現左右兩個螢幕的切換
今天第三篇,模仿ucweb的首頁,做乙個可以左右滑動的雙屏。而我們要做的事情就是分析它並精簡它 畢竟我們只是打算左右滑動罷了,並不需要能建立快捷方式資料夾之類的東西,更不需要在上面拖放圖示 expand source view plain 因此,不管是drop還是drag,統統不需要了 expand...