`stage1_2` 目錄中抽象語法樹 (AST) 基本結構完整探討 3.7 CT - benchen2001/matiec GitHub Wiki

stage1_2 目錄中抽象語法樹 (AST) 基本結構完整探討

一、AST 核心基礎類別

1. symbol_c (基礎抽象類別)

  • 定義位置src/absyntax/absyntax.hh
  • 功能:所有 AST 節點的基礎類別
  • 重要成員
    • 位置資訊:first_linefirst_columnfirst_filefirst_order
    • 型別資訊:datatype(節點型別)、candidate_datatypes(可能型別清單)
    • Visitor 支援:accept(visitor_c &visitor) 虛擬方法
  • 特點:提供基本位置追踪、型別標記及 Visitor 模式支援

2. token_c (詞法單元基類)

  • 定義位置src/absyntax/absyntax.hh
  • 繼承自symbol_c
  • 額外成員value(儲存詞法單元的實際字串值)
  • 用途:表示終端符號(如識別字、常數、關鍵字等)

3. list_c (節點列表基類)

  • 定義位置src/absyntax/absyntax.hh
  • 繼承自symbol_c
  • 功能:管理一組 AST 節點(子節點列表)
  • 主要方法
    • add_element(symbol_c *element):新增元素
    • n:列表元素數量
    • elements[]:儲存元素的陣列

二、AST 節點自動生成巨集

1. 節點巨集類型

  • SYM_TOKEN(class_name_c, ...):生成詞法單元節點類別

    class class_name_c: public token_c {
      // ...
    }
    
  • SYM_REFx(class_name_c, ref1, ref2, ...):生成有 x 個子節點的節點類別

    class class_name_c: public symbol_c {
      symbol_c *ref1;  // 第一個子節點
      symbol_c *ref2;  // 第二個子節點
      // ...最多到 ref6
    }
    
  • SYM_LIST(class_name_c, ...):生成節點列表類別

    class class_name_c: public list_c {
      // ...
    }
    

2. 巨集展開示例

// 定義一個詞法單元類別
SYM_TOKEN(identifier_c)

// 定義一個二元表達式節點(兩個子節點)
SYM_REF2(add_expression_c, l_exp, r_exp)

// 定義一個語句列表類別
SYM_LIST(statement_list_c)

三、AST 節點分類(依語法結構)

1. 詞法單元(Terminals)

  • 識別字identifier_cderived_datatype_identifier_cpoutype_identifier_c
  • 常數
    • 數值:integer_creal_cbinary_integer_coctal_integer_chex_integer_c
    • 布林:boolean_true_cboolean_false_c
    • 字串:single_byte_character_string_cdouble_byte_character_string_c
    • 時間:duration_ctime_of_day_cdate_cdate_and_time_c

2. 資料型別(Data Types)

  • 基本型別bool_type_name_cint_type_name_creal_type_name_ctime_type_name_c
  • 型別宣告
    • simple_type_declaration_c:簡單型別定義
    • subrange_type_declaration_c:子範圍型別(如 INT(0..100)
    • enumerated_type_declaration_c:列舉型別
    • array_type_declaration_c:陣列型別
    • structure_type_declaration_c:結構型別

3. 變數與宣告(Variables & Declarations)

  • 變數存取
    • 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)
  • 變數宣告項目
    • var1_init_decl_c:單一變數宣告與初始化
    • array_var_init_decl_c:陣列變數宣告與初始化
    • structured_var_init_decl_c:結構變數宣告與初始化

4. 程式組織單元(POUs)

  • function_declaration_c:函式宣告
  • function_block_declaration_c:功能塊宣告(如範例中的 AVERAGE
  • program_declaration_c:程式宣告

5. 語句與表達式(Statements & Expressions)

  • 語句
    • assignment_statement_c:賦值語句(如 SUM := SUM + FIFO.XOUT
    • if_statement_c:條件語句(如範例中的 IF RUN THEN ... ELSE ... END_IF
    • case_statement_cfor_statement_cwhile_statement_crepeat_statement_c
  • 表達式
    • 算術運算:add_expression_csub_expression_cmul_expression_cdiv_expression_c
    • 邏輯運算:and_expression_cor_expression_cxor_expression_c
    • 關係運算:equ_expression_clt_expression_cgt_expression_c
  • 函式呼叫
    • function_invocation_c:函式呼叫
    • fb_invocation_c:功能塊呼叫(如範例中的 FIFO(...)

6. 特定語言元素

  • IL 指令LD_operator_cST_operator_cADD_operator_c
  • SFC 元素step_ctransition_caction_csequential_function_chart_c

四、AST 結構範例(以 AVERAGE 功能塊為例)

以提供的 AVERAGE 功能塊為例,其 AST 結構如下:

function_block_declaration_c
├── identifier_c ("AVERAGE")
├── NULL (無返回型別)
├── var_declarations_list_c
│   ├── input_declarations_c
│   │   ├── var1_init_decl_c 
│   │   │   ├── var1_list_c
│   │   │   │   └── identifier_c ("RUN")
│   │   │   └── bool_type_name_c
│   │   ├── var1_init_decl_c
│   │   │   ├── var1_list_c
│   │   │   │   └── identifier_c ("XIN")
│   │   │   └── real_type_name_c
│   │   └── var1_init_decl_c
│   │       ├── var1_list_c
│   │       │   └── identifier_c ("N")
│   │       └── int_type_name_c
│   ├── output_declarations_c
│   │   └── var1_init_decl_c
│   │       ├── var1_list_c
│   │       │   └── identifier_c ("XOUT")
│   │       └── real_type_name_c
│   └── var_declarations_c
│       ├── var1_init_decl_c (SUM)
│       │   ├── var1_list_c
│       │   │   └── identifier_c ("SUM")
│       │   ├── real_type_name_c
│       │   └── real_c ("0.0")
│       └── var1_init_decl_c (FIFO)
│           ├── var1_list_c
│           │   └── identifier_c ("FIFO")
│           └── identifier_c ("DELAY")
└── function_block_body_c
    └── statement_list_c
        ├── assignment_statement_c
        │   ├── symbolic_variable_c ("SUM")
        │   └── sub_expression_c
        │       ├── symbolic_variable_c ("SUM")
        │       └── structured_variable_c
        │           ├── symbolic_variable_c ("FIFO")
        │           └── identifier_c ("XOUT")
        ├── fb_invocation_c (FIFO)
        │   ├── identifier_c ("FIFO")
        │   └── param_assignment_list_c
        │       ├── param_assignment_c
        │       │   ├── identifier_c ("RUN")
        │       │   └── symbolic_variable_c ("RUN")
        │       ├── param_assignment_c
        │       │   ├── identifier_c ("XIN")
        │       │   └── symbolic_variable_c ("XIN")
        │       └── param_assignment_c
        │           ├── identifier_c ("N")
        │           └── symbolic_variable_c ("N")
        ├── assignment_statement_c (SUM := SUM + FIFO.XOUT)
        └── if_statement_c
            ├── symbolic_variable_c ("RUN")
            ├── statement_list_c
            │   └── assignment_statement_c (XOUT := SUM/N)
            └── statement_list_c
                ├── assignment_statement_c (SUM := N*XIN)
                └── assignment_statement_c (XOUT := XIN)

五、AST 構建過程

  1. 詞法分析 - src/stage1_2/iec_flex.ll 將源代碼分解成標記
  2. 語法分析 - src/stage1_2/iec_bison.yy 根據語法規則構建 AST
    • 使用 YACC/Bison 定義的語法規則
    • 在語法規則動作中構建 AST 節點
  3. 創建節點 - 使用如 new_identifier(), new_function_block_declaration() 等函數
  4. AST 優化 - 可能進行初步優化,如消除不必要的節點

六、技術亮點與設計特色

  1. 多階段設計:清晰分離詞法分析、語法分析和 AST 構建
  2. 通用節點基類:所有節點繼承自 symbol_c,支援多型處理
  3. 巨集自動生成:使用巨集大量減少重複代碼
  4. 完整位置資訊:每個節點保留源代碼位置,便於錯誤報告
  5. Visitor 模式支援:所有節點實現 accept() 方法,便於遍歷和變換
  6. 型別系統整合:AST 節點預留了型別資訊欄位,便於後續型別檢查
  7. 模組化結構:不同語言特性(ST、IL、SFC等)有專門的節點類別

七、小結

matiec 編譯器的 stage1_2 目錄中的抽象語法樹設計充分體現了編譯器構建的現代化思想。它通過三種基本節點類型(symbol_ctoken_clist_c)和一系列巨集自動生成的具體節點類別,完整表達了 IEC 61131-3 標準中的所有語言特性。這種設計不僅模組化程度高、擴展性好,而且為後續的語意分析和代碼生成階段提供了堅實的基礎。