• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            loop_in_codes

            低調做技術__歡迎移步我的獨立博客 codemaro.com 微博 kevinlynx

            [總結]LL(1)分析法及其實現

            LL(1)分析法和遞歸下降分析法同屬于自頂向下分析法。相對于遞歸下降而言,LL通過顯示
            地維護一個棧來進行語法分析,遞歸下降則是利用了函數調用棧。

            LL分析法主要由分析棧、分析表和一個驅動算法組成。其實LL的分析算法還是很容易懂的,
            主要就是一個匹配替換的過程。而要構造這里的分析表,則還涉及計算first集和follow集
            的算法。

            1

            個人覺得龍書在解釋這些算法和概念時都非常清楚細致,雖然也有人說它很晦澀。

            first集和follow集的計算,拋開書上給的嚴密算法,用人的思維去理解(對于compiler
            compiler則需要用程序去構造這些集合,這是讓計算機去理解),其實很簡單:

            1、對于某個非終結符A的first集(first(A)),簡單地說就是由A推導得到的串的首符號的
            集合:A->aB,那么這里的a就屬于first(A),很形象。
            2、follow(A),則是緊隨A的終結符號集合,例如B->Aa,這里的a就屬于follow(A),也很形
            象。

            當然,因為文法符號中有epsilon,所以在計算上面兩個集合時則會涉及到一種傳遞性。例
            如,A->Bc, B->epsilon,B可以推導出epsilon,也就是基本等同于沒有,那么first(A)中
            就會包含c符號。

            在了解了first集和follow集的計算方法后,則可以通過另一些規則構造出LL需要的分析表。

            編譯原理里總有很多很多的理論和算法。但正是這些理論和算法,使得編譯器的實現變得簡
            單,代碼易維護。

            在某個特定的編程語言中,因為其文法一定,所以對于其LL(1)實現中的分析表就是確定的
            。我們也不需要在程序里動態構造first和follow集合。

            那么,要實現一個LL(1)分析法,大致步驟就集中于:設計文法->建立該文法的分析表->編
            碼。

            LL分析法是不能處理左遞歸文法的,例如:expr->expr + term,因為左遞歸文法會讓對應
            的分析表里某一項存在多個候選式。這里,又會涉及到消除左遞歸的方法。這個方法也很簡
            單,只需要把文法推導式代入如下的公式即可:

            A -> AB | C 等價于:A -> CX, X -> BX | epsilon

            最后一個問題是,如何在LL分析過程中建立抽象語法樹呢?雖然這里的LL分析法可以檢查文
            法對應的語言是否合法有效,但是似乎還不能做任何有意義的事情。這個問題歸結于語法制
            導翻譯,一般在編譯原理教程中語法分析后的章節里。

            LL分析法最大的悲劇在于將一棵在人看來清晰直白的語法樹分割了。在遞歸下降分析法中,
            一個樹節點所需要的屬性(例如算術運算符所需要的操作數)可以直接由其子節點得到。但
            是,在為了消除左遞歸而改變了的文法式子中,一個節點所需要的屬性可能跑到其兄弟節點
            或者父節點中去了。貌似這里可以參考“繼承屬性”概念。

            不過,綜合而言,我們有很多業余的手段來處理這種問題,例如建立屬性堆棧。具體來說,
            例如對于例子代碼中計算算術表達式,就可以把表達式中的數放到一個棧里。

            例子中,通過在文法表達式中插入動作符號來標識一個操作。例如對于文法:
            expr2->addop term expr2,則可以改為:expr2->addop term # expr2。當發現分析棧的棧
            頂元素是'#'時,則在屬性堆棧里取出操作數做計算。例子中還將操作符壓入了堆棧。

            下載例子,例子代碼最好對照arith_expr.txt中寫的文法和分析表來看。

            PS,最近在云風博客中看到他給的一句評論,我覺得很有道理,并且延伸開來可以說明我們
            周圍的很多現象:

            ”很多東西,意識不到問題比找不到解決方法要嚴重很多。比如one-pass 這個,覺得實現
            麻煩不去實現,和覺得實現沒有意義不去實現就是不同的。“

            對于以下現象,這句話都可以指明問題:
            1、認為造輪子沒有意義,從不考慮自己是否能造出;
            2、常告訴別人某個技術復雜晦澀不利于團隊使用,卻并不懂這個技術;
            3、籠統來說,【覺得】太多東西沒有意義,雖然并不真正懂這個東西。

            posted on 2010-03-15 21:33 Kevin Lynx 閱讀(9640) 評論(2)  編輯 收藏 引用 所屬分類: 編譯原理

            評論

            # re: [總結]LL(1)分析法及其實現[未登錄] 2010-03-16 08:17 ~

            籠統來說,【覺得】太多東西沒有意義,雖然并不真正懂這個東西!  回復  更多評論   

            # re: [總結]LL(1)分析法及其實現 2010-05-17 15:08 路過

            3、籠統來說,【覺得】太多東西沒有意義,雖然并不真正懂這個東西。


            1、認為造輪子沒有意義,從不考慮自己是否能造出;
            這個比喻很失水準。應該為不知道輪子有什么用  回復  更多評論   

            亚洲美日韩Av中文字幕无码久久久妻妇| 99久久99久久久精品齐齐| 色综合久久中文色婷婷| 91亚洲国产成人久久精品网址| 久久久久人妻一区精品| 亚洲国产精品无码成人片久久| 国产精品久久网| 欧美日韩久久中文字幕| 国产精品岛国久久久久| 久久久久久久久久久久久久| 成人午夜精品久久久久久久小说| 久久综合偷偷噜噜噜色| 久久综合中文字幕| 久久天天躁狠狠躁夜夜avapp| 精品久久久久久久久久久久久久久 | 91久久精品电影| 无码超乳爆乳中文字幕久久| 久久AAAA片一区二区| 久久精品亚洲一区二区三区浴池| 久久精品成人| 99久久婷婷国产综合精品草原| 久久精品国产亚洲av日韩| 久久99九九国产免费看小说| 久久精品中文字幕有码| 99久久精品免费| 热久久这里只有精品| 国产精品视频久久久| 久久发布国产伦子伦精品| 精品国产乱码久久久久软件| 久久精品视屏| 久久九九久精品国产免费直播| 国产综合精品久久亚洲| 国产精品嫩草影院久久| 国产ww久久久久久久久久| 日本精品久久久久中文字幕8| 国产产无码乱码精品久久鸭| 久久精品午夜一区二区福利| 精品少妇人妻av无码久久| 久久国产精品久久精品国产| 久久香蕉国产线看观看99| 国产精品日韩欧美久久综合|