`stage1_2` 目錄中抽象語法樹 (AST) 基本結構完整探討 3.7 CT - benchen2001/matiec GitHub Wiki
stage1_2 目錄中抽象語法樹 (AST) 基本結構完整探討
一、AST 核心基礎類別
1. symbol_c (基礎抽象類別)
- 定義位置:
src/absyntax/absyntax.hh - 功能:所有 AST 節點的基礎類別
- 重要成員:
- 位置資訊:
first_line、first_column、first_file、first_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_c、derived_datatype_identifier_c、poutype_identifier_c - 常數:
- 數值:
integer_c、real_c、binary_integer_c、octal_integer_c、hex_integer_c - 布林:
boolean_true_c、boolean_false_c - 字串:
single_byte_character_string_c、double_byte_character_string_c - 時間:
duration_c、time_of_day_c、date_c、date_and_time_c
- 數值:
2. 資料型別(Data Types)
- 基本型別:
bool_type_name_c、int_type_name_c、real_type_name_c、time_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_c、for_statement_c、while_statement_c、repeat_statement_c
- 表達式:
- 算術運算:
add_expression_c、sub_expression_c、mul_expression_c、div_expression_c - 邏輯運算:
and_expression_c、or_expression_c、xor_expression_c - 關係運算:
equ_expression_c、lt_expression_c、gt_expression_c等
- 算術運算:
- 函式呼叫:
function_invocation_c:函式呼叫fb_invocation_c:功能塊呼叫(如範例中的FIFO(...))
6. 特定語言元素
- IL 指令:
LD_operator_c、ST_operator_c、ADD_operator_c等 - SFC 元素:
step_c、transition_c、action_c、sequential_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 構建過程
- 詞法分析 -
src/stage1_2/iec_flex.ll將源代碼分解成標記 - 語法分析 -
src/stage1_2/iec_bison.yy根據語法規則構建 AST- 使用 YACC/Bison 定義的語法規則
- 在語法規則動作中構建 AST 節點
- 創建節點 - 使用如
new_identifier(),new_function_block_declaration()等函數 - AST 優化 - 可能進行初步優化,如消除不必要的節點
六、技術亮點與設計特色
- 多階段設計:清晰分離詞法分析、語法分析和 AST 構建
- 通用節點基類:所有節點繼承自
symbol_c,支援多型處理 - 巨集自動生成:使用巨集大量減少重複代碼
- 完整位置資訊:每個節點保留源代碼位置,便於錯誤報告
- Visitor 模式支援:所有節點實現
accept()方法,便於遍歷和變換 - 型別系統整合:AST 節點預留了型別資訊欄位,便於後續型別檢查
- 模組化結構:不同語言特性(ST、IL、SFC等)有專門的節點類別
七、小結
matiec 編譯器的 stage1_2 目錄中的抽象語法樹設計充分體現了編譯器構建的現代化思想。它通過三種基本節點類型(symbol_c、token_c、list_c)和一系列巨集自動生成的具體節點類別,完整表達了 IEC 61131-3 標準中的所有語言特性。這種設計不僅模組化程度高、擴展性好,而且為後續的語意分析和代碼生成階段提供了堅實的基礎。