青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

隨筆-341  評論-2670  文章-0  trackbacks-0

手把手教你寫腳本引擎(五)——簡單的高級語言(3,符號表)

 

陳梓瀚

華南理工大學(xué)軟件本科05

vczh@163.com

http://www.shnenglu.com/vczh/

 

符號表的結(jié)構(gòu)的復(fù)雜度跟語言的語義規(guī)則的復(fù)雜度有關(guān)。對于C#來說,每一個符號都附帶了一大堆信息,譬如位置啦,所在的namespace啦,類型啦什么的。對于JavaScript來說,符號表幾乎是不需要的,因?yàn)闁|西都動態(tài)了,編譯時幾乎不檢查內(nèi)容。語義分析的輸出是符號表,代碼生成的輸入是符號表和語法樹。因此語法樹除了放語法相關(guān)的內(nèi)容,語義相關(guān)的內(nèi)容最好放到符號表里面(譬如說表達(dá)式的類型啦,語句的scope結(jié)果啦)。關(guān)于一個現(xiàn)實(shí)中的符號表組織可以看CMinus的語義分析結(jié)果。

 

首先我們要解決類型的表達(dá)問題。一門復(fù)雜的語言的類型有很多種。這里的種類指的不是intstring的區(qū)別,而是函數(shù)類型、結(jié)構(gòu)類型這種區(qū)別。每一種類型還有很多附帶的屬性。在語義分析的過程中,我們經(jīng)常要比較兩個類型是否一致。于是符號表的類型表達(dá)要設(shè)計(jì)成易于讀取、修改和比較。

 

我們通常由兩種解決方法。第一種方法是用一個繼承結(jié)構(gòu)來表達(dá)。定義一個基類TypeBase,然后底下一堆繼承。乍一看很OOP,實(shí)際不然。語義分析的時候我們對每一種特殊的類型都有一些特殊的操作,我們還是舉那個判斷類型是否相等的操作來說明一下。我們知道OOP里面的虛函數(shù)解決了一維的分派問題。我們拿到一個Base,對Base->Method求值,總是可以根據(jù)Base的實(shí)際類型來求值。如果我們需要對兩個類型同時進(jìn)行分派呢?譬如說Equal(Base1,Base2),這種操作當(dāng)且僅當(dāng)Base1Base2的實(shí)際種類相同才有比較的意義。這個時候我們改造成Base1->Equal(Base2)的話,也是免不了對Base2進(jìn)行一下dynamic_cast還是什么類似的操作的。

 

所以我個人比較偏向于第二種做法。我們?yōu)槊恳粋€類型創(chuàng)建一個唯一ID。譬如說int 0啦,int(int,int)1啦,int*2什么的。比較兩個類型是否相等就直接拿ID去比較,ID相等則類型相等,ID不相等則類型不相等。在實(shí)際操作上怎么做呢?我們知道語義分析的過程中會產(chǎn)生出一堆(理論上可以為無窮多的)新類型。每一種類型都有一些屬性。譬如說基本類型是有限的,可以用enum來表達(dá)。而函數(shù)類型需要返回值和參數(shù)類型表。于是我們拿屬性去要一個ID的時候,符號表首先檢查這個類型是否已經(jīng)存在,存在則返回對應(yīng)的ID,不存在則創(chuàng)建一條新的記錄,然后綁定一個新的ID。譬如CMinus的類型表采用如下接口分配ID

 

class VL_CMinusTypeTable : public VL_Base

{

public:

VInt GetPrimitiveType(VLE_CMinusPrimitiveType Type);

VInt GetPointer(VInt Type);

VInt GetArray(VInt Type , VInt Count);

VInt GetFunction(VInt ReturnType , VL_List<VInt , true>& ParameterTypes);

VInt CreateStruct();

VL_CMinusTypeSlot* GetType(VInt Type);

};

 

如果我們已知一個類型的ID,求其指針類型的ID,就調(diào)用GetPointer(TypeID)。經(jīng)過這一套函數(shù)的處理,我們總是可以不用擔(dān)心是否在什么地方讓兩個ID指向了相同的類型,或者一個類型不小心擁有了多個ID,十分好管理。

 

第二個問題就是要保存每一個表達(dá)式的類型和語句的Scope了。我不建議將這些信息保存在語法樹里面。原因比較復(fù)雜,因?yàn)橐环荽a在不同的上下文中可能有不同的意思,然后我們有一天突然有需要將這些環(huán)境中的這份代碼的語義分析結(jié)果保留下來的話,如果東西原本是存在語法樹里面的,那就完蛋了,只能去復(fù)制語法樹了。于是我建議將語法分析得不到的信息通通存進(jìn)符號表。因?yàn)楸磉_(dá)式和語句都是指針,我們只需要一些map就可以將表達(dá)式和語句的附加信息存起來了。

 

第三個問題是scope。一個變量或參數(shù)的作用范圍是有限的,于是我們只好創(chuàng)建一個scope樹,其中每一個節(jié)點(diǎn)都看得到父節(jié)點(diǎn),至于能不能看到子節(jié)點(diǎn)我覺得是無所謂的。于是對于一個具體的scope來說,一個scope就變成了一個鏈表,保存了當(dāng)前scope的所有符號名,然后還能知道直接或間接的父scope。下面舉個直觀的例子。假設(shè)我們有代碼:

 

int A=0;

int B(int C,int D)

{

  int E=0;

}

 

為了處理這份代碼,我們建立了三個scope。第一個是全局scope,記錄了AB。第二個是函數(shù)scope,記錄了CD。第三個是屬于語句的一個scope,記錄了E。于是我們用一個鏈表把他們串起來:語句scope -> 函數(shù)scope -> 全局scope

 

這樣做的好處是我們查找scope會變得很方便。譬如現(xiàn)在的上下文是語句scope,那么它理應(yīng)可以看見變量、參數(shù)、全局函數(shù)和全局變量。添加一個符號也很方便,只要當(dāng)前的scope沒有這個名字,不管上面的scope有沒有我們都可以添加,添加完就把上面的scope的同名符號給覆蓋了。

 

一個scope其實(shí)還可以記錄其他的東西的,譬如距離最近的循環(huán)表達(dá)式啦(用來判斷break是否應(yīng)該存在),所屬的函數(shù)啦(return后面要不要接表達(dá)式),還有其他的很多雜七雜八的東西。

 

第四個問題是如何創(chuàng)建符號表。之前的文章我們把語句和表達(dá)式都建立成了兩個大型的繼承結(jié)構(gòu)。表達(dá)式添加一個函數(shù)叫GetType,返回一個ID。語句建立一個函數(shù)叫Validate,用來驗(yàn)證語句是否合法。他們的參數(shù)都是符號表和當(dāng)前的scope,這樣的話,表達(dá)式為了創(chuàng)建類型就會產(chǎn)生出一堆ID,語句為了讓表達(dá)式可以知道每一個變量的類型就要創(chuàng)建scope。這么一遞歸下去,符號表也有了,類型也檢查完了。所以上文才會說語義分析產(chǎn)生符號表。

 

符號表就介紹到這里了。一個高級語言所遇到的基本的問題其實(shí)都講得差不多了。接下來的文章就針對具體的問題進(jìn)行講解了,譬如繼承、反射、垃圾收集等等的跟具體語言相關(guān)的問題。

posted on 2009-05-10 18:48 陳梓瀚(vczh) 閱讀(7278) 評論(1)  編輯 收藏 引用 所屬分類: 腳本技術(shù)

評論:
# re: 手把手教你寫腳本引擎(五)——簡單的高級語言(3,符號表) 2010-08-12 05:29 | aaa
博主講得非常精彩。能夠繼續(xù)講一下繼承,反射,垃圾回收的問題么?  回復(fù)  更多評論
  
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            国产精品久久久一区二区| 午夜精品美女久久久久av福利| 欧美在线视频二区| 亚洲综合久久久久| 国产欧美日韩免费看aⅴ视频| 欧美精品一区二区三区一线天视频| 91久久在线播放| 亚洲经典自拍| 国产精品国产三级国产普通话蜜臀 | 久久久噜噜噜久久狠狠50岁| 久久久久久香蕉网| 国产精品视频大全| 久久综合中文| 欧美日本簧片| 欧美在线一区二区| 欧美成人三级在线| 午夜免费在线观看精品视频| 久久精品一级爱片| 日韩亚洲精品视频| 午夜精品久久久久久久久久久| 精品成人一区二区三区| 亚洲美女免费精品视频在线观看| 国产欧美欧美| 亚洲激情在线观看| 国产亚洲一级| 一本久道久久综合婷婷鲸鱼| 红桃视频国产精品| 亚洲天堂黄色| 亚洲精品欧美精品| 久久国产精品久久久久久久久久| 日韩视频精品在线| 久久人人97超碰精品888| 亚洲欧美在线x视频| 欧美大片国产精品| 久久综合久久综合久久综合| 欧美日韩在线播放| 欧美国产精品久久| 国产一区二区三区在线播放免费观看| 亚洲人成在线观看| 一色屋精品视频在线观看网站| 在线一区观看| 一区二区三区**美女毛片| 老鸭窝91久久精品色噜噜导演| 欧美一区二区网站| 欧美性事免费在线观看| 亚洲国产精品尤物yw在线观看 | 开心色5月久久精品| 欧美在线免费| 国产精品久久久久久久久果冻传媒| 你懂的成人av| 一区国产精品| 欧美中日韩免费视频| 欧美一区二区视频网站| 国产精品久久波多野结衣| 亚洲人成啪啪网站| 日韩系列在线| 欧美激情视频网站| 亚洲欧洲精品一区二区三区不卡| 在线成人小视频| 久久美女性网| 亚洲第一精品在线| 亚洲激情影院| 欧美激情久久久久久| 亚洲国产精品欧美一二99| 亚洲国产欧美日韩另类综合| 久久亚洲捆绑美女| 久久中文在线| 国产精品jizz在线观看美国| 欧美一区二区成人| 国产一区二三区| 欧美在线免费视频| 久久午夜电影网| 在线不卡a资源高清| 久久亚洲高清| 欧美激情亚洲另类| 日韩午夜在线电影| 欧美视频日韩视频在线观看| 在线视频欧美精品| 久久激情网站| 亚洲国产福利在线| 欧美激情一二三区| 亚洲午夜高清视频| 久久综合久色欧美综合狠狠 | 欧美精品一线| 亚洲少妇自拍| 久久人人97超碰人人澡爱香蕉 | 久久福利视频导航| 久久超碰97中文字幕| 午夜精品久久久久久99热软件| 校园春色综合网| 黄色在线成人| 欧美精品精品一区| 亚洲免费在线观看| 美女主播一区| 中文日韩欧美| 国内精品福利| 欧美母乳在线| 久久九九精品99国产精品| 亚洲成人在线视频播放 | 久久精品国产v日韩v亚洲| 亚洲国产欧美久久| 亚洲午夜久久久| 欧美在线视频一区| 亚洲精品久久久久久久久久久| 欧美日韩一区二区三| 欧美在线观看一区二区| 亚洲国产精品毛片| 久久精品国产精品亚洲综合 | 欧美 日韩 国产一区二区在线视频| 亚洲欧洲一区二区在线观看| 久久黄色小说| 亚洲一区二区三区久久| 精品av久久久久电影| 欧美天堂亚洲电影院在线观看 | 国产精品美女在线观看| 美乳少妇欧美精品| 欧美精品啪啪| 亚洲国产美国国产综合一区二区| 欧美专区中文字幕| 亚洲视频成人| 国语自产精品视频在线看| 欧美啪啪成人vr| 久久视频在线看| 欧美有码在线视频| 亚洲视频精品| 亚洲理论在线观看| 亚洲国产另类久久精品| 久久午夜羞羞影院免费观看| 欧美亚洲一区在线| 一区二区三区高清| 日韩图片一区| 日韩视频在线观看国产| 亚洲国产精品一区二区www| 激情综合色综合久久| 国产婷婷色一区二区三区| 国产精品久久久久婷婷| 国产精品成人在线观看| 欧美午夜精品理论片a级大开眼界| 欧美激情小视频| 欧美啪啪成人vr| 亚洲最新合集| 中日韩美女免费视频网站在线观看| 欧美在线中文字幕| 亚洲欧洲一区二区三区| 最新日韩欧美| 亚洲黑丝在线| 亚洲精品免费观看| 亚洲伦理久久| 亚洲一级黄色av| 亚洲欧美视频在线观看| 亚洲欧美日韩专区| 欧美一级精品大片| 欧美在线在线| 免费看亚洲片| 亚洲黄色在线| avtt综合网| 午夜国产精品影院在线观看| 先锋亚洲精品| 玖玖视频精品| 欧美日韩亚洲一区二区三区| 国产精品一二一区| 精品电影在线观看| 99精品欧美一区二区三区综合在线| 欧美成人午夜激情在线| 亚洲精品乱码久久久久久| 国产精品成人一区二区网站软件 | 一区二区日韩| 一区二区三区日韩在线观看| 亚洲一区二区三区在线看 | 久久9热精品视频| 免费欧美电影| 国产精品高潮在线| 精品成人一区二区| 制服丝袜亚洲播放| 久久国产精品72免费观看| 免费观看日韩av| 中国女人久久久| 免费短视频成人日韩| 国产精品久久久爽爽爽麻豆色哟哟 | 欧美一区在线看| 一区精品在线播放| 久久米奇亚洲| 亚洲欧美一级二级三级| 亚洲国产天堂久久国产91| 欧美精品七区| 国产一区二区三区高清| 亚洲精品欧美极品| 久久久久久久综合狠狠综合| 亚洲高清视频在线| 亚洲欧美日韩一区二区三区在线观看| 乱中年女人伦av一区二区| 国产精品日韩| 亚洲人成网站在线播| 久久精品主播| 亚洲中字在线| 欧美午夜一区二区| 亚洲精品视频中文字幕| 久久影院午夜论| 亚洲欧美日韩一区二区三区在线| 欧美精品一区二区三区在线播放 |