• <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://m.shnenglu.com/vczh/archive/2008/06/15/53373.html】  回復(fù)  更多評(píng)論   

            久久夜色精品国产亚洲| 亚洲欧美日韩精品久久亚洲区| 久久精品一本到99热免费| 久久91综合国产91久久精品| 狠狠人妻久久久久久综合| 2021国产精品久久精品| 国产成人精品久久二区二区| 久久精品视频网| 久久久久国色AV免费观看| 香蕉久久夜色精品国产尤物| 久久综合视频网| 72种姿势欧美久久久久大黄蕉| 色综合合久久天天综合绕视看| 久久久久久久国产免费看| 亚洲天堂久久久| 99久久亚洲综合精品成人| 久久免费视频6| 久久99国产亚洲高清观看首页| 亚洲色欲久久久久综合网| 996久久国产精品线观看| 久久只有这精品99| 久久久久无码中| 久久精品国产亚洲一区二区| 亚洲乱码中文字幕久久孕妇黑人| 国产精品青草久久久久福利99| 久久国产精品成人片免费| 久久乐国产综合亚洲精品| 国产亚洲色婷婷久久99精品91| 欧洲精品久久久av无码电影| 国产69精品久久久久9999APGF| 久久久久亚洲AV无码专区网站| 久久久久18| 日本高清无卡码一区二区久久| 国产福利电影一区二区三区久久老子无码午夜伦不 | 国产精品女同一区二区久久| 亚洲国产天堂久久综合网站| 国产精品欧美久久久天天影视| 亚洲色欲久久久综合网 | 久久国产乱子精品免费女| 久久精品国产精品青草app| 国产综合免费精品久久久|