• <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 閱讀(3164) 評(píng)論(0)  編輯 收藏 引用 所屬分類: kl腳本實(shí)現(xiàn)編譯原理

            亚洲人成网亚洲欧洲无码久久| 日韩AV毛片精品久久久| 久久久久无码精品国产不卡| 精品久久人妻av中文字幕| 日本三级久久网| 欧美久久一区二区三区| 精品熟女少妇av免费久久| 91久久成人免费| 久久天天躁狠狠躁夜夜2020一| 99久久精品毛片免费播放| 欧美久久亚洲精品| 久久这里只有精品久久| 久久精品国产亚洲av麻豆蜜芽| 国产日产久久高清欧美一区| 日韩精品久久久久久久电影| 久久人人妻人人爽人人爽| 亚洲精品tv久久久久久久久久| 国产亚洲综合久久系列| 97精品国产97久久久久久免费| 久久美女网站免费| 国产精品久久久久久久久免费| 伊人色综合九久久天天蜜桃| 中文字幕一区二区三区久久网站| 久久精品国产清自在天天线| 欧美久久综合九色综合| 国产高潮国产高潮久久久91 | 久久亚洲精品视频| 亚洲综合熟女久久久30p| 亚洲欧美日韩久久精品| 久久99精品久久久久久9蜜桃| 大伊人青草狠狠久久| 97精品伊人久久大香线蕉app| 日本久久久久亚洲中字幕| 少妇人妻综合久久中文字幕| 亚洲国产高清精品线久久| 久久免费视频一区| 人妻无码精品久久亚瑟影视| 日韩久久久久中文字幕人妻| 一本一道久久a久久精品综合| 欧美精品九九99久久在观看| 欧美日韩成人精品久久久免费看|