• <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

            低調(diào)做技術(shù)__歡迎移步我的獨(dú)立博客 codemaro.com 微博 kevinlynx

            實(shí)現(xiàn)一種解釋性腳本語(yǔ)言(四)

            author: Kevin Lynx email: zmhn320#163.com date: 3.9.2009

            語(yǔ)法分析

                語(yǔ)法分析接收詞法分析階段的token集合為輸入,將這些沒(méi)有關(guān)系的tokens整理為相互
            之間有關(guān)系的結(jié)構(gòu)。書(shū)面點(diǎn)的說(shuō)法叫語(yǔ)法樹(shù)。
                每一次讓我寫這些文縐縐的概念真讓我受不了:D。

            語(yǔ)法樹(shù)

                語(yǔ)法樹(shù)簡(jiǎn)單來(lái)說(shuō)就是一個(gè)以token作為每個(gè)節(jié)點(diǎn)的樹(shù)型結(jié)構(gòu)。例如我們有表達(dá)式age =
            age + 1;,在詞法階段它被整理為token集合:age, =, age, +, 1。那么在經(jīng)過(guò)語(yǔ)法分析后
            ,這些tokens將被整理為大致如下的樹(shù)形結(jié)構(gòu):
                    =
                  /   \
                age    +
                     /   \
                   age     1

                整理成這樣的結(jié)構(gòu)有什么好處?就kl解釋器而言,最直接的好處就是我可以遞歸地解釋
            這棵樹(shù)執(zhí)行。例如:

                value compute( TreeNode *root )
                {
                    /* child[0]保存結(jié)果值age,child[1]是那個(gè)+表達(dá)式 */
                    return op_exp( root->child[1] );
                }

                value op_exp( TreeNode *node )
                {
                    switch( node->op )
                    {
                        case '+':
                        {
                            /* + 表達(dá)式必然有左右操作數(shù) */
                            value left = factor( node->child[0] );
                            value right = factor( node->child[1] );
                            return left + right;
                        }
                    }
                }
                value factor( TreeNode *node )
                {
                    switch( node->type )
                    {
                        case ID:
                            /* 查找age的值 */
                            return age;

                        case CONST:
                            /* 1 是常量 */
                            return node->cvalue;
                    }
                }

                如你所見(jiàn),當(dāng)我們完成了語(yǔ)法分析階段,我們就可以完成我們的解釋器了。后面我會(huì)單
            獨(dú)講解下整個(gè)解釋過(guò)程,包括每個(gè)模塊是如何協(xié)作的。我不知道其他解釋器是怎么做的,但
            是我這樣做,起碼結(jié)果是對(duì)的。

            如何整理出語(yǔ)法樹(shù)?

                這里不得不提到所謂的BNF文法,很明顯你還是無(wú)法從我這里獲取編譯原理里某個(gè)概念
            的講解。我這里提這個(gè)概念完全是方便我提到這個(gè)東西。
                每一種語(yǔ)言都有其自己的BNF文法,因?yàn)槿f(wàn)惡的先知告訴我們,每一門語(yǔ)言都需要建立
            其語(yǔ)法樹(shù)。- -!
                就像詞法分析一樣,因?yàn)榇蟛糠终Z(yǔ)言的結(jié)構(gòu)都差不多,所以我覺(jué)得詞法分析和語(yǔ)法分析
            基本上都沒(méi)有任何特別之處。也就是說(shuō),別的語(yǔ)言的BNF你可以直接拿來(lái)改改用。
                抄個(gè)BNF如下:
                exp -> exp adop term | term
                addop -> + | -
                term -> term mulop factor | factor
                mulop -> *
                factor -> (exp) | number
                這個(gè)BNF用來(lái)描述一般的算數(shù)表達(dá)式(+-*/)。簡(jiǎn)單來(lái)說(shuō),一門語(yǔ)言的BNF就是用于描述該
            語(yǔ)言所有語(yǔ)句的東西,包括if、while、函數(shù)定義之類。建議你google一下C語(yǔ)言的BNF,并
            改造之用于你自己的語(yǔ)言。

                那么有了BNF之后,該如何整理出語(yǔ)法樹(shù)呢?
                通常,我們的代碼里都會(huì)直接有對(duì)應(yīng)exp、term、addop之類的函數(shù)。按照我這句話的意
            思,上面抄的BNF被翻譯為程序代碼后,就可能為:
                exp()
                {
                    if( ... ) left = exp()
                    right = term();
                    left addop right;
                }
                term()
                {
                    if( ... ) left = term()
                    right = factor();
                    left mulop right;
                }
                factor()
                {
                    if( ... ) return exp();
                    else return number;
                }

                (可能還會(huì)涉及到EBNF,用于處理重復(fù)和選擇的一些情況---不用管這句話)

                每一個(gè)函數(shù)基本上都會(huì)返回一個(gè)樹(shù)節(jié)點(diǎn),當(dāng)然,該節(jié)點(diǎn)下可能會(huì)有很多子節(jié)點(diǎn)。   

            總結(jié)

                語(yǔ)法分析基本上就是以上信息。它將詞法分析輸出的token集合整理成一顆語(yǔ)法樹(shù)。為
            了整理出這棵語(yǔ)法樹(shù),你需要找一份用于描述你語(yǔ)言的BNF,然后根據(jù)BNF翻譯成處理代碼。

            代碼導(dǎo)讀

                kl中的整個(gè)語(yǔ)法分析代碼位于klparser.c/klparser.h中,其BNF基本上取自<編譯原理與
            實(shí)踐>附錄中的C_語(yǔ)言。

            posted on 2009-03-09 11:12 Kevin Lynx 閱讀(3644) 評(píng)論(3)  編輯 收藏 引用 所屬分類: kl腳本實(shí)現(xiàn)編譯原理

            評(píng)論

            # re: 實(shí)現(xiàn)一種解釋性腳本語(yǔ)言(四) 2009-03-09 22:17 陳梓瀚(vczh)

            你的結(jié)構(gòu)沒(méi)有考慮語(yǔ)法錯(cuò)誤的處理辦法。  回復(fù)  更多評(píng)論   

            # re: 實(shí)現(xiàn)一種解釋性腳本語(yǔ)言(四) 2009-03-09 22:26 Kevin Lynx

            @陳梓瀚(vczh)
            貌似是的,后面對(duì)于錯(cuò)誤的處理,甚至最基本的錯(cuò)誤報(bào)告(定位)都存在問(wèn)題。對(duì)這塊不熟,沒(méi)管了。
              回復(fù)  更多評(píng)論   

            # re: 實(shí)現(xiàn)一種解釋性腳本語(yǔ)言(四) 2009-03-10 13:29 陳梓瀚(vczh)

            @Kevin Lynx
            見(jiàn)【http://www.shnenglu.com/vczh/archive/2008/06/15/53373.html】  回復(fù)  更多評(píng)論   

            性做久久久久久久久| 99久久精品免费| 国产成人精品久久综合| 97精品久久天干天天天按摩 | 精品一久久香蕉国产线看播放| 久久国产成人午夜aⅴ影院| 国产精品美女久久久久久2018| 无码国内精品久久人妻蜜桃| 久久精品国产亚洲5555| 久久久这里有精品中文字幕| 欧美与黑人午夜性猛交久久久| 91精品观看91久久久久久| 久久国产精品久久| a级毛片无码兔费真人久久| 亚洲国产成人久久综合一 | 99久久国产亚洲高清观看2024| 久久99国产精品99久久| 91精品久久久久久无码| 国产精品VIDEOSSEX久久发布| 香港aa三级久久三级老师2021国产三级精品三级在 | 久久国产成人午夜AV影院| 精品久久久久国产免费| 亚洲精品午夜国产va久久| 久久久国产打桩机| 成人资源影音先锋久久资源网| 久久久久亚洲AV无码专区桃色| 久久亚洲国产精品成人AV秋霞 | 亚洲AV无码久久精品狠狠爱浪潮 | 国产精品久久久久久福利漫画 | 久久精品国产亚洲av日韩| 久久久久久综合一区中文字幕 | 无码任你躁久久久久久老妇App| 国产精品美女久久久久| 国产午夜精品理论片久久| 久久中文字幕人妻熟av女| 国产人久久人人人人爽| 伊人久久大香线蕉成人| 香蕉久久夜色精品国产小说| 亚洲色欲久久久综合网东京热| 久久久久无码中| 国产精品久久自在自线观看|