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

            詞法分析

                詞法分析屬于整個(gè)編譯流程中的第一個(gè)階段。為什么要把編譯過(guò)程分為多個(gè)階段,這就
            如同軟件分層一樣,個(gè)人覺(jué)得是出于降低復(fù)雜性的考慮。
                再次聲明我不會(huì)告訴你任何編譯原理的理論知識(shí),因?yàn)樘孤实卣f(shuō)我也不會(huì):D。所以我努
            力將我們需要了解的概念盡可能簡(jiǎn)單地告訴你。當(dāng)然,可能會(huì)與教科書(shū)不吻合。

            什么是詞法分析?

                詞法分析就是把一段話整理成單詞集合。舉個(gè)簡(jiǎn)單的例子,例如有代碼:age = age + 1;,
            經(jīng)過(guò)詞法分析后,將得到:age、=、age、+、1、;幾個(gè)符號(hào)。為了方便,我稱每個(gè)單詞為一
            個(gè)token。

            詞法分析的作用

                詞法分析分析出來(lái)的單詞集合,直接作為編譯流程中接下來(lái)的語(yǔ)法分析的輸入。那么語(yǔ)
            法分析階段面對(duì)的將是一個(gè)一個(gè)的token,而不是單個(gè)的字符。
                例如,在處理age = age + 1;這種語(yǔ)句時(shí),當(dāng)我們獲取到token "="時(shí),我們直接期望接
            下來(lái)的token應(yīng)該是個(gè)表達(dá)式。以單詞為單位地處理,比直接處理單個(gè)字符簡(jiǎn)單很多。

            詞法分析的過(guò)程

                詞法分析的輸入是單個(gè)字符流,一般我們fopen一個(gè)源代碼文件,保存在一個(gè)char緩存
            里,這就是詞法分析的輸入。而詞法分析的最終輸出結(jié)果就是一個(gè)一個(gè)的token。
                為了處理方便,token并不是單純的單詞。通常我們會(huì)將源代碼中的所有單詞分類,例
            如變量名其實(shí)都屬于一類token。簡(jiǎn)單的token可定義為:
                struct Token
                {
                    int type;
                    char value[256];
                };
                type用于表示token的類型,例如一個(gè)變量名token的類型是一個(gè)標(biāo)識(shí)符。value可以用
            來(lái)具體地保存這個(gè)變量的名字。

                對(duì)于type的處理,通常會(huì)事先定義一組枚舉值,例如:
                enum    {    ID, NUM, STRING, IF, ELSE, WHILE, RETURN, FUNCTION }等等用于標(biāo)示
            在一個(gè)源代碼中可能出現(xiàn)的所有token。

                雖然說(shuō)詞法分析的結(jié)果是一個(gè)token集合,但事實(shí)上我們并不是一次做完詞法分析。通常
            詞法分析模塊提供一個(gè)get_token函數(shù)。每次調(diào)用該函數(shù)時(shí),都返回源代碼中下一個(gè)token。
            例如,有源代碼:age = age + 1;
                第一次調(diào)用get_token將獲得 { ID, "age" },第二次獲得 { ASSIGN, "=" },第三次
            獲得{ ID, "age" },等等。

                那么,詞法分析該如何實(shí)現(xiàn)?也就是struct Token get_token()函數(shù)如何實(shí)現(xiàn)?其實(shí)很
            簡(jiǎn)單,你告訴我:給你一個(gè)字符串,你如何判斷這個(gè)字符串全部是數(shù)字?
                int is_num( const char *str )
                {
                    while( *str != 0 )
                    {
                        if( !isdigit( *str++ ) ) return 0;
                    }
                    return 1;
                }
                所以,基本上,詞法分析的過(guò)程也就是這個(gè)過(guò)程。就拿標(biāo)識(shí)符舉例,典型的標(biāo)識(shí)符一般
            以字符開(kāi)頭,然后接著是數(shù)字或字符或_,當(dāng)遇到非法字符時(shí),這個(gè)標(biāo)識(shí)符的掃描即結(jié)束。
                詞法分析一般是個(gè)while+switch:
                struct Token get_token()
                {
                    while( current_char != 0 )
                    {
                        switch( current_char )
                        {
                            case CHARACTER:
                                /* 掃描一個(gè)標(biāo)識(shí)符 token */
                                break;

                            case '=':
                                /* 獲得一個(gè) ASSIGN token */
                                break;

                                ...
                        }
                    }
                }

                現(xiàn)在,試著去總結(jié)一門(mén)語(yǔ)言里的每一個(gè)token的規(guī)則,然后自己去寫(xiě)寫(xiě)看。

            代碼導(dǎo)讀

                在本節(jié)我將提供kl在googlecode的SVN上的代碼,先不要去管代碼包中的其他東西。關(guān)于
            詞法的代碼可以在kllex.c kllex.h中找到。lex_token是提供給其他模塊的接口,用于獲取
            當(dāng)前掃描的token。掃描結(jié)果可以通過(guò)lexState結(jié)構(gòu)體獲取。
                再次提下版權(quán)問(wèn)題,代碼文件以及代碼包中我并沒(méi)有加入任何版權(quán)說(shuō)明,哪怕是GPL。
            但是如同我之前說(shuō)的一樣,我不介意你傳播、改動(dòng)此代碼,但是請(qǐng)保留原作者信息。當(dāng)然,
            我并不介意你加上@modified by xxx:)。

                下載kl源代碼:http://klcommon.googlecode.com/files/kllan_0.1.0.zip

            posted on 2009-03-07 13:43 Kevin Lynx 閱讀(3831) 評(píng)論(2)  編輯 收藏 引用 所屬分類: kl腳本實(shí)現(xiàn)編譯原理

            評(píng)論

            # re: 實(shí)現(xiàn)一種解釋性腳本語(yǔ)言(三) 2009-03-15 16:28 夢(mèng)在天涯

            while( *str != 0 )
            {
            if( !isdigit( *str ) ) return 0;
            }

            為什么不是if(str != 0)
            {
            if(!isdigit(*str) return 0;
            }
            return 1;  回復(fù)  更多評(píng)論   

            # re: 實(shí)現(xiàn)一種解釋性腳本語(yǔ)言(三) 2009-03-15 16:47 Kevin Lynx

            @夢(mèng)在天涯
            這個(gè)例子是用于判定一個(gè)字符串是否全部是數(shù)字,不過(guò)例子中寫(xiě)的有問(wèn)題,應(yīng)該是:
            int is_number( const char *str )
            {
            while( *str != 0 )
            {
            if( !isdigit( *str++ ) ) return 0;
            }
            return 1;
            }

            謝謝提醒。
              回復(fù)  更多評(píng)論   

            香蕉久久夜色精品国产2020 | 亚洲v国产v天堂a无码久久| 国产Av激情久久无码天堂| 久久久久国产精品人妻| 久久午夜无码鲁丝片午夜精品| 久久婷婷久久一区二区三区| 久久99国产综合精品免费| 亚洲乱码中文字幕久久孕妇黑人| 亚洲国产精品一区二区三区久久 | 久久综合狠狠综合久久| 久久国内免费视频| 久久婷婷午色综合夜啪| 一本久道久久综合狠狠躁AV| 一级女性全黄久久生活片免费| 久久综合日本熟妇| 久久无码中文字幕东京热| 国产偷久久久精品专区| 一本一道久久精品综合| 国产精品无码久久综合网| 99久久精品国产一区二区| 久久精品人妻一区二区三区| 亚洲国产精品综合久久一线| 色综合久久中文字幕无码| 国产成人精品久久二区二区| 精品视频久久久久| 亚洲精品美女久久久久99小说 | 亚洲精品无码久久久久久| 99久久中文字幕| 久久九九久精品国产免费直播| 欧美亚洲国产精品久久久久| 久久精品国产亚洲AV无码娇色| 国产精品永久久久久久久久久| 欧美精品国产综合久久| 久久亚洲国产午夜精品理论片| 亚洲乱码日产精品a级毛片久久 | 少妇久久久久久被弄到高潮| 国内精品久久久久影院老司| 久久精品九九亚洲精品天堂| 精品999久久久久久中文字幕| 久久伊人亚洲AV无码网站| 久久久久国产精品熟女影院|