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

            kl中的錯(cuò)誤處理

            kl中的錯(cuò)誤處理

                之前我一直說(shuō)錯(cuò)誤處理是kl里的軟肋,由于一直在關(guān)注一些具體功能的改進(jìn),也沒(méi)有對(duì)
            這方面進(jìn)行改善。

                我這里所說(shuō)的錯(cuò)誤處理,包括語(yǔ)言本身和作為庫(kù)本身兩方面。
                語(yǔ)言本身指的是對(duì)于腳本代碼里的各種語(yǔ)法錯(cuò)誤、運(yùn)行時(shí)錯(cuò)誤等的處理。好的處理應(yīng)該
            不僅僅可以報(bào)告錯(cuò)誤,而且還能忽視錯(cuò)誤讓處理過(guò)程繼續(xù)。
                而把kl解釋器作為一個(gè)庫(kù)使用時(shí),庫(kù)本身也應(yīng)該對(duì)一些錯(cuò)誤情況進(jìn)行報(bào)告。

                整體上,kl簡(jiǎn)單地通過(guò)回調(diào)函數(shù)指針來(lái)把錯(cuò)誤信息傳給庫(kù)的應(yīng)用層。而因?yàn)槲蚁M麄€(gè)
            kl實(shí)現(xiàn)的幾層(詞法分析、語(yǔ)法分析、符號(hào)表、解釋器等)可以盡可能地獨(dú)立。例如雖然語(yǔ)
            法分析依賴于詞法分析(依賴于詞法分析提供的接口),但是因?yàn)樵~法分析并不對(duì)語(yǔ)法分析
            依賴,所以完全可以把詞法分析模塊拿出來(lái)單獨(dú)使用。所以,在日志方面,我?guī)缀鯙槊恳粚?br>都附加了個(gè)error_log函數(shù)指針。
                而用戶層在通過(guò)kllib層使用整個(gè)庫(kù)時(shí),傳入的回調(diào)函數(shù)會(huì)被間接地傳到詞法分析層。
            實(shí)際上,當(dāng)kl作為一個(gè)庫(kù)時(shí),kllib正是用于橋接庫(kù)本身和用戶層的bridge。

                另一方面,語(yǔ)言本身在處理錯(cuò)誤的腳本代碼時(shí),錯(cuò)誤分為幾大類型層次:
                1.詞法錯(cuò)誤 lex error,如掃描字符串出錯(cuò)
                2.語(yǔ)法錯(cuò)誤 syntax error,整理語(yǔ)法樹(shù)時(shí)出錯(cuò)
                3.運(yùn)行時(shí)錯(cuò)誤 runtime error,在解釋執(zhí)行代碼時(shí)出錯(cuò)
                4.庫(kù)錯(cuò)誤 lib error,發(fā)生在kllib這個(gè)bridge層的錯(cuò)誤
                kl在報(bào)告錯(cuò)誤信息時(shí),會(huì)首先附加該錯(cuò)誤是什么類型的錯(cuò)誤。

                這里最麻煩的是語(yǔ)法錯(cuò)誤的處理。因?yàn)檎Z(yǔ)法分析時(shí)發(fā)生錯(cuò)誤的可能性最大,錯(cuò)誤類型也
            有很多。例如你少寫(xiě)了分號(hào),少寫(xiě)了括號(hào),都會(huì)導(dǎo)致錯(cuò)誤。這個(gè)階段發(fā)生錯(cuò)誤不僅要求能準(zhǔn)
            確報(bào)告錯(cuò)誤,還需要忽略錯(cuò)誤讓整個(gè)過(guò)程盡量正確地下去。

                語(yǔ)法分析階段最根本的就是符號(hào)推導(dǎo)(單就kl的實(shí)現(xiàn)而言),所謂的符號(hào)推導(dǎo)是這樣一
            個(gè)過(guò)程,例如有賦值語(yǔ)句:a = 1;語(yǔ)法分析時(shí),語(yǔ)法分析器希望(所謂的推導(dǎo))等號(hào)后面會(huì)
            是一個(gè)表達(dá)式,當(dāng)分析完了表達(dá)式后,又希望接下來(lái)的符號(hào)(token)是分號(hào)作為該語(yǔ)句的結(jié)
            束。
                所以,klparser.c中的syn_match正是完成這個(gè)過(guò)程。每次你傳入你希望的符號(hào),例如
            分號(hào),該函數(shù)就檢查詞法分析中當(dāng)前符號(hào)(token)是否是分號(hào)。當(dāng)然,對(duì)于正確的腳本代碼,
            它是一個(gè)分號(hào),但是如果是錯(cuò)誤的代碼,syn_match就會(huì)打印諸如:
                >>syntax error->unexpected token-> ....
                即當(dāng)前的符號(hào)是不被期望的。

                上面完成了錯(cuò)誤的檢測(cè)。對(duì)于錯(cuò)誤的忽略,或者更高級(jí)點(diǎn)地對(duì)錯(cuò)誤的校正,kl中處理得
            比較簡(jiǎn)單,即:直接消耗掉這個(gè)不是期望中的符號(hào)。例如:
                a = 1 /* 忘加了分號(hào) */
                b = 1;
                上面兩句代碼被處理時(shí),在處理完a=1后,發(fā)現(xiàn)當(dāng)前的符號(hào)(token)b(是一個(gè)ID token)不
            是期望(expect)中的分號(hào),首先報(bào)告b不是期望的符號(hào),然后kl直接掠過(guò)b,獲取下個(gè)符號(hào)=。
            然后處理a=1這個(gè)過(guò)程結(jié)束。當(dāng)然,下次處理其他語(yǔ)句時(shí),發(fā)現(xiàn)=符號(hào),又會(huì)繼續(xù)發(fā)生錯(cuò)誤。

                錯(cuò)誤信息中比較重要的還有行號(hào)信息。之前kl這方面一直存在BUG,我在寫(xiě)貪食蛇例子
            的時(shí)候每次新加代碼都不敢加太多。因?yàn)榻忉屍鲌?bào)告的錯(cuò)誤行號(hào)總是錯(cuò)誤的,我只能靠有沒(méi)
            有錯(cuò)誤來(lái)找錯(cuò)誤,而不能通過(guò)錯(cuò)誤信息找錯(cuò)誤。
                行號(hào)信息被保存在詞法分析狀態(tài)中(lexState:lineno),語(yǔ)法分析中獲取token時(shí),會(huì)取
            出當(dāng)前的行號(hào),保存到語(yǔ)法樹(shù)樹(shù)節(jié)點(diǎn)中。因?yàn)榘ń忉屇K都是基于樹(shù)節(jié)點(diǎn)的,所以詞法分
            析語(yǔ)法分析解釋器三層都可以準(zhǔn)確報(bào)告行號(hào)。

                但是之前解釋器報(bào)告的行號(hào)始終很詭異。癥結(jié)在于我在載入腳本代碼文件時(shí),以rb方式
            載入,即二進(jìn)制形式。于是,在windows下,每行文本尾都會(huì)有\(zhòng)r\n兩個(gè)字符。而在詞法分
            析階段對(duì)于行號(hào)的增加是:
                case '\n':
                case '\r':
                    ls->lineno ++;
                不同OS對(duì)于文本文件的換行所添加的字符都不一樣,例如windows用\r\n,unix系用\n
            ,貌似Mac用\r。所以,詞法分析這里寫(xiě)應(yīng)該可以準(zhǔn)確地處理行號(hào)。

                但是對(duì)于windows,這里就直接將行號(hào)增加了兩次,所以也就導(dǎo)致了行號(hào)出錯(cuò)的問(wèn)題。查
            了下文檔,發(fā)現(xiàn)以文本方式打開(kāi)文件("r"),調(diào)用fread函數(shù)讀入文件內(nèi)容時(shí),就會(huì)自動(dòng)把
            \r\n替換為\n。

                代碼改后,又出問(wèn)題。這個(gè)時(shí)候,通過(guò)fseek和ftell獲取到的文件尺寸,貌似包括了
            \r\n,而fread出來(lái)的內(nèi)容卻因?yàn)樘鎿Q\r\n為\n而沒(méi)有這么多。
                不過(guò)文件載入不屬于kl庫(kù)本身,kl只接收以字符串形式表示的腳本代碼,所以也算不了
            核心問(wèn)題。

                同樣,最新代碼可以從google SVN獲取。當(dāng)然,我也在考慮是否換一個(gè)新的項(xiàng)目地址。

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

            麻豆亚洲AV永久无码精品久久| 中文字幕久久欲求不满| 久久这里只有精品首页| 久久妇女高潮几次MBA| 国产午夜精品久久久久免费视| 韩国无遮挡三级久久| 久久无码人妻精品一区二区三区| 思思久久99热免费精品6| 久久亚洲AV成人出白浆无码国产| 国产亚洲精久久久久久无码AV| 久久这里有精品| 久久久久成人精品无码| 久久久久久久久无码精品亚洲日韩 | 日韩久久无码免费毛片软件| 影音先锋女人AV鲁色资源网久久| 欧美精品一区二区精品久久| 一本色道久久综合狠狠躁| 国产精自产拍久久久久久蜜| 无码人妻久久一区二区三区免费丨| 国产精品内射久久久久欢欢| 国内精品伊人久久久久AV影院| 青青热久久国产久精品 | 精品熟女少妇AV免费久久| 91精品国产91热久久久久福利| 亚洲AV日韩精品久久久久| 美女久久久久久| 久久久网中文字幕| 国产免费久久精品99久久| 国产∨亚洲V天堂无码久久久| 亚洲va国产va天堂va久久| 一级女性全黄久久生活片免费| 人人狠狠综合久久亚洲婷婷| 国产成人精品免费久久久久| 久久亚洲精品成人av无码网站| 伊人久久大香线焦AV综合影院| 无码精品久久一区二区三区| 久久亚洲国产精品123区| 久久久久综合中文字幕| 亚洲精品国精品久久99热| 香蕉aa三级久久毛片 | 7777久久亚洲中文字幕|