符號表之二 組織和運營策略

2021-08-13 09:38:49 字數 2427 閱讀 4729

1.符號表的幾種組織形式

前面的文章

《符號表之一:符號屬性》也可以看到不同符號之間的語義屬性數目和內容是存在差異的,那麼如果運營符號表呢?顯然有兩個很明顯的思路:

1. 分而治之:創造多個符號表,每個符號表內的符號是屬性完全相同的;(組織方法分散,雖然單個表內的運營較為簡單,但是子表過多,增加了很多任務作量)

圖1. 分而治之:分散子表

2. 集權管理:犧牲空間,新增冗餘,將所有符號放在乙個表內。(管理倒是集中了,但是不同符號間存在很大差異,為了囊括所有符號的所有屬性,必然是需要新增冗餘的,這種方法導致符號表過於臃腫,甚至可能導致符號表是稀疏的)

圖2. 集權管理:統一大表

3. 近者合併,諸侯鼎力:所以簡單的思路是兩個方案折中,放寬「同類符號」的標準,比如屬性雖然不完全相同,但是差異不大的,也可以放在同乙個表內,這樣便可以降低子表數目的同時,減少單個表的臃腫程度

圖3. 諸侯鼎力:近似者合併

從上述討論可看到,為便於符號表的組織管理,每一張符號表的表長通常為定長的。即每張符號表可看成是乙個多元組,每個元組由若干個成員(屬性)組成,元組之間有相同的成員個數和一致的排列。元組之間的區分必須是表項中唯一標識該項的欄,這在符號表中就是」符號」這一欄,也就是表的」關鍵字欄」。對於變數、函式及過程來說,它們的」識別符號」就是作為它們記錄在表中的關鍵字(即」符號」),這也是為什麼編譯器會對變數名或函式名進行再次修飾的原因。

2.符號表的運營策略

既然上面已經提到了採用第三種方案「近者合併,諸侯鼎力」的策略後,那麼表項填入的方式可以有幾種呢?

1. 線性組織(陣列型別):按照符號被掃瞄到的順序填入符號表,這種線性表管理簡單但是比較難過的是,這種陣列需要預先劃分空間,即表項存在上限,所以對於符號個數不確定的情況,不能採用線性表。不過對於事先能夠確定符號個數或符號個數不多(公認小於20)時採用線性組織是非常好的。

2.排序組織(鍊錶型別):線性組織最大優點是【填入】時很簡單,但不足的是符號表後期的索引較為低效,基本只能靠遍歷。前面說道符號表的組織形式直接決定了後期語義處理等階段的效率。所以很自然的便是提出排序組織,按照符號名公升序排列,這樣子可以使用二分查詢來加速後期的搜尋速度。

3. 雜湊對映(雜湊):如果想把後期的搜尋速度提公升到極致,那麼顯然雜湊雜湊是乙個極端的做法,通過完全犧牲空間來換取時間。考慮到現今記憶體空間的增加,為了提高編譯速度,目前絕大多數的編譯程式都是採用雜湊雜湊做法來進行表現組織。

3.符號表的外延擴充套件

前面提到了符號表為了管理方便,所以表項的表長是固定的,但是如果符號的某個屬性的屬性值範圍較大,比如string_name最小1字元最大32字元,那麼如果依據了表長固定的原則,那顯然只能採用最大字元上限作為該域的size設定,但一旦這樣,必然會導致該項存在較大的冗餘,空間浪費嚴重。那麼解決方案也很明顯:從傳值變成傳位址(指標)就可以了。

學術點的說法:」由於程式中的識別符號長短不一,有時可能差別很大,用等長結構會產生溢位或冗餘。希望既保證關鍵字段的等長,又要減少甚至消除冗餘,可採用關鍵字池的索引結構,即新增一層【位址指標項】。(linux函式呼叫臨時棧上的形參輸入方式也是這樣)「

圖4. 符號名域借助」位址指標「的組分擴充套件

除了符號名域這種借助」位址指標「的組分擴充套件,還有一種類似前面介紹過的」拉鍊「方式的一種符號間關係組織,比如說要標識函式識別符號和歸屬於它的形參之間的隸屬關係,則可以通過鍊錶鏈結的方式來進行關係組織,末尾標」空「來代表檢索到頭。比如以func1 (para1, para2, para3)func2 ()為例介紹組分鏈結關係。

圖5. 鍊錶式組織符號間關聯關係

而對於這種存在擴充套件組分的情況,除了這種拉鍊式的解決方案,還有一種更通用的方案,這便是建立外延擴充套件資料結構來全域性性的指出關聯關係。這種方式雖然清晰,但是顯然管理和運營成本也是很高的,很厚重!

圖6. 外延設定擴充套件資料結構說明符號間關聯關係

總結來看,可以看到隨著現今硬體設施的效能提公升,對於空間效率的重視已經越來越弱,而犧牲空間來獲取盡可能呢大的時間效率提公升是諸多程式的設計訴求,這也進一步地提出了對小到資料結構大到整體架構的更嚴格的要求。

符號表 二叉查詢樹

實現了二叉查詢樹的 插入,查詢,獲取最大 最小值,刪除最大 最小值,按照給定的鍵值刪除鍵值,向上取整等方法。如下 標頭檔案如下 bst.h created on 2014年6月28日 author zhongchao ifndef bst define bst include include inc...

二分查詢實現符號表

使用keys和values兩個陣列分別儲存鍵和值 實現的核心是rank 方法,它返回表中小於給定鍵的數量 有序陣列的二分查詢 public class arraybinarysearchst comparable value implements iorderedsymboltable public...

基於二叉查詢樹的符號表

1.資料表示 我們巢狀定義乙個私有node類來表示二叉查詢樹上的乙個結點。每個結點都含有乙個鍵,乙個值,一條左鏈結,一條右鏈結。左鏈結指向一棵由小於該結點的所有鍵組成的二叉查詢樹,右鏈結指向一棵由大於該結點的所有鍵組成的二叉查詢樹。變數n給出以該結點為根的子樹的結點總數。這樣有 size x siz...