首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

手把手教你寫腳本引擎(五):符號表設計與型別系統實作

     編輯:關於C++

承接前四篇,本文深入探討高階語言腳本引擎的核心組件——符號表。符號表連接語法分析與程式碼生成,承載型別資訊、作用域結構、識別子屬性等語義層面資料,是編譯器前後端的關鍵介面。

型別表示策略:唯一 ID 系統

面對函數型別、結構型別、指標、陣列等複雜型別體系,採用繼承階層雖符合 OOP 直覺,但雙重分派問題棘手(如 Equal(Base1, Base2) 需 dynamic_cast)。本文採用 唯一型別 ID 方案:

  • 基本型別對應固定 ID(int=0, float=1...)
  • 複合型別透過屬性查詢/建立 ID:GetPointer(baseID)、GetArray(elemID, count)、GetFunction(retID, paramIDs[])
  • 型別比較簡化為整數比較,極高效且避免重複 ID 問題

語法樹與符號表分離

不建議將型別、作用域資訊直接存於語法樹節點。因同一程式碼在不同上下文可能有不同語義,若需保留多環境分析結果,語法樹耦合會導致深拷貝困難。改用 map<Expr*, TypeInfo>、map<Stmt*, ScopeInfo> 等關聯容器,以節點指標為鍵外掛語義資訊。

作用域鏈結構

採鏈表串聯巢狀作用域:StmtScope → FuncScope → GlobalScope。查找識別子沿鏈向上搜尋;新增識別子僅檢查當前作用域,自動遮蔽外層同名符號。作用域節點可額外記錄:最近迴圈標籤(break/continue 合法性)、所屬函數(return 型別檢查)等編譯期上下文。

符號表建構流程

語法樹節點定義虛擬介面:

  • 運算式節點:virtual TypeID GetType(SymbolTable&, Scope*)
  • 陳述句節點:virtual void Validate(SymbolTable&, Scope*)

遞迴遍歷語法樹時,運算式產生型別 ID 註冊至型別表,陳述句建立作用域並驗證合法性。此過程即語義分析,產出完整符號表供下階段程式碼生成使用。

介面範例 (CMinus 型別表)

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& ParameterTypes);
    VInt CreateStruct();
    VL_CMinusTypeSlot* GetType(VInt Type);
};

後續主題預告

下篇將針對繼承、反射、垃圾回收等具體語言特性展開實作討論。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved