深入探討 matiec 編譯器中 `stage1_2` - benchen2001/matiec GitHub Wiki

基於我之前的分析,我將繼續深入探討 matiec 編譯器中 stage1_2 目錄的抽象語法樹 (AST) 基本結構。

matiec 編譯器 stage1_2 目錄的抽象語法樹 (AST) 基本結構

抽象語法樹 (AST) 是 matiec 編譯器分析 IEC 61131-3 程式的核心資料結構。從 absyntax.def 檔案中,我們可以看到 AST 的詳細定義。以下是 AST 的主要結構分類及說明:

1. 基礎類別

AST 的基礎結構由三種基本類型組成:

  1. symbol_c - 所有 AST 節點的基礎類別
  2. token_c - 表示詞法單元的葉節點,如識別符、常數等
  3. list_c - 表示節點列表的容器節點

這三個基本類別定義於 absyntax.hh 中,形成了 AST 的基礎骨架。

2. 主要節點類別分類

2.1 語彙元素 (Lexical Elements)

這類節點代表程式碼中的基本元素:

  • 識別符 (Identifiers)

    • identifier_c - 基本識別符
    • derived_datatype_identifier_c - 派生資料類型識別符
    • poutype_identifier_c - POU (Program Organization Unit) 類型識別符
  • 常數 (Constants)

    • 數值常數

      • integer_c - 整數常數
      • real_c - 實數常數
      • binary_integer_c - 二進位整數
      • octal_integer_c - 八進位整數
      • hex_integer_c - 十六進位整數
      • neg_real_c - 負實數
      • neg_integer_c - 負整數
    • 布林常數

      • boolean_true_c - TRUE 值
      • boolean_false_c - FALSE 值
    • 字串常數

      • single_byte_character_string_c - 單位元組字串 (STRING)
      • double_byte_character_string_c - 雙位元組字串 (WSTRING)
    • 時間相關常數

      • duration_c - 持續時間 (如 T#10ms)
      • time_of_day_c - 一天中的時間 (如 TOD#12:00:00)
      • date_c - 日期 (如 D#2022-10-15)
      • date_and_time_c - 日期和時間 (如 DT#2022-10-15-12:00:00)

2.2 資料類型 (Data Types)

這類節點表示 IEC 61131-3 支援的各種資料類型:

  • 基本資料類型

    • bool_type_name_c - BOOL 型別
    • int_type_name_c - INT 型別
    • real_type_name_c - REAL 型別
    • time_type_name_c - TIME 型別
    • string_type_name_c - STRING 型別
    • 等其他基本型別
  • 派生資料類型

    • simple_type_declaration_c - 簡單型別宣告 (如 MyInt : INT;)
    • subrange_type_declaration_c - 子範圍型別宣告 (如 MyRange : INT (0..100);)
    • enumerated_type_declaration_c - 列舉型別宣告
    • array_type_declaration_c - 陣列型別宣告
    • structure_type_declaration_c - 結構體型別宣告
    • string_type_declaration_c - 字串型別宣告
  • 安全相關型別

    • safebool_type_name_c - 安全 BOOL 型別
    • safeint_type_name_c - 安全 INT 型別
    • 等其他安全型別

2.3 變數 (Variables)

表示不同種類的變數:

  • 變數存取

    • symbolic_variable_c - 一般符號變數
    • direct_variable_c - 直接表示變數 (如 %IX0.0)
    • array_variable_c - 陣列變數 (含索引)
    • structured_variable_c - 結構體變數 (含成員存取)
  • 變數宣告

    • var_declarations_c - VAR 區段宣告
    • input_declarations_c - VAR_INPUT 區段宣告
    • output_declarations_c - VAR_OUTPUT 區段宣告
    • input_output_declarations_c - VAR_IN_OUT 區段宣告
    • external_var_declarations_c - VAR_EXTERNAL 區段宣告
    • global_var_declarations_c - VAR_GLOBAL 區段宣告
    • located_var_declarations_c - 位址變數宣告
    • var1_init_decl_c - 單一變數宣告與初始化
    • array_var_init_decl_c - 陣列變數宣告與初始化
    • structured_var_init_decl_c - 結構體變數宣告與初始化

2.4 程式組織單元 (Program Organization Units)

表示 IEC 61131-3 的三種主要程式組織單元:

  • 函式 (Functions)

    • function_declaration_c - 函式宣告
  • 功能塊 (Function Blocks)

    • function_block_declaration_c - 功能塊宣告
  • 程式 (Programs)

    • program_declaration_c - 程式宣告

2.5 語句 (Statements)

主要出現在 ST(結構化文字)語言中的語句:

  • 賦值語句

    • assignment_statement_c - 賦值語句 (如 a := 10;)
  • 流程控制語句

    • if_statement_c - IF 語句
    • case_statement_c - CASE 語句
    • for_statement_c - FOR 迴圈
    • while_statement_c - WHILE 迴圈
    • repeat_statement_c - REPEAT 迴圈
    • exit_statement_c - EXIT 語句
    • return_statement_c - RETURN 語句
  • 函式呼叫

    • function_invocation_c - 函式呼叫
    • fb_invocation_c - 功能塊呼叫

2.6 表達式 (Expressions)

表示各種運算表達式:

  • 一元運算

    • neg_expression_c - 負號運算 (如 -a)
    • not_expression_c - 非運算 (如 NOT a)
  • 二元運算

    • add_expression_c - 加法 (如 a + b)
    • sub_expression_c - 減法 (如 a - b)
    • mul_expression_c - 乘法 (如 a * b)
    • div_expression_c - 除法 (如 a / b)
    • mod_expression_c - 取餘 (如 a MOD b)
    • power_expression_c - 冪運算 (如 a ** b)
    • and_expression_c - 與運算 (如 a AND b)
    • or_expression_c - 或運算 (如 a OR b)
    • xor_expression_c - 異或運算 (如 a XOR b)
    • equ_expression_c - 等於 (如 a = b)
    • notequ_expression_c - 不等於 (如 a <> b)
    • lt_expression_c - 小於 (如 a < b)
    • gt_expression_c - 大於 (如 a > b)
    • le_expression_c - 小於等於 (如 a <= b)
    • ge_expression_c - 大於等於 (如 a >= b)

2.7 IL (指令列表) 特有節點

表示 IL 語言特有的語法結構:

  • 運算符

    • LD_operator_c - 載入操作符
    • ST_operator_c - 儲存操作符
    • ADD_operator_c - 加法操作符
    • SUB_operator_c - 減法操作符
    • 等其他 IL 操作符
  • 跳轉和呼叫

    • JMP_operator_c - 跳轉操作符
    • CAL_operator_c - 呼叫操作符
  • 指令結構

    • il_instruction_c - IL 指令
    • il_simple_operation_c - 簡單 IL 操作
    • il_function_call_c - IL 中的函式呼叫
    • il_expression_c - IL 中的表達式

2.8 SFC (順序功能圖) 特有節點

表示 SFC 語言特有的語法結構:

  • 步驟 (Steps)

    • step_c - 一般步驟
    • initial_step_c - 初始步驟
  • 轉移 (Transitions)

    • transition_c - 轉移條件
  • 動作 (Actions)

    • action_c - 動作
    • action_association_c - 步驟與動作的關聯
  • 網路結構

    • sequential_function_chart_c - SFC 圖
    • sfc_network_c - SFC 網路

2.9 配置元素 (Configuration Elements)

表示 IEC 61131-3 的配置相關結構:

  • 配置

    • configuration_declaration_c - 配置宣告
  • 資源

    • resource_declaration_c - 資源宣告
  • 任務

    • task_configuration_c - 任務配置
    • task_initialization_c - 任務初始化
  • 程式配置

    • program_configuration_c - 程式配置

3. AST 節點間的關係

AST 節點透過指針連接,形成樹狀結構:

  1. 父子關係 - 如 if_statement_c 包含 expression(條件)和 statement_list(處理語句)
  2. 列表關係 - 如 var_declaration_list_c 包含多個變數宣告
  3. 型別關係 - 如 symbolic_variable_c 可能指向 integer_type_name_c 作為其型別

4. 特別關注的 AST 節點

4.1 simple_spec_init_c

這是一個重要的節點,用於表示簡單型別宣告與初始化:

/* simple_specification ASSIGN constant */
SYM_REF2(simple_spec_init_c, simple_specification, constant)

用於表示如下形式的程式碼:

enable : BOOL := TRUE;
count : INT := 0;

4.2 function_declaration_c 與其他 POU 宣告

這些節點代表程式組織單元的宣告:

/* enumvalue_symtable is filled in by enum_declaration_check_c, during stage3 semantic verification */
SYM_REF4(function_declaration_c, derived_function_name, type_name, var_declarations_list, function_body, enumvalue_symtable_t enumvalue_symtable;)

5. AST 在 stage1_2 中的構建過程

  1. 詞法分析 - iec_flex.ll 將程式碼分解為標記
  2. 語法分析 - iec_bison.yy 根據語法規則構建 AST
  3. AST 構建 - ast_build.cc 提供用於創建 AST 節點的函數
  4. AST 優化 - ast_optim.cc 對 AST 進行簡化和優化

6. 特徵與實現細節

  1. 多態與動態類型識別

    • 所有 AST 節點都繼承自 symbol_c
    • 使用 visitor 模式進行 AST 遍歷和處理
  2. 位置資訊

    • 每個 AST 節點包含位置資訊 (first_line, first_column 等)
    • 用於準確報告錯誤位置
  3. 型別資訊

    • 節點在語意分析階段添加型別資訊
    • 通過 datatype 指針和 candidate_datatypes 列表管理
  4. 擴展性

    • AST 結構支持 IEC 61131-3 的所有語言特性
    • 支持安全相關擴展 (SAFExxx 型別)

7. 使用範例

以下是 AST 如何表示一個簡單的 ST 程式的範例:

FUNCTION Add : INT
VAR_INPUT
  a, b : INT;
END_VAR
  Add := a + b;
END_FUNCTION

對應的 AST 結構:

  • function_declaration_c
    • derived_function_name -> identifier_c ("Add")
    • type_name -> int_type_name_c
    • var_declarations_list -> var_declarations_list_c
      • input_declarations_c
        • var1_init_decl_c
          • var1_list_c -> ["a", "b"]
          • simple_specification -> int_type_name_c
    • function_body -> statement_list_c
      • assignment_statement_c
        • l_exp -> identifier_c ("Add")
        • r_exp -> add_expression_c
          • l_exp -> symbolic_variable_c ("a")
          • r_exp -> symbolic_variable_c ("b")

這個結構完整地捕捉了程式的語義,為後續階段的語意分析和程式碼生成提供了基礎。

總結

stage1_2 目錄中的抽象語法樹結構是 matiec 編譯器的核心。它透過一個層次清晰、設計良好的節點層次結構,完整表示了 IEC 61131-3 標準的所有語言特性。這個 AST 不僅支持標準的五種程式語言 (ST, IL, LD, FBD, SFC),還提供了擴展功能和安全相關特性。通過這個 AST,編譯器能夠執行語意分析、型別檢查,並最終生成目標程式碼。