onion_frontend/parser/
ast.rs

1//! AST 解析模块:将 Token 流转换为抽象语法树(AST)。
2//!
3//! 本模块实现了 Onion 语言的语法分析器,将词法分析产生的 Token 流转换为
4//! 结构化的抽象语法树。支持丰富的语法结构,包括表达式、控制流、函数定义、
5//! 类型系统、模式匹配等。
6//!
7//! # Onion 语言语法结构
8//!
9//! ## 基础语法
10//! - **字面量**:`42`, `"hello"`, `true`, `false`, `null`, `undefined`
11//! - **变量**:`variable_name`
12//! - **元组**:`x, y, z` 或 `(x, y, z)`
13//! - **对象**:`{...}` 块作用域
14//!
15//! ## 表达式
16//! - **算术运算**:`+`, `-`, `*`, `/`, `%`, `**` (幂运算)
17//! - **比较运算**:`==`, `!=`, `>`, `<`, `>=`, `<=`
18//! - **逻辑运算**:`and`, `or`, `xor`, `not`
19//! - **位运算**:`<<`, `>>` (位移)
20//! - **一元运算**:`-x` (负号), `+x` (绝对值)
21//!
22//! ## 变量与赋值
23//! - **变量定义**:`x := value` (let binding)
24//! - **变量赋值**:`x = value` (assignment)
25//! - **模式匹配**:`key: value` (pair), `key => value` (named pair)
26//!
27//! ## 函数与 Lambda
28//! - **函数定义**:`params -> body` (静态函数)
29//! - **动态函数**:`params -> dyn body` (动态函数)
30//! - **捕获变量**:`params -> & captured_vars body`
31//! - **函数调用**:`func args`
32//!
33//! ## 控制流
34//! - **条件判断**:`if condition body` 或 `if condition body else else_body`
35//! - **循环**:`while condition body`
36//! - **跳转**:`break value`, `continue value`, `return value`, `raise error`
37//!
38//! ## 高级特性
39//! - **范围**:`start..end`
40//! - **成员访问**:`object.member`
41//! - **包含检查**:`element in container`
42//! - **同一性检查**:`x is y`
43//! - **类型转换**:`value as type`
44//! - **集合操作**:`collection | filter` (set), `collection |> map` (map)
45//!
46//! ## 修饰符
47//! - **可变性**:`mut`, `const`
48//! - **类型查询**:`typeof`, `keyof`, `valueof`, `lengthof`
49//! - **断言**:`assert condition`
50//! - **导入**:`import module`
51//! - **并发**:`launch`, `spawn`, `async`, `sync`, `atomic`
52//!
53//! ## 编译时特性
54//! - **编译时求值**:`@ expression`
55//! - **AST 序列化**:`$ expression`
56//! - **动态/静态模式**:`dynamic expression`, `static expression`
57//! - **命名空间**:`Type::value`
58//! - **假设元组**:`...value`
59//! - **快速命名**:`expression ?`
60//!
61//! # 用法示例
62//! ```ignore
63//! let tokens = tokenize(source);
64//! let gathered = ast_token_stream::from_stream(&tokens);
65//! let ast = build_ast(&mut diagnostics, gathered)?;
66//! ```
67
68use base64::Engine;
69use serde::{Deserialize, Serialize};
70
71use crate::{
72    diagnostics::{Diagnostic, SourceLocation, collector::DiagnosticCollector},
73    parser::lexer::{Token, TokenType},
74};
75use std::{
76    collections::HashSet,
77    fmt::{self, Debug, Display, Formatter},
78    vec,
79};
80
81/// AST 解析诊断信息类型。
82///
83/// 封装语法分析过程中可能出现的各种错误类型。
84#[derive(Debug, Clone)]
85pub enum ASTParseDiagnostic {
86    /// 意外的 Token。
87    UnexpectedToken(Option<SourceLocation>),
88    /// 括号不匹配。
89    UnmatchedParenthesis(Option<SourceLocation>),
90    /// 无效的变量名。
91    InvalidVariableName(Option<SourceLocation>),
92    /// 不支持的语法结构。
93    UnsupportedStructure(Option<SourceLocation>),
94    /// 缺少必要的语法结构。
95    MissingStructure(Option<SourceLocation>, String),
96    /// 无效的语法。
97    InvalidSyntax(Option<SourceLocation>, String),
98}
99
100impl Diagnostic for ASTParseDiagnostic {
101    fn severity(&self) -> crate::diagnostics::ReportSeverity {
102        match self {
103            ASTParseDiagnostic::UnexpectedToken(_) => crate::diagnostics::ReportSeverity::Error,
104            ASTParseDiagnostic::UnmatchedParenthesis(_) => {
105                crate::diagnostics::ReportSeverity::Error
106            }
107            ASTParseDiagnostic::InvalidVariableName(_) => crate::diagnostics::ReportSeverity::Error,
108            ASTParseDiagnostic::UnsupportedStructure(_) => {
109                crate::diagnostics::ReportSeverity::Error
110            }
111            ASTParseDiagnostic::MissingStructure(_, _) => crate::diagnostics::ReportSeverity::Error,
112            ASTParseDiagnostic::InvalidSyntax(_, _) => crate::diagnostics::ReportSeverity::Error,
113        }
114    }
115
116    fn title(&self) -> String {
117        "AST Parse Error".into()
118    }
119
120    fn message(&self) -> String {
121        match self {
122            ASTParseDiagnostic::UnexpectedToken(_) => "Unexpected token found".into(),
123            ASTParseDiagnostic::UnmatchedParenthesis(_) => "Unmatched parenthesis found".into(),
124            ASTParseDiagnostic::InvalidVariableName(_) => "Invalid variable name".into(),
125            ASTParseDiagnostic::UnsupportedStructure(_) => "Unsupported structure".into(),
126            ASTParseDiagnostic::MissingStructure(_, expected) => {
127                format!("Missing structure: {}", expected)
128            }
129            ASTParseDiagnostic::InvalidSyntax(_, expected) => {
130                format!("Invalid syntax: {}", expected)
131            }
132        }
133    }
134
135    fn location(&self) -> Option<SourceLocation> {
136        match self {
137            ASTParseDiagnostic::UnexpectedToken(loc) => loc.clone(),
138            ASTParseDiagnostic::UnmatchedParenthesis(loc) => loc.clone(),
139            ASTParseDiagnostic::InvalidVariableName(loc) => loc.clone(),
140            ASTParseDiagnostic::UnsupportedStructure(loc) => loc.clone(),
141            ASTParseDiagnostic::MissingStructure(loc, _) => loc.clone(),
142            ASTParseDiagnostic::InvalidSyntax(loc, _) => loc.clone(),
143        }
144    }
145
146    fn help(&self) -> Option<String> {
147        match self {
148            ASTParseDiagnostic::UnexpectedToken(_) => Some("Check the syntax near the unexpected token.".into()),
149            ASTParseDiagnostic::UnmatchedParenthesis(_) => Some("Ensure all parentheses are properly matched.".into()),
150            ASTParseDiagnostic::InvalidVariableName(_) => Some("Variable names must start with a letter and can only contain letters, numbers, and underscores.".into()),
151            ASTParseDiagnostic::UnsupportedStructure(_) => None,
152            ASTParseDiagnostic::MissingStructure(_, _) => None,
153            ASTParseDiagnostic::InvalidSyntax(_, _) => None,
154        }
155    }
156
157    fn copy(&self) -> Box<dyn Diagnostic> {
158        Box::new(self.clone())
159    }
160}
161
162/// Token 流类型别名。
163pub type TokenStream = Vec<Token>;
164/// 收集的 Token 片段类型别名。
165pub type GatheredTokens<'t> = &'t [Token];
166
167/// AST Token 流处理模块。
168pub mod ast_token_stream {
169    /// 从 Token 流创建收集的 Token 片段。
170    pub fn from_stream<'t>(stream: &'t super::TokenStream) -> super::GatheredTokens<'t> {
171        stream.as_slice()
172    }
173}
174
175/// 获取下一个平衡的 Token 组。
176///
177/// 处理括号、方括号、花括号的匹配,确保返回的 Token 组语法完整。
178fn get_next_tokens<'a, 'b>(
179    collector: &'a mut DiagnosticCollector,
180    tokens: GatheredTokens<'b>,
181    offset: usize,
182) -> Result<GatheredTokens<'b>, ()> {
183    let mut stack = Vec::<&Token>::new();
184    let mut next_tokens_end = 0usize;
185    let mut index = offset;
186    if index >= tokens.len() {
187        return Ok(&[]);
188    }
189    loop {
190        if ["{", "[", "("].contains(&tokens[index].token().as_str())
191            && tokens[index] == TokenType::SYMBOL
192        {
193            stack.push(&tokens[index]);
194            next_tokens_end += 1;
195        } else if ["}", "]", ")"].contains(&tokens[index].token().as_str())
196            && tokens[index] == TokenType::SYMBOL
197        {
198            if stack.is_empty() {
199                break;
200            }
201            let last = stack.pop().unwrap();
202            if (last == "{" && tokens[index] != "}")
203                || (last == "[" && tokens[index] != "]")
204                || (last == "(" && tokens[index] != ")")
205            {
206                return collector.fatal(ASTParseDiagnostic::UnmatchedParenthesis(
207                    span_from_two_token(&last, &tokens[index]),
208                ));
209            }
210
211            next_tokens_end += 1;
212        } else {
213            next_tokens_end += 1;
214        }
215        index += 1;
216        if index >= tokens.len() || stack.is_empty() {
217            break;
218        }
219    }
220    if !stack.is_empty() {
221        let last = stack.pop().unwrap();
222        return collector.fatal(ASTParseDiagnostic::UnmatchedParenthesis(
223            span_from_two_token(&last, &tokens[offset + next_tokens_end - 1]),
224        ));
225    }
226    Ok(&tokens[offset..offset + next_tokens_end])
227}
228
229/// 将 Token 流分割为语法单元组。
230///
231/// 根据括号匹配将 Token 流分割为独立的语法单元,每个单元是一个完整的表达式。
232fn gather<'a, 'b>(
233    collector: &'a mut DiagnosticCollector,
234    tokens: GatheredTokens<'b>,
235) -> Result<Vec<GatheredTokens<'b>>, ()> {
236    let mut offset = 0;
237    let mut result = Vec::<GatheredTokens>::new();
238    while offset < tokens.len() {
239        let next_tokens = get_next_tokens(collector, tokens, offset)?;
240        if next_tokens.is_empty() {
241            return collector.fatal(ASTParseDiagnostic::UnsupportedStructure(
242                span_from_single_token(&tokens[offset]),
243            ));
244        }
245        offset += next_tokens.len();
246        result.push(next_tokens);
247    }
248    Ok(result)
249}
250
251/// AST 节点类型枚举。
252///
253/// 定义了 Onion 语言中所有可能的 AST 节点类型,对应不同的语法结构。
254///
255/// # 语法结构说明
256///
257/// ## 字面量类型
258/// - `Null`:空值 `null`
259/// - `Undefined`:未定义值 `undefined`
260/// - `String(String)`:字符串字面量 `"text"`
261/// - `Boolean(bool)`:布尔值 `true`/`false`
262/// - `Number(String)`:数值字面量 `42`, `3.14`, `0xFF`
263/// - `Base64(String)`:Base64 编码数据
264///
265/// ## 变量与标识符
266/// - `Variable(String)`:变量引用 `variable_name`
267/// - `Required(String)`:必需变量占位符 `@required "var"`
268///
269/// ## 变量操作
270/// - `Let(String)`:变量绑定 `x := value`
271/// - `Assign`:变量赋值 `x = value`
272///
273/// ## 函数与应用
274/// - `LambdaDef(bool, HashSet<String>)`:Lambda 定义 `params -> body`
275///   - 第一个参数:是否为动态函数 (`dyn`)
276///   - 第二个参数:捕获的变量集合 (`& captured_vars`)
277/// - `Apply`:函数应用 `func args`
278///
279/// ## 数据结构
280/// - `Tuple`:元组 `x, y, z`
281/// - `Pair`:键值对 `key: value`
282/// - `AssumeTuple`:假设元组 `...value`
283///
284/// ## 控制流
285/// - `If`:条件分支 `if condition body [else else_body]`
286/// - `While`:循环 `while condition body`
287/// - `Break`:跳出循环 `break value`
288/// - `Continue`:继续循环 `continue value`
289/// - `Return`:函数返回 `return value`
290/// - `Raise`:抛出异常 `raise error`
291///
292/// ## 运算符
293/// - `Operation(ASTNodeOperation)`:各种运算 `+`, `-`, `*`, `/`, `==`, 等
294///
295/// ## 高级特性
296/// - `Range`:范围 `start..end`
297/// - `In`:包含检查 `element in container`
298/// - `Is`:同一性检查 `x is y`
299/// - `GetAttr`:成员访问 `object.member`
300/// - `Set`:集合过滤 `collection | filter`
301/// - `Map`:集合映射 `collection |> map`
302/// - `Namespace(String)`:命名空间 `Type::value`
303///
304/// ## 修饰符与元操作
305/// - `Modifier(ASTNodeModifier)`:修饰符 `mut`, `const`, `typeof`, 等
306/// - `Frame`:作用域块 `{...}`
307/// - `Expressions`:表达式序列 `expr1; expr2; ...`
308///
309/// ## 编译时特性
310/// - `Dynamic`:动态模式 `dynamic expression`
311/// - `Static`:静态模式 `static expression`
312/// - `Comptime`:编译时求值 `@ expression`
313#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
314pub enum ASTNodeType {
315    Null, // Null
316    Undefined,
317    String(String), // String
318    Boolean(bool),  // Boolean
319    Number(String), // Number (Integer, Float)
320    Base64(String), // Base64
321
322    Variable(String), // Variable
323    Required(String), // 变量存在性占位符,我们不直接硬编码对应的AST,我们通过comptime中调用`required "var"`来生成
324
325    Let(String),                      // x := expression
326    Frame,                            // {...}
327    Assign,                           // x = expression
328    LambdaDef(bool, HashSet<String>), // tuple -> body or tuple -> dyn expression
329    Expressions,                      // expression1; expression2; ...
330    Apply,                            // x y
331    Operation(ASTNodeOperation),      // x + y, x - y, x * y, x / y ...
332    Tuple,                            // x, y, z, ...
333    AssumeTuple,                      // ...value
334    Pair,                             // x: y
335    GetAttr,                          // x.y
336    Return,                           // return expression
337    If,    // if expression truecondition || if expression truecondition else falsecondition
338    While, // while expression body
339    Modifier(ASTNodeModifier), // modifier expression
340    Break, // break
341    Continue, // continue
342    Range, // x..y
343    In,    // x in y
344    Namespace(String), // Type::Value
345    LazySet, // collection | filter
346    Map,   // collection |> map
347    Is,    // x is y
348    Raise, // raise expression
349
350    Dynamic, // 假设子表达式的所有变量都存在
351    Static,  // 假设子表达式的所有变量都在当前上下文中定义
352
353    Comptime, // 编译时计算的表达式
354}
355
356impl Display for ASTNodeType {
357    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
358        write!(
359            f,
360            "{}",
361            match self {
362                ASTNodeType::Null => "Null",
363                ASTNodeType::Undefined => "Undefined",
364                ASTNodeType::String(_) => "String",
365                ASTNodeType::Boolean(_) => "Boolean",
366                ASTNodeType::Number(_) => "Number",
367                ASTNodeType::Base64(_) => "Base64",
368                ASTNodeType::Variable(_) => "Variable",
369                ASTNodeType::Required(_) => "Required",
370                ASTNodeType::Let(_) => "Let",
371                ASTNodeType::Frame => "Frame",
372                ASTNodeType::Assign => "Assign",
373                ASTNodeType::LambdaDef(_, _) => "LambdaDef",
374                ASTNodeType::Expressions => "Expressions",
375                ASTNodeType::Apply => "Apply",
376                ASTNodeType::Operation(_) => "Operation",
377                ASTNodeType::Tuple => "Tuple",
378                ASTNodeType::AssumeTuple => "AssumeTuple",
379                ASTNodeType::Pair => "Pair",
380                ASTNodeType::GetAttr => "GetAttr",
381                ASTNodeType::Return => "Return",
382                ASTNodeType::If => "If",
383                ASTNodeType::While => "While",
384                ASTNodeType::Modifier(_) => "Modifier",
385                ASTNodeType::Break => "Break",
386                ASTNodeType::Continue => "Continue",
387                ASTNodeType::Range => "Range",
388                ASTNodeType::In => "In",
389                ASTNodeType::Namespace(_) => "Namespace",
390                ASTNodeType::LazySet => "LazySet",
391                ASTNodeType::Map => "Map",
392                ASTNodeType::Is => "Is",
393                ASTNodeType::Raise => "Raise",
394                ASTNodeType::Dynamic => "Dynamic",
395                ASTNodeType::Static => "Static",
396                ASTNodeType::Comptime => "Comptime",
397            }
398        )
399    }
400}
401
402/// AST 运算符枚举。
403///
404/// 定义了 Onion 语言中所有支持的运算符及其操作类型。
405///
406/// # 运算符类型
407///
408/// ## 算术运算符 (二元)
409/// - `Add`:加法 `+`
410/// - `Subtract`:减法 `-`
411/// - `Multiply`:乘法 `*`
412/// - `Divide`:除法 `/`
413/// - `Modulus`:取模 `%`
414/// - `Power`:幂运算 `**`
415///
416/// ## 位运算符 (二元)
417/// - `And`:按位与 `and`
418/// - `Or`:按位或 `or`
419/// - `Xor`:按位异或 `xor`
420/// - `LeftShift`:左移 `<<`
421/// - `RightShift`:右移 `>>`
422///
423/// ## 比较运算符 (二元)
424/// - `Equal`:等于 `==`
425/// - `NotEqual`:不等于 `!=`
426/// - `Less`:小于 `<`
427/// - `LessEqual`:小于等于 `<=`
428/// - `Greater`:大于 `>`
429/// - `GreaterEqual`:大于等于 `>=`
430///
431/// ## 一元运算符
432/// - `Not`:逻辑非 `not`
433/// - `Minus`:数值取负 `-`
434/// - `Abs`:绝对值 `abs`
435#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
436pub enum ASTNodeOperation {
437    Add,          // +
438    Subtract,     // -
439    Multiply,     // *
440    Divide,       // /
441    Modulus,      // %
442    Power,        // **
443    And,          // and
444    Xor,          // xor
445    Or,           // or
446    Not,          // not
447    Equal,        // ==
448    NotEqual,     // !=
449    Greater,      // >
450    Less,         // <
451    GreaterEqual, // >=
452    LessEqual,    // <=
453    LeftShift,    // << (left shift)
454    RightShift,   // >> (right shift)
455    Abs,          // 一元绝对值
456    Minus,        // 一元负号
457}
458
459/// AST 修饰符枚举。
460///
461/// 定义了 Onion 语言中所有可用的修饰符,用于修改表达式的语义。
462///
463/// # 修饰符类型
464///
465/// ## 变量修饰符
466/// - `Mut`:可变修饰符 `mut variable`,声明变量可以被修改
467/// - `Const`:常量修饰符 `const variable`,声明变量为常量
468///
469/// ## 类型操作修饰符
470/// - `KeyOf`:键类型提取 `keyof object`,获取对象的键类型
471/// - `ValueOf`:值类型提取 `valueof object`,获取对象的值类型
472/// - `TypeOf`:类型提取 `typeof expression`,获取表达式的类型
473/// - `LengthOf`:长度提取 `lengthof collection`,获取集合的长度
474///
475/// ## 函数调度修饰符
476/// - `Launch`:并行启动 `launch expression`,在新线程中执行表达式
477/// - `Spawn`:异步启动 `spawn expression`,在异步上下文中执行表达式
478/// - `Async`:异步修饰符 `async function`,声明函数为异步调度入口
479/// - `Sync`:同步修饰符 `sync function`,声明函数为同步调度入口
480/// - `Atomic`:原子操作修饰符 `atomic expression`,移除表达式的调度修饰作为标准函数调用
481///
482/// ## 其他修饰符
483/// - `Assert`:断言 `assert condition`,在运行时检查条件
484/// - `Import`:导入模块 `import module`,引入外部字节码
485#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
486pub enum ASTNodeModifier {
487    Mut,      // Mut
488    Const,    // Const
489    KeyOf,    // KeyOf
490    ValueOf,  // ValueOf
491    Assert,   // Assert
492    Import,   // Import
493    TypeOf,   // TypeOf
494    LengthOf, // LengthOf
495    Launch,   // Launch
496    Spawn,    // Spawn
497    Async,    // Async
498    Sync,     // Sync
499    Atomic,   // Atomic
500}
501
502/// AST 节点结构体。
503///
504/// 表示 Onion 语言的抽象语法树节点,是构成整个语法树的基本单元。
505///
506/// # 字段说明
507/// - `node_type`:节点类型,定义了该节点的语法角色和语义
508/// - `source_location`:源码位置信息,用于错误报告和调试
509/// - `children`:子节点列表,构成树形结构
510///
511/// # 设计原则
512///
513/// ## 递归结构
514/// AST 节点通过 `children` 字段形成递归的树形结构,每个节点可以包含任意数量的子节点。
515///
516/// ## 位置信息
517/// 每个节点都可以携带源码位置信息,便于在编译时提供准确的错误定位。
518///
519/// ## 类型安全
520/// 通过 `ASTNodeType` 枚举确保节点类型的类型安全,避免无效的语法树结构。
521#[derive(Debug, Clone, Serialize, Deserialize)]
522pub struct ASTNode {
523    pub node_type: ASTNodeType,                  // Type of the node
524    pub source_location: Option<SourceLocation>, // Source location for error reporting
525    pub children: Vec<ASTNode>,                  // Children of the node
526}
527
528impl PartialEq for ASTNode {
529    fn eq(&self, other: &Self) -> bool {
530        self.node_type == other.node_type && self.children == other.children
531    }
532}
533
534impl ASTNode {
535    /// 创建新的 AST 节点。
536    ///
537    /// # 参数
538    /// - `node_type`:节点类型
539    /// - `source_location`:源码位置信息(可选)
540    /// - `children`:子节点列表
541    ///
542    /// # 返回
543    /// 新创建的 AST 节点实例
544    pub fn new(
545        node_type: ASTNodeType,
546        source_location: Option<SourceLocation>,
547        children: Vec<ASTNode>,
548    ) -> ASTNode {
549        ASTNode {
550            node_type,
551            source_location,
552            children,
553        }
554    }
555
556    /// 格式化打印 AST 节点树。
557    ///
558    /// 以缩进的形式递归打印整个 AST 结构,用于调试和可视化。
559    ///
560    /// # 参数
561    /// - `indent`:当前缩进级别
562    #[allow(unused)]
563    pub fn formatted_print(&self, indent: usize) {
564        let indent_str = " ".repeat(indent);
565        let output = match &self.node_type {
566            node_type @ (ASTNodeType::Variable(v)
567            | ASTNodeType::Number(v)
568            | ASTNodeType::String(v)) => {
569                format!("{}{:?}: {:?}", indent_str, node_type, v)
570            }
571            node_type @ ASTNodeType::Boolean(v) => {
572                format!("{}{:?}: {:?}", indent_str, node_type, v)
573            }
574            node_type => format!("{}{:?}", indent_str, node_type),
575        };
576
577        println!("{}", output);
578
579        if !self.children.is_empty() {
580            for child in &self.children {
581                child.formatted_print(indent + 2);
582            }
583        }
584    }
585}
586
587/// 匹配器函数类型。
588///
589/// 定义了语法解析匹配器的函数签名。
590///
591/// # 参数
592/// - `&mut DiagnosticCollector`:诊断信息收集器
593/// - `&[GatheredTokens]`:待解析的 Token 组
594///
595/// # 返回
596/// - `Ok(Some(ASTNode))`:成功匹配并生成 AST 节点
597/// - `Ok(None)`:无法匹配当前模式
598/// - `Err(())`:解析出现致命错误
599type MatcherFn = fn(&mut DiagnosticCollector, &[GatheredTokens]) -> Result<Option<ASTNode>, ()>;
600
601/// 节点匹配器结构体。
602///
603/// 包含多个匹配器函数,用于按优先级尝试解析不同的语法模式。
604struct NodeMatcher {
605    matchers: Vec<MatcherFn>,
606}
607
608/// 从 Token 组生成源码位置信息。
609///
610/// 计算一组 Token 片段覆盖的源码范围,用于错误报告。
611///
612/// # 参数
613/// - `tokens`:Token 组数组
614///
615/// # 返回
616/// 包含起始和结束位置的源码位置信息
617fn span_from_tokens(tokens: &[GatheredTokens]) -> Option<SourceLocation> {
618    if tokens.is_empty() {
619        return None;
620    }
621    let first_token = tokens.first().and_then(|t| t.first());
622    let last_token = tokens.last().and_then(|t| t.last());
623    if let (Some(start_loc), Some(end_loc)) = (first_token, last_token) {
624        if start_loc.source_code().eq(end_loc.source_code()) {
625            return Some(SourceLocation {
626                span: (
627                    start_loc.origin_token_span().0,
628                    end_loc.origin_token_span().1,
629                ),
630                source: start_loc.source_code().clone(),
631            });
632        }
633    }
634    None
635}
636
637/// 从两个 Token 生成源码位置信息。
638///
639/// 计算从起始 Token 到结束 Token 的源码范围。
640///
641/// # 参数
642/// - `start`:起始 Token
643/// - `end`:结束 Token
644///
645/// # 返回
646/// 包含两个 Token 之间范围的源码位置信息
647fn span_from_two_token(start: &Token, end: &Token) -> Option<SourceLocation> {
648    if start.source_code().eq(end.source_code()) {
649        return Some(SourceLocation {
650            span: (start.origin_token_span().0, end.origin_token_span().1),
651            source: start.source_code().clone(),
652        });
653    }
654    None
655}
656
657/// 从单个 Token 生成源码位置信息。
658///
659/// 获取单个 Token 的源码位置信息。
660///
661/// # 参数
662/// - `token`:目标 Token
663///
664/// # 返回
665/// Token 的源码位置信息
666fn span_from_single_token(token: &Token) -> Option<SourceLocation> {
667    Some(SourceLocation {
668        span: token.origin_token_span(),
669        source: token.source_code().clone(),
670    })
671}
672
673impl NodeMatcher {
674    /// 创建新的节点匹配器。
675    ///
676    /// # 返回
677    /// 空的节点匹配器实例
678    fn new() -> NodeMatcher {
679        NodeMatcher {
680            matchers: Vec::new(),
681        }
682    }
683
684    /// 添加匹配器函数。
685    ///
686    /// 将新的匹配器函数添加到匹配器列表中。匹配器按添加顺序进行尝试。
687    ///
688    /// # 参数
689    /// - `matcher`:匹配器函数
690    fn add_matcher(
691        &mut self,
692        matcher: fn(&mut DiagnosticCollector, &[GatheredTokens]) -> Result<Option<ASTNode>, ()>,
693    ) {
694        self.matchers.push(matcher);
695    }
696
697    /// 尝试匹配 Token 组生成 AST 节点。
698    ///
699    /// 按优先级顺序尝试所有匹配器,直到找到可以处理当前 Token 组的匹配器。
700    ///
701    /// # 参数
702    /// - `collector`:诊断信息收集器
703    /// - `tokens`:待解析的 Token 组
704    ///
705    /// # 返回
706    /// - `Ok(ASTNode)`:成功生成的 AST 节点
707    /// - `Err(())`:所有匹配器都无法处理或出现错误
708    #[stacksafe::stacksafe]
709    fn match_node(
710        &self,
711        collector: &mut DiagnosticCollector,
712        tokens: &[GatheredTokens],
713    ) -> Result<Option<ASTNode>, ()> {
714        if tokens.is_empty() {
715            return Ok(Some(ASTNode::new(ASTNodeType::Tuple, None, vec![])));
716        }
717        let mut best_match: Option<ASTNode> = None;
718        // 遍历所有注册的语法规则匹配器
719        for matcher in &self.matchers {
720            match matcher(collector, tokens) {
721                Ok(Some(node)) => {
722                    // 更新最佳匹配
723                    best_match = Some(node);
724                    break;
725                }
726                Ok(None) => {
727                    // 匹配器明确表示不匹配,继续尝试下一个匹配器
728                    continue;
729                }
730                Err(e) => {
731                    // 如果一个匹配器内部出错,可以选择立即返回错误,或者忽略并尝试下一个
732                    // 这里我们选择立即返回,因为这通常意味着一个严重的、意外的问题
733                    return Err(e);
734                }
735            }
736        }
737
738        // 返回找到的最佳匹配
739        match best_match {
740            Some(node) => Ok(Some(node)),
741            None => {
742                return collector.fatal(ASTParseDiagnostic::UnsupportedStructure(
743                    span_from_tokens(tokens),
744                ));
745            }
746        }
747    }
748}
749
750/// 检查 Token 组是否为指定符号。
751///
752/// 验证 Token 组是否包含单个符号 Token 且匹配指定的符号字符串。
753///
754/// # 参数
755/// - `token`:Token 组
756/// - `symbol`:要匹配的符号字符串
757///
758/// # 返回
759/// 如果匹配则返回 `true`,否则返回 `false`
760fn is_symbol(token: &GatheredTokens, symbol: &str) -> bool {
761    if token.len() != 1 {
762        return false;
763    }
764    let token = &token[0];
765    token == TokenType::SYMBOL && token == symbol
766}
767
768/// 检查 Token 组是否为指定标识符。
769///
770/// 验证 Token 组是否包含单个标识符 Token 且匹配指定的标识符字符串。
771///
772/// # 参数
773/// - `token`:Token 组
774/// - `identifier`:要匹配的标识符字符串
775///
776/// # 返回
777/// 如果匹配则返回 `true`,否则返回 `false`
778fn is_identifier(token: &GatheredTokens, identifier: &str) -> bool {
779    if token.len() != 1 {
780        return false;
781    }
782    let token = &token[0];
783    token == TokenType::IDENTIFIER && token == identifier
784}
785
786/// 解包括号包围的 Token 组。
787fn unwrap_brace<'t, 'a>(
788    collector: &'a mut DiagnosticCollector,
789    token: &GatheredTokens<'t>,
790) -> Result<GatheredTokens<'t>, ()> {
791    if token.len() < 2 {
792        return collector.fatal(ASTParseDiagnostic::UnexpectedToken(span_from_single_token(
793            &token[0],
794        )));
795    }
796    if token[0] == TokenType::SYMBOL
797        && token[0] == "{"
798        && token.last().unwrap() == TokenType::SYMBOL
799        && token.last().unwrap() == "}"
800    {
801        return Ok(&token[1..token.len() - 1]);
802    }
803    if token[0] == TokenType::SYMBOL
804        && token[0] == "["
805        && token.last().unwrap() == TokenType::SYMBOL
806        && token.last().unwrap() == "]"
807    {
808        return Ok(&token[1..token.len() - 1]);
809    }
810    if token[0] == TokenType::SYMBOL
811        && token[0] == "("
812        && token.last().unwrap() == TokenType::SYMBOL
813        && token.last().unwrap() == ")"
814    {
815        return Ok(&token[1..token.len() - 1]);
816    }
817    collector.fatal(ASTParseDiagnostic::UnexpectedToken(span_from_single_token(
818        &token[0],
819    )))
820}
821
822/// 检查 Token 组是否为括号包围的内容。
823///
824/// 验证 Token 组是否以 `(` 开始并以 `)` 结束。
825///
826/// # 参数
827/// - `token`:Token 组
828///
829/// # 返回
830/// 如果是括号包围则返回 `true`,否则返回 `false`
831fn is_bracket(token: &GatheredTokens) -> bool {
832    if token.len() < 2 {
833        return false;
834    }
835    token[0] == TokenType::SYMBOL
836        && token[0] == "("
837        && token.last().unwrap() == TokenType::SYMBOL
838        && token.last().unwrap() == ")"
839}
840
841/// 检查 Token 组是否为花括号包围的内容。
842///
843/// 验证 Token 组是否以 `{` 开始并以 `}` 结束。
844///
845/// # 参数
846/// - `token`:Token 组
847///
848/// # 返回
849/// 如果是花括号包围则返回 `true`,否则返回 `false`
850fn is_brace(token: &GatheredTokens) -> bool {
851    if token.len() < 2 {
852        return false;
853    }
854    token[0] == TokenType::SYMBOL
855        && token[0] == "{"
856        && token.last().unwrap() == TokenType::SYMBOL
857        && token.last().unwrap() == "}"
858}
859
860/// 检查 Token 组是否为方括号包围的内容。
861///
862/// 验证 Token 组是否以 `[` 开始并以 `]` 结束。
863///
864/// # 参数
865/// - `token`:Token 组
866///
867/// # 返回
868/// 如果是方括号包围则返回 `true`,否则返回 `false`
869fn is_square_bracket(token: &GatheredTokens) -> bool {
870    if token.len() < 2 {
871        return false;
872    }
873    token[0] == TokenType::SYMBOL
874        && token[0] == "["
875        && token.last().unwrap() == TokenType::SYMBOL
876        && token.last().unwrap() == "]"
877}
878
879/// 构建抽象语法树。
880///
881/// 这是 AST 构建的主入口函数,将词法分析后的 Token 流转换为 AST。
882///
883/// # 参数
884/// - `collector`:诊断信息收集器,用于收集解析过程中的错误和警告
885/// - `tokens`:词法分析后的 Token 流
886///
887/// # 返回
888/// - `Ok(ASTNode)`:成功构建的 AST 根节点
889/// - `Err(())`:解析失败,错误信息已添加到收集器中
890///
891/// # 解析流程
892/// 1. 使用 `gather` 函数将 Token 流分组为语法单元
893/// 2. 使用 `match_all` 函数尝试匹配各种语法模式
894/// 3. 如果没有匹配到任何模式,返回空元组节点
895/// 4. 否则返回匹配成功的 AST 节点
896pub fn build_ast(
897    collector: &mut DiagnosticCollector,
898    tokens: GatheredTokens<'_>,
899) -> Result<ASTNode, ()> {
900    let gathered = gather(collector, tokens)?;
901    let matched = match_all(collector, &gathered)?;
902    if matched.is_none() {
903        return Ok(ASTNode::new(ASTNodeType::Tuple, None, vec![]));
904    }
905    Ok(matched.unwrap())
906}
907
908/// 尝试匹配所有可能的语法模式。
909///
910/// 创建并配置节点匹配器,按优先级尝试所有支持的语法模式。
911///
912/// # 参数
913/// - `collector`:诊断信息收集器
914/// - `tokens`:分组后的 Token 组数组
915///
916/// # 返回
917/// - `Ok(Some(ASTNode))`:成功匹配的 AST 节点
918/// - `Ok(None)`:没有找到匹配的模式
919/// - `Err(())`:解析出现错误
920///
921/// # 支持的语法模式(按优先级)
922/// - 表达式序列:`expr1; expr2; ...`
923/// - 动态/静态模式:`dynamic expr`, `static expr`
924/// - 控制流:`return`, `break`, `continue`, `raise`
925/// - 元组:`a, b, c`
926/// - 编译时求值:`@ expr`
927/// - Base64 序列化
928/// - 变量绑定:`x := expr`
929/// - 变量赋值:`x = expr`
930/// - 集合操作:`collection |> map`, `collection | filter`
931/// - Lambda 函数:`args -> body`
932/// - 命名空间:`Type::value`
933/// - 键值对:`key: value`
934/// - 循环:`while condition body`
935/// - 条件:`if condition body [else else_body]`
936/// - 范围:`start..end`
937/// - 包含检查:`elem in collection`
938/// - 同一性检查:`x is y`
939/// - 成员访问:`obj.member`
940/// - 修饰符:`mut expr`, `const expr`, 等
941/// - 运算符:`+`, `-`, `*`, `/`, `==`, 等
942/// - 函数应用:`func args`
943/// - 变量、字面量等原子表达式
944fn match_all<'t>(
945    collector: &mut DiagnosticCollector,
946    tokens: &[GatheredTokens<'t>],
947) -> Result<Option<ASTNode>, ()> {
948    let mut node_matcher = NodeMatcher::new();
949    node_matcher.add_matcher(match_expressions);
950    node_matcher.add_matcher(match_dynamic_and_static);
951    node_matcher.add_matcher(match_return_emit_raise);
952    node_matcher.add_matcher(match_tuple);
953    node_matcher.add_matcher(match_comptime);
954    node_matcher.add_matcher(match_serialize_to_base64);
955    node_matcher.add_matcher(match_let);
956    node_matcher.add_matcher(match_assign);
957    node_matcher.add_matcher(match_map);
958    node_matcher.add_matcher(match_set_def);
959    node_matcher.add_matcher(match_lambda_def);
960    node_matcher.add_matcher(match_named_to);
961    node_matcher.add_matcher(match_pair);
962    node_matcher.add_matcher(match_while);
963    node_matcher.add_matcher(match_break_and_continue);
964    node_matcher.add_matcher(match_if);
965    node_matcher.add_matcher(match_or);
966    node_matcher.add_matcher(match_and);
967    node_matcher.add_matcher(match_xor);
968    node_matcher.add_matcher(match_not);
969    node_matcher.add_matcher(match_operation_compare);
970    node_matcher.add_matcher(match_operation_add_sub);
971    node_matcher.add_matcher(match_operation_mul_div_mod);
972    node_matcher.add_matcher(match_bitwise_shift);
973    node_matcher.add_matcher(match_unary);
974    node_matcher.add_matcher(match_power);
975    node_matcher.add_matcher(match_range);
976    node_matcher.add_matcher(match_in);
977    node_matcher.add_matcher(match_is);
978    node_matcher.add_matcher(match_as);
979    node_matcher.add_matcher(match_modifier);
980    node_matcher.add_matcher(match_quick_named_to);
981    node_matcher.add_matcher(match_assume_tuple);
982    node_matcher.add_matcher(match_alias);
983    node_matcher.add_matcher(match_member_access_and_apply);
984    node_matcher.add_matcher(match_variable);
985    node_matcher.match_node(collector, tokens)
986}
987
988/// 尝试匹配子节点,如果失败则返回 None 或错误。
989/// 这是一个简化的宏,用于在匹配子节点时处理结果。
990macro_rules! try_match_node {
991    ($collector:expr, $tokens:expr) => {
992        match match_all($collector, $tokens) {
993            Ok(Some(node)) => node,
994            Ok(None) => return Ok(None),
995            Err(e) => return Err(e),
996        }
997    };
998}
999fn match_expressions(
1000    collector: &mut DiagnosticCollector,
1001    tokens: &[GatheredTokens],
1002) -> Result<Option<ASTNode>, ()> {
1003    let mut offset = 0usize;
1004    let mut left_start = 0usize;
1005    let mut separated = Vec::<ASTNode>::new();
1006    while offset < tokens.len() {
1007        if is_symbol(&tokens[offset], ";") {
1008            let left_tokens = &tokens[left_start..offset];
1009            separated.push(try_match_node!(collector, left_tokens));
1010            left_start = offset + 1;
1011        }
1012        offset += 1;
1013    }
1014    if separated.is_empty() {
1015        return Ok(None);
1016    }
1017    let left_tokens = &tokens[left_start..offset];
1018    separated.push(try_match_node!(collector, left_tokens));
1019    Ok(Some(ASTNode::new(
1020        ASTNodeType::Expressions,
1021        span_from_tokens(tokens),
1022        separated,
1023    )))
1024}
1025
1026fn match_comptime(
1027    collector: &mut DiagnosticCollector,
1028    tokens: &[GatheredTokens],
1029) -> Result<Option<ASTNode>, ()> {
1030    if tokens.is_empty() || !is_symbol(&tokens[0], "@") {
1031        return Ok(None);
1032    }
1033    let right = try_match_node!(collector, &tokens[1..]);
1034    let node = ASTNode::new(
1035        ASTNodeType::Comptime,
1036        span_from_tokens(&tokens),
1037        vec![right],
1038    );
1039    Ok(Some(node))
1040}
1041
1042fn match_serialize_to_base64(
1043    collector: &mut DiagnosticCollector,
1044    tokens: &[GatheredTokens],
1045) -> Result<Option<ASTNode>, ()> {
1046    if tokens.is_empty() || !is_symbol(&tokens[0], "$") {
1047        return Ok(None);
1048    }
1049    let ast = try_match_node!(collector, &tokens[1..]);
1050
1051    let serialized = match bincode::serde::encode_to_vec(&ast, bincode::config::standard()) {
1052        Ok(data) => data,
1053        Err(err) => {
1054            return collector.fatal(ASTParseDiagnostic::InvalidSyntax(
1055                span_from_tokens(&tokens),
1056                format!("Failed to serialize AST: {}", err),
1057            ));
1058        }
1059    };
1060    let base64_encoded = base64::engine::general_purpose::STANDARD.encode(serialized);
1061
1062    // 将 `$expr` 解糖为 `ast.deserialize("base64...")` 的AST结构
1063
1064    // 1. 创建 `ast.deserialize` 节点 (GetAttr)
1065    let get_attr_node = ASTNode::new(
1066        ASTNodeType::GetAttr,
1067        None, // 这是一个生成的节点,没有直接的源码位置
1068        vec![
1069            ASTNode::new(ASTNodeType::Variable("ast".to_string()), None, vec![]),
1070            ASTNode::new(ASTNodeType::String("deserialize".to_string()), None, vec![]),
1071        ],
1072    );
1073
1074    // 2. 创建参数节点 (Base64编码的字符串)
1075    let arg_node = ASTNode::new(ASTNodeType::Base64(base64_encoded), None, vec![]);
1076
1077    // 3. 创建函数调用节点 (Apply)
1078    let apply_node = ASTNode::new(
1079        ASTNodeType::Apply,
1080        span_from_tokens(&tokens), // 整个调用节点的源码位置对应于原始的 `$expr`
1081        vec![get_attr_node, arg_node],
1082    );
1083
1084    Ok(Some(apply_node))
1085}
1086fn match_dynamic_and_static(
1087    collector: &mut DiagnosticCollector,
1088    tokens: &[GatheredTokens],
1089) -> Result<Option<ASTNode>, ()> {
1090    if tokens.len() == 0
1091        || !is_symbol(&tokens[0], "dynamic") && !is_identifier(&tokens[0], "static")
1092    {
1093        return Ok(None);
1094    }
1095    let right = try_match_node!(collector, &tokens[1..]);
1096    let node = ASTNode::new(
1097        if is_identifier(&tokens[0], "dynamic") {
1098            ASTNodeType::Dynamic
1099        } else {
1100            ASTNodeType::Static
1101        },
1102        span_from_tokens(&tokens),
1103        vec![right],
1104    );
1105    Ok(Some(node))
1106}
1107
1108fn match_return_emit_raise(
1109    collector: &mut DiagnosticCollector,
1110    tokens: &[GatheredTokens],
1111) -> Result<Option<ASTNode>, ()> {
1112    if tokens.len() == 0
1113        || !is_identifier(&tokens[0], "return") && !is_identifier(&tokens[0], "raise")
1114    {
1115        return Ok(None);
1116    }
1117    let right = try_match_node!(collector, &tokens[1..]);
1118    Ok(Some(ASTNode::new(
1119        if is_identifier(&tokens[0], "return") {
1120            ASTNodeType::Return
1121        } else {
1122            ASTNodeType::Raise
1123        },
1124        span_from_tokens(&tokens),
1125        vec![right],
1126    )))
1127}
1128
1129fn match_tuple(
1130    collector: &mut DiagnosticCollector,
1131    tokens: &[GatheredTokens],
1132) -> Result<Option<ASTNode>, ()> {
1133    let mut offset = 0usize;
1134    let mut left_tokens = Vec::<GatheredTokens>::new();
1135    let mut separated = Vec::<ASTNode>::new();
1136    while offset < tokens.len() {
1137        if is_symbol(&tokens[offset], ",") {
1138            if !left_tokens.is_empty() {
1139                separated.push(try_match_node!(collector, &left_tokens));
1140                left_tokens.clear();
1141            }
1142        } else {
1143            left_tokens.push(tokens[offset]);
1144        }
1145        offset += 1;
1146    }
1147    if separated.is_empty() {
1148        return Ok(None);
1149    }
1150    if !left_tokens.is_empty() {
1151        separated.push(try_match_node!(collector, &left_tokens));
1152    }
1153    Ok(Some(ASTNode::new(
1154        ASTNodeType::Tuple,
1155        span_from_tokens(&tokens),
1156        separated,
1157    )))
1158}
1159
1160fn match_let(
1161    collector: &mut DiagnosticCollector,
1162    tokens: &[GatheredTokens],
1163) -> Result<Option<ASTNode>, ()> {
1164    if tokens.len() <= 2 || !is_symbol(&tokens[1], ":=") {
1165        return Ok(None);
1166    }
1167    let left_tokens = gather(collector, tokens[0])?;
1168    let left = try_match_node!(collector, &left_tokens);
1169    let right = try_match_node!(collector, &tokens[2..]);
1170
1171    match left.node_type {
1172        ASTNodeType::Variable(name) | ASTNodeType::String(name) => Ok(Some(ASTNode::new(
1173            ASTNodeType::Let(name),
1174            span_from_tokens(&tokens),
1175            vec![right],
1176        ))),
1177        _ => {
1178            return collector.fatal(ASTParseDiagnostic::InvalidVariableName(span_from_tokens(
1179                &left_tokens,
1180            )));
1181        }
1182    }
1183}
1184
1185fn match_assign(
1186    collector: &mut DiagnosticCollector,
1187    tokens: &[GatheredTokens],
1188) -> Result<Option<ASTNode>, ()> {
1189    // 确保有足够的 token 来处理赋值
1190    if tokens.len() == 0 {
1191        return Ok(None);
1192    }
1193
1194    // 向右搜索 = 符号
1195    let mut offset = 0;
1196    let mut left_tokens: Vec<&[Token]> = Vec::new();
1197
1198    while offset < tokens.len() {
1199        // 找到 = 符号
1200        if is_symbol(&tokens[offset], "=") {
1201            break;
1202        }
1203        left_tokens.push(tokens[offset]);
1204        offset += 1;
1205    }
1206
1207    // 没找到 = 符号
1208    if offset >= tokens.len() {
1209        return Ok(None);
1210    }
1211
1212    let left = try_match_node!(collector, &left_tokens);
1213    let right = try_match_node!(collector, &tokens[offset + 1..]);
1214
1215    return Ok(Some(ASTNode::new(
1216        ASTNodeType::Assign,
1217        span_from_tokens(&tokens),
1218        vec![left, right],
1219    )));
1220}
1221
1222fn match_named_to(
1223    collector: &mut DiagnosticCollector,
1224    tokens: &[GatheredTokens],
1225) -> Result<Option<ASTNode>, ()> {
1226    if tokens.len() <= 2 || !is_symbol(&tokens[1], "=>") {
1227        return Ok(None);
1228    }
1229
1230    let left_tokens = gather(collector, tokens[0])?;
1231    let mut left = try_match_node!(collector, &left_tokens);
1232
1233    if let ASTNodeType::Variable(name) = left.node_type {
1234        left = ASTNode::new(
1235            ASTNodeType::String(name),
1236            left.source_location,
1237            left.children,
1238        );
1239    }
1240    let right = try_match_node!(collector, &tokens[2..]);
1241    Ok(Some(ASTNode::new(
1242        ASTNodeType::Pair,
1243        span_from_tokens(&tokens),
1244        vec![left, right],
1245    )))
1246}
1247
1248fn match_pair(
1249    collector: &mut DiagnosticCollector,
1250    tokens: &[GatheredTokens],
1251) -> Result<Option<ASTNode>, ()> {
1252    if tokens.len() <= 2 || !is_symbol(&tokens[1], ":") {
1253        return Ok(None);
1254    }
1255
1256    let left_tokens = gather(collector, tokens[0])?;
1257    let left = try_match_node!(collector, &left_tokens);
1258    let right = try_match_node!(collector, &tokens[2..]);
1259    Ok(Some(ASTNode::new(
1260        ASTNodeType::Pair,
1261        span_from_tokens(&tokens),
1262        vec![left, right],
1263    )))
1264}
1265
1266fn match_while(
1267    collector: &mut DiagnosticCollector,
1268    tokens: &[GatheredTokens],
1269) -> Result<Option<ASTNode>, ()> {
1270    if tokens.len() <= 2 || !is_identifier(&tokens[0], "while") {
1271        return Ok(None);
1272    }
1273    let condition_tokens = gather(collector, tokens[1])?;
1274    let condition = try_match_node!(collector, &condition_tokens);
1275    let body = try_match_node!(collector, &tokens[2..]);
1276    Ok(Some(ASTNode::new(
1277        ASTNodeType::While,
1278        span_from_tokens(&tokens),
1279        vec![condition, body],
1280    )))
1281}
1282
1283fn match_if(
1284    collector: &mut DiagnosticCollector,
1285    tokens: &[GatheredTokens],
1286) -> Result<Option<ASTNode>, ()> {
1287    if tokens.len() <= 2 || !is_identifier(&tokens[0], "if") {
1288        return Ok(None);
1289    }
1290
1291    let condition_tokens = gather(collector, tokens[1])?;
1292    let true_condition_tokens = gather(collector, tokens[2])?;
1293
1294    let condition = try_match_node!(collector, &condition_tokens);
1295    let true_condition = try_match_node!(collector, &true_condition_tokens);
1296
1297    if 3 < tokens.len() && is_identifier(&tokens[3], "else") {
1298        let false_condition = try_match_node!(collector, &tokens[4..]);
1299        return Ok(Some(ASTNode::new(
1300            ASTNodeType::If,
1301            span_from_tokens(&tokens),
1302            vec![condition, true_condition, false_condition],
1303        )));
1304    }
1305    Ok(Some(ASTNode::new(
1306        ASTNodeType::If,
1307        span_from_tokens(&tokens),
1308        vec![condition, true_condition],
1309    )))
1310}
1311
1312fn match_break_and_continue(
1313    collector: &mut DiagnosticCollector,
1314    tokens: &[GatheredTokens],
1315) -> Result<Option<ASTNode>, ()> {
1316    if tokens.len() == 0 {
1317        return Ok(None);
1318    }
1319    if is_identifier(&tokens[0], "break") {
1320        let right = try_match_node!(collector, &tokens[1..]);
1321        return Ok(Some(ASTNode::new(
1322            ASTNodeType::Break,
1323            span_from_tokens(&tokens),
1324            vec![right],
1325        )));
1326    } else if is_identifier(&tokens[0], "continue") {
1327        let right = try_match_node!(collector, &tokens[1..]);
1328        return Ok(Some(ASTNode::new(
1329            ASTNodeType::Continue,
1330            span_from_tokens(&tokens),
1331            vec![right],
1332        )));
1333    }
1334    Ok(None)
1335}
1336
1337fn match_or(
1338    collector: &mut DiagnosticCollector,
1339    tokens: &[GatheredTokens],
1340) -> Result<Option<ASTNode>, ()> {
1341    let mut offset: usize = tokens.len() - 1;
1342    let mut operator = Option::<&str>::None;
1343    let mut operator_pos: usize = 0;
1344    while offset > 0 {
1345        let pos = offset;
1346        if is_identifier(&tokens[pos], "or") {
1347            operator = Some("or");
1348            operator_pos = pos;
1349            break;
1350        }
1351        offset -= 1;
1352    }
1353    if operator.is_none() {
1354        return Ok(None);
1355    }
1356
1357    let left = try_match_node!(collector, &tokens[..operator_pos]);
1358    let right = try_match_node!(collector, &tokens[operator_pos + 1..]);
1359
1360    return Ok(Some(ASTNode::new(
1361        ASTNodeType::Operation(ASTNodeOperation::Or),
1362        span_from_tokens(&tokens),
1363        vec![left, right],
1364    )));
1365}
1366
1367fn match_and(
1368    collector: &mut DiagnosticCollector,
1369    tokens: &[GatheredTokens],
1370) -> Result<Option<ASTNode>, ()> {
1371    let mut offset: usize = tokens.len() - 1;
1372    let mut operator = Option::<&str>::None;
1373    let mut operator_pos: usize = 0;
1374    while offset > 0 {
1375        let pos = offset;
1376        if is_identifier(&tokens[pos], "and") {
1377            operator = Some("and");
1378            operator_pos = pos;
1379            break;
1380        }
1381        offset -= 1;
1382    }
1383    if operator.is_none() {
1384        return Ok(None);
1385    }
1386
1387    let left = try_match_node!(collector, &tokens[..operator_pos]);
1388    let right = try_match_node!(collector, &tokens[operator_pos + 1..]);
1389
1390    return Ok(Some(ASTNode::new(
1391        ASTNodeType::Operation(ASTNodeOperation::And),
1392        span_from_tokens(&tokens),
1393        vec![left, right],
1394    )));
1395}
1396
1397fn match_xor(
1398    collector: &mut DiagnosticCollector,
1399    tokens: &[GatheredTokens],
1400) -> Result<Option<ASTNode>, ()> {
1401    if tokens.len() == 0 {
1402        return Ok(None);
1403    }
1404    let mut offset: usize = tokens.len() - 1;
1405    let mut operator = Option::<&str>::None;
1406    let mut operator_pos: usize = 0;
1407    while offset > 0 {
1408        let pos = offset;
1409        if is_identifier(&tokens[pos], "xor") {
1410            operator = Some("xor");
1411            operator_pos = pos;
1412            break;
1413        }
1414        offset -= 1;
1415    }
1416    if operator.is_none() {
1417        return Ok(None);
1418    }
1419
1420    let left = try_match_node!(collector, &tokens[..operator_pos]);
1421    let right = try_match_node!(collector, &tokens[operator_pos + 1..]);
1422
1423    return Ok(Some(ASTNode::new(
1424        ASTNodeType::Operation(ASTNodeOperation::Xor),
1425        span_from_tokens(&tokens),
1426        vec![left, right],
1427    )));
1428}
1429
1430fn match_not(
1431    collector: &mut DiagnosticCollector,
1432    tokens: &[GatheredTokens],
1433) -> Result<Option<ASTNode>, ()> {
1434    if tokens.len() <= 1 || !is_identifier(&tokens[0], "not") {
1435        return Ok(None);
1436    }
1437    let node = try_match_node!(collector, &tokens[1..]);
1438    return Ok(Some(ASTNode::new(
1439        ASTNodeType::Operation(ASTNodeOperation::Not),
1440        span_from_tokens(&tokens),
1441        vec![node],
1442    )));
1443}
1444
1445// >, <, >=, <=, ==, !=
1446fn match_operation_compare(
1447    collector: &mut DiagnosticCollector,
1448    tokens: &[GatheredTokens],
1449) -> Result<Option<ASTNode>, ()> {
1450    if tokens.len() == 0 {
1451        return Ok(None);
1452    }
1453    let mut offset: usize = tokens.len() - 1;
1454    let mut operator = None;
1455    let mut operator_pos: usize = 0;
1456    while offset > 0 {
1457        let pos = offset;
1458        if is_symbol(&tokens[pos], ">")
1459            || is_symbol(&tokens[pos], "<")
1460            || is_symbol(&tokens[pos], ">=")
1461            || is_symbol(&tokens[pos], "<=")
1462            || is_symbol(&tokens[pos], "==")
1463            || is_symbol(&tokens[pos], "!=")
1464        {
1465            operator = Some(tokens[pos][0].token());
1466            operator_pos = pos;
1467            break;
1468        }
1469        offset -= 1;
1470    }
1471    if operator.is_none() {
1472        return Ok(None);
1473    }
1474
1475    let left = try_match_node!(collector, &tokens[..operator_pos]);
1476    let right = try_match_node!(collector, &tokens[operator_pos + 1..]);
1477
1478    let operation = match operator.unwrap().as_str() {
1479        ">" => ASTNodeOperation::Greater,
1480        "<" => ASTNodeOperation::Less,
1481        ">=" => ASTNodeOperation::GreaterEqual,
1482        "<=" => ASTNodeOperation::LessEqual,
1483        "==" => ASTNodeOperation::Equal,
1484        "!=" => ASTNodeOperation::NotEqual,
1485        _ => unreachable!(),
1486    };
1487    return Ok(Some(ASTNode::new(
1488        ASTNodeType::Operation(operation),
1489        span_from_tokens(&tokens),
1490        vec![left, right],
1491    )));
1492}
1493
1494// +, -
1495fn match_operation_add_sub(
1496    collector: &mut DiagnosticCollector,
1497    tokens: &[GatheredTokens],
1498) -> Result<Option<ASTNode>, ()> {
1499    if tokens.is_empty() {
1500        return Ok(None);
1501    }
1502    let mut offset: usize = tokens.len() - 1;
1503    let mut operator = None;
1504    let mut operator_pos: usize = 0;
1505    while offset > 0 {
1506        let pos = offset;
1507        if is_symbol(&tokens[pos], "+") || is_symbol(&tokens[pos], "-") {
1508            operator = Some(tokens[pos][0].token());
1509            operator_pos = pos;
1510            break;
1511        }
1512        offset -= 1;
1513    }
1514    if operator.is_none() {
1515        return Ok(None);
1516    }
1517    if operator_pos == 0 {
1518        return Ok(None);
1519    }
1520    let left = try_match_node!(collector, &tokens[..operator_pos]);
1521    let right = try_match_node!(collector, &tokens[operator_pos + 1..]);
1522    let op = operator.unwrap();
1523    let operation = if op == "+" {
1524        ASTNodeOperation::Add
1525    } else {
1526        ASTNodeOperation::Subtract
1527    };
1528    return Ok(Some(ASTNode::new(
1529        ASTNodeType::Operation(operation),
1530        span_from_tokens(&tokens),
1531        vec![left, right],
1532    )));
1533}
1534
1535fn match_operation_mul_div_mod(
1536    collector: &mut DiagnosticCollector,
1537    tokens: &[GatheredTokens],
1538) -> Result<Option<ASTNode>, ()> {
1539    if tokens.is_empty() {
1540        return Ok(None);
1541    }
1542    let mut offset: usize = tokens.len() - 1;
1543    let mut operator = None;
1544    let mut operator_pos: usize = 0;
1545    while offset > 0 {
1546        let pos = offset;
1547        if is_symbol(&tokens[pos], "*")
1548            || is_symbol(&tokens[pos], "/")
1549            || is_symbol(&tokens[pos], "%")
1550        {
1551            operator = Some(tokens[pos][0].token());
1552            operator_pos = pos;
1553            break;
1554        }
1555        offset -= 1;
1556    }
1557    if operator.is_none() {
1558        return Ok(None);
1559    }
1560    let left = try_match_node!(collector, &tokens[..operator_pos]);
1561    let right = try_match_node!(collector, &tokens[operator_pos + 1..]);
1562    let operation = match operator.unwrap().as_str() {
1563        "*" => ASTNodeOperation::Multiply,
1564        "/" => ASTNodeOperation::Divide,
1565        "%" => ASTNodeOperation::Modulus,
1566        _ => unreachable!(),
1567    };
1568    return Ok(Some(ASTNode::new(
1569        ASTNodeType::Operation(operation),
1570        span_from_tokens(&tokens),
1571        vec![left, right],
1572    )));
1573}
1574
1575fn match_bitwise_shift(
1576    collector: &mut DiagnosticCollector,
1577    tokens: &[GatheredTokens],
1578) -> Result<Option<ASTNode>, ()> {
1579    if tokens.is_empty() {
1580        return Ok(None);
1581    }
1582    let mut offset: usize = tokens.len() - 1;
1583    let mut operator = None;
1584    let mut operator_pos: usize = 0;
1585    while offset > 0 {
1586        let pos = offset;
1587        if is_symbol(&tokens[pos], "<<") || is_symbol(&tokens[pos], ">>") {
1588            operator = Some(tokens[pos][0].token());
1589            operator_pos = pos;
1590            break;
1591        }
1592        offset -= 1;
1593    }
1594    if operator.is_none() {
1595        return Ok(None);
1596    }
1597
1598    let left = try_match_node!(collector, &tokens[..operator_pos]);
1599    let right = try_match_node!(collector, &tokens[operator_pos + 1..]);
1600
1601    return Ok(Some(ASTNode::new(
1602        ASTNodeType::Operation(if operator.unwrap() == "<<" {
1603            ASTNodeOperation::LeftShift
1604        } else {
1605            ASTNodeOperation::RightShift
1606        }),
1607        span_from_tokens(&tokens),
1608        vec![left, right],
1609    )));
1610}
1611
1612fn match_unary(
1613    collector: &mut DiagnosticCollector,
1614    tokens: &[GatheredTokens],
1615) -> Result<Option<ASTNode>, ()> {
1616    if tokens.is_empty() {
1617        return Ok(None);
1618    }
1619    if is_symbol(&tokens[0], "-") || is_symbol(&tokens[0], "+") {
1620        if tokens.len() <= 1 {
1621            return Ok(None);
1622        };
1623        let right = try_match_node!(collector, &tokens[1..]);
1624        let operation = match tokens[0][0].token().as_str() {
1625            "-" => ASTNodeOperation::Minus,
1626            "+" => ASTNodeOperation::Abs,
1627            _ => unreachable!(),
1628        };
1629        return Ok(Some(ASTNode::new(
1630            ASTNodeType::Operation(operation),
1631            span_from_tokens(&tokens),
1632            vec![right],
1633        )));
1634    }
1635    Ok(None)
1636}
1637
1638fn match_power(
1639    collector: &mut DiagnosticCollector,
1640    tokens: &[GatheredTokens],
1641) -> Result<Option<ASTNode>, ()> {
1642    if tokens.len() < 3 {
1643        return Ok(None);
1644    }
1645
1646    // 正向搜索 **
1647    let find = tokens.iter().position(|token| is_symbol(token, "**"));
1648    if find.is_none() {
1649        return Ok(None);
1650    }
1651    let operator_pos = find.unwrap();
1652    if operator_pos + 1 >= tokens.len() {
1653        return Ok(None);
1654    }
1655    let left = try_match_node!(collector, &tokens[..operator_pos]);
1656    let right = try_match_node!(collector, &tokens[operator_pos + 1..]);
1657
1658    return Ok(Some(ASTNode::new(
1659        ASTNodeType::Operation(ASTNodeOperation::Power),
1660        span_from_tokens(&tokens),
1661        vec![left, right],
1662    )));
1663}
1664fn match_map(
1665    collector: &mut DiagnosticCollector,
1666    tokens: &[GatheredTokens],
1667) -> Result<Option<ASTNode>, ()> {
1668    if tokens.is_empty() {
1669        return Ok(None);
1670    }
1671
1672    // 从右向左查找 |> 操作符
1673    let mut offset: usize = tokens.len() - 1;
1674    let mut operator_pos: usize = 0;
1675    let mut found = false;
1676
1677    while offset > 0 {
1678        let pos = offset;
1679        if is_symbol(&tokens[pos], "|>") {
1680            operator_pos = pos;
1681            found = true;
1682            break;
1683        }
1684        offset -= 1;
1685    }
1686
1687    if !found {
1688        return Ok(None);
1689    }
1690
1691    let left = try_match_node!(collector, &tokens[..operator_pos]);
1692    let right = try_match_node!(collector, &tokens[operator_pos + 1..]);
1693
1694    return Ok(Some(ASTNode::new(
1695        ASTNodeType::Map,
1696        span_from_tokens(&tokens),
1697        vec![left, right],
1698    )));
1699}
1700fn match_set_def(
1701    collector: &mut DiagnosticCollector,
1702    tokens: &[GatheredTokens],
1703) -> Result<Option<ASTNode>, ()> {
1704    if tokens.is_empty() {
1705        return Ok(None);
1706    }
1707
1708    // 从右向左查找 | 操作符
1709    let mut offset: usize = tokens.len() - 1;
1710    let mut operator_pos: usize = 0;
1711    let mut found = false;
1712
1713    while offset > 0 {
1714        let pos = offset;
1715        if is_symbol(&tokens[pos], "|") {
1716            operator_pos = pos;
1717            found = true;
1718            break;
1719        }
1720        offset -= 1;
1721    }
1722
1723    if !found {
1724        return Ok(None);
1725    }
1726
1727    let left = try_match_node!(collector, &tokens[..operator_pos]);
1728    let right = try_match_node!(collector, &tokens[operator_pos + 1..]);
1729
1730    return Ok(Some(ASTNode::new(
1731        ASTNodeType::LazySet,
1732        span_from_tokens(&tokens),
1733        vec![left, right],
1734    )));
1735}
1736
1737fn match_lambda_def(
1738    collector: &mut DiagnosticCollector,
1739    tokens: &[GatheredTokens],
1740) -> Result<Option<ASTNode>, ()> {
1741    // Need at least params, ->, body_start
1742    if tokens.len() < 3 {
1743        return Ok(None);
1744    }
1745    // Check for -> symbol
1746    if !is_symbol(&tokens[1], "->") {
1747        return Ok(None);
1748    }
1749
1750    // Parse parameters (left part)
1751    let left_tokens = gather(collector, tokens[0])?;
1752    let left = try_match_node!(collector, &left_tokens);
1753
1754    let mut body_start_index = 2; // Index after params ->
1755    let mut capture_vars = HashSet::new();
1756    if body_start_index < tokens.len() && is_symbol(&tokens[body_start_index], "&") {
1757        // If there's an '&' symbol, it indicates a capture
1758        body_start_index += 1; // Skip the '&'
1759        if body_start_index >= tokens.len() {
1760            return collector.fatal(ASTParseDiagnostic::MissingStructure(
1761                span_from_single_token(tokens.last().unwrap().last().unwrap()), // Point to the last token
1762                "Lambda capture".to_string(),
1763            ));
1764        }
1765        // then we expect a capture name or tuple
1766        let capture = gather(collector, tokens[body_start_index])?;
1767        let capture_node = try_match_node!(collector, &capture);
1768        match capture_node.node_type {
1769            ASTNodeType::String(v) | ASTNodeType::Variable(v) => {
1770                // Valid capture variable
1771                capture_vars.insert(v);
1772            }
1773            ASTNodeType::Tuple => {
1774                for child in &capture_node.children {
1775                    if let ASTNodeType::String(v) | ASTNodeType::Variable(v) = &child.node_type {
1776                        capture_vars.insert(v.clone());
1777                    } else {
1778                        return collector.fatal(ASTParseDiagnostic::InvalidSyntax(
1779                            span_from_single_token(tokens[body_start_index].first().unwrap()),
1780                            "Capture must be a variable or tuple of variables".to_string(),
1781                        ));
1782                    }
1783                }
1784            }
1785            _ => {
1786                return collector.fatal(ASTParseDiagnostic::InvalidSyntax(
1787                    span_from_single_token(tokens[body_start_index].first().unwrap()),
1788                    "Capture must be a variable or tuple of variables".to_string(),
1789                ));
1790            }
1791        }
1792        body_start_index += 1;
1793    }
1794
1795    // Check for 'dyn' keyword
1796    let is_dyn = body_start_index < tokens.len() && is_identifier(&tokens[body_start_index], "dyn");
1797    if is_dyn {
1798        body_start_index += 1;
1799    }
1800
1801    // Check if there's anything left for the body
1802    if body_start_index >= tokens.len() {
1803        return collector.fatal(ASTParseDiagnostic::MissingStructure(
1804            span_from_single_token(tokens.last().unwrap().last().unwrap()), // Point to the last token
1805            "Lambda body".to_string(),
1806        ));
1807    }
1808
1809    // Parse the lambda body (right part)
1810    let right = try_match_node!(collector, &tokens[body_start_index..]);
1811
1812    Ok(Some(ASTNode::new(
1813        // Use the new ASTNodeType variant
1814        ASTNodeType::LambdaDef(is_dyn, capture_vars),
1815        span_from_tokens(&tokens),
1816        vec![left, right],
1817    )))
1818}
1819
1820fn match_modifier(
1821    collector: &mut DiagnosticCollector,
1822    tokens: &[GatheredTokens],
1823) -> Result<Option<ASTNode>, ()> {
1824    if tokens.len() < 2 {
1825        return Ok(None);
1826    }
1827    if tokens[0].len() == 1
1828        && vec![
1829            "mut", "const", "keyof", "valueof", "assert", "import", "typeof", "lengthof", "launch",
1830            "spawn", "async", "sync", "atomic",
1831        ]
1832        .contains(&tokens[0].first().unwrap().token().as_str())
1833    {
1834        let right = try_match_node!(collector, &tokens[1..]);
1835        let modifier = match tokens[0].first().unwrap().token().as_str() {
1836            "mut" => ASTNodeModifier::Mut,
1837            "const" => ASTNodeModifier::Const,
1838            "keyof" => ASTNodeModifier::KeyOf,
1839            "valueof" => ASTNodeModifier::ValueOf,
1840            "assert" => ASTNodeModifier::Assert,
1841            "import" => ASTNodeModifier::Import,
1842            "typeof" => ASTNodeModifier::TypeOf,
1843            "lengthof" => ASTNodeModifier::LengthOf,
1844            "launch" => ASTNodeModifier::Launch,
1845            "spawn" => ASTNodeModifier::Spawn,
1846            "async" => ASTNodeModifier::Async,
1847            "sync" => ASTNodeModifier::Sync,
1848            "atomic" => ASTNodeModifier::Atomic,
1849            _ => return Ok(None),
1850        };
1851        return Ok(Some(ASTNode::new(
1852            ASTNodeType::Modifier(modifier),
1853            span_from_tokens(&tokens),
1854            vec![right],
1855        )));
1856    }
1857    Ok(None)
1858}
1859
1860fn match_quick_named_to(
1861    collector: &mut DiagnosticCollector,
1862    tokens: &[GatheredTokens],
1863) -> Result<Option<ASTNode>, ()> {
1864    // expr ?
1865    if tokens.len() <= 1 {
1866        return Ok(None);
1867    }
1868    if is_symbol(&tokens[tokens.len() - 1], "?") {
1869        let left_tokens = tokens[..tokens.len() - 1].to_vec();
1870        let mut node = try_match_node!(collector, &left_tokens);
1871        if let ASTNodeType::Variable(name) = node.node_type {
1872            node = ASTNode::new(
1873                ASTNodeType::String(name),
1874                node.source_location,
1875                node.children,
1876            );
1877        }
1878        return Ok(Some(ASTNode::new(
1879            ASTNodeType::Pair,
1880            span_from_tokens(&tokens),
1881            vec![node, ASTNode::new(ASTNodeType::Boolean(true), None, vec![])],
1882        )));
1883    }
1884    Ok(None)
1885}
1886
1887fn match_assume_tuple(
1888    collector: &mut DiagnosticCollector,
1889    tokens: &[GatheredTokens],
1890) -> Result<Option<ASTNode>, ()> {
1891    if tokens.len() < 2 {
1892        return Ok(None);
1893    }
1894    if !is_symbol(&tokens[0], "...") {
1895        return Ok(None);
1896    }
1897    let right = try_match_node!(collector, &tokens[1..]);
1898    Ok(Some(ASTNode::new(
1899        ASTNodeType::AssumeTuple,
1900        span_from_tokens(&tokens),
1901        vec![right],
1902    )))
1903}
1904
1905fn match_alias(
1906    collector: &mut DiagnosticCollector,
1907    tokens: &[GatheredTokens],
1908) -> Result<Option<ASTNode>, ()> {
1909    if tokens.len() < 3 {
1910        return Ok(None);
1911    }
1912
1913    if !is_symbol(&tokens[1], "::") {
1914        return Ok(None);
1915    }
1916
1917    let type_tokens = gather(collector, tokens[0])?;
1918    let type_node = try_match_node!(collector, &type_tokens);
1919
1920    let type_name = match &type_node.node_type {
1921        ASTNodeType::Variable(name) => name.clone(),
1922        ASTNodeType::String(name) => name.clone(),
1923        _ => {
1924            return collector.fatal(ASTParseDiagnostic::InvalidSyntax(
1925                span_from_single_token(tokens[0].first().unwrap()),
1926                "Expected identifier".to_string(),
1927            ));
1928        }
1929    };
1930
1931    // 解析右侧值表达式
1932    let right = try_match_node!(collector, &tokens[2..]);
1933
1934    Ok(Some(ASTNode::new(
1935        ASTNodeType::Namespace(type_name),
1936        span_from_tokens(&tokens),
1937        vec![right],
1938    )))
1939}
1940
1941fn match_member_access_and_apply(
1942    collector: &mut DiagnosticCollector,
1943    tokens: &[GatheredTokens],
1944) -> Result<Option<ASTNode>, ()> {
1945    // x y or x.y
1946    if tokens.len() <= 1 {
1947        return Ok(None);
1948    }
1949
1950    let is_member_access = is_symbol(&tokens[tokens.len() - 2], ".");
1951    let left = if is_member_access {
1952        tokens[..tokens.len() - 2].to_vec()
1953    } else {
1954        tokens[..tokens.len() - 1].to_vec()
1955    };
1956    let left_node = try_match_node!(collector, &left);
1957    let right_tokens = gather(collector, &tokens.last().unwrap())?;
1958    let mut right_node = try_match_node!(collector, &right_tokens);
1959
1960    if let ASTNodeType::Variable(name) = &right_node.node_type {
1961        if is_member_access {
1962            // 如果是变量名,转换为字符串节点
1963            right_node = ASTNode::new(
1964                ASTNodeType::String(name.clone()),
1965                right_node.source_location.clone(),
1966                right_node.children,
1967            );
1968        }
1969    }
1970
1971    return Ok(Some(ASTNode::new(
1972        if is_member_access {
1973            ASTNodeType::GetAttr
1974        } else {
1975            ASTNodeType::Apply
1976        },
1977        span_from_tokens(&tokens),
1978        vec![left_node, right_node],
1979    )));
1980}
1981
1982fn match_range(
1983    collector: &mut DiagnosticCollector,
1984    tokens: &[GatheredTokens],
1985) -> Result<Option<ASTNode>, ()> {
1986    if tokens.len() < 3 {
1987        return Ok(None);
1988    }
1989    if !is_symbol(&tokens[1], "..") {
1990        // x..y
1991        return Ok(None);
1992    }
1993
1994    let left_tokens = gather(collector, tokens[0])?;
1995    let left = try_match_node!(collector, &left_tokens);
1996    let right = try_match_node!(collector, &tokens[2..]);
1997
1998    Ok(Some(ASTNode::new(
1999        ASTNodeType::Range,
2000        span_from_tokens(&tokens),
2001        vec![left, right],
2002    )))
2003}
2004
2005fn match_in(
2006    collector: &mut DiagnosticCollector,
2007    tokens: &[GatheredTokens],
2008) -> Result<Option<ASTNode>, ()> {
2009    if 2 >= tokens.len() {
2010        return Ok(None);
2011    }
2012    if !is_identifier(&tokens[1], "in") {
2013        return Ok(None);
2014    }
2015
2016    let left_tokens = gather(collector, tokens[0])?;
2017    let left = try_match_node!(collector, &left_tokens);
2018    let right = try_match_node!(collector, &tokens[2..]);
2019
2020    Ok(Some(ASTNode::new(
2021        ASTNodeType::In,
2022        span_from_tokens(&tokens),
2023        vec![left, right],
2024    )))
2025}
2026
2027fn match_is(
2028    collector: &mut DiagnosticCollector,
2029    tokens: &[GatheredTokens],
2030) -> Result<Option<ASTNode>, ()> {
2031    if tokens.len() <= 2 {
2032        return Ok(None);
2033    }
2034    if !is_identifier(&tokens[1], "is") {
2035        return Ok(None);
2036    }
2037
2038    let left_tokens = gather(collector, tokens[0])?;
2039    let left = try_match_node!(collector, &left_tokens);
2040    let right = try_match_node!(collector, &tokens[2..]);
2041
2042    Ok(Some(ASTNode::new(
2043        ASTNodeType::Is,
2044        span_from_tokens(&tokens),
2045        vec![left, right],
2046    )))
2047}
2048
2049fn match_as(
2050    collector: &mut DiagnosticCollector,
2051    tokens: &[GatheredTokens],
2052) -> Result<Option<ASTNode>, ()> {
2053    // 搜索 `as` 关键字
2054    if tokens.len() <= 2 {
2055        return Ok(None);
2056    }
2057
2058    // 从右向左扫描 `as` 关键字所在的位置
2059    let mut offset: usize = tokens.len() - 1;
2060    let mut operator_pos: usize = 0;
2061    let mut found = false;
2062
2063    while offset > 0 {
2064        let pos = offset;
2065        if is_identifier(&tokens[pos], "as") {
2066            operator_pos = pos;
2067            found = true;
2068            break;
2069        }
2070        offset -= 1;
2071    }
2072
2073    if !found {
2074        return Ok(None);
2075    }
2076
2077    // 解析左侧表达式(要转换的值)
2078    let left = try_match_node!(collector, &tokens[..operator_pos]);
2079
2080    // 解析右侧表达式(目标类型,应该是一个变量如 int, string 等)
2081    let right = try_match_node!(collector, &tokens[operator_pos + 1..]);
2082
2083    Ok(Some(ASTNode::new(
2084        ASTNodeType::Apply,
2085        span_from_tokens(&tokens),
2086        vec![right, left],
2087    )))
2088}
2089
2090fn match_variable(
2091    collector: &mut DiagnosticCollector,
2092    tokens: &[GatheredTokens],
2093) -> Result<Option<ASTNode>, ()> {
2094    if tokens.is_empty() {
2095        return Ok(None);
2096    }
2097    // 匹配括号内容(元组)
2098    if is_bracket(&tokens[0]) || is_square_bracket(&tokens[0]) {
2099        let inner_tokens = unwrap_brace(collector, &tokens[0])?;
2100        let gathered_inner = gather(collector, inner_tokens)?;
2101        let node = try_match_node!(collector, &gathered_inner);
2102        return Ok(Some(node));
2103    }
2104
2105    // 匹配函数体 {...}
2106    if is_brace(&tokens[0]) {
2107        let body_tokens = unwrap_brace(collector, &tokens[0])?;
2108        let gathered_body = gather(collector, body_tokens)?;
2109        let body = try_match_node!(collector, &gathered_body);
2110
2111        return Ok(Some(ASTNode::new(
2112            ASTNodeType::Frame,
2113            span_from_tokens(&tokens),
2114            vec![body],
2115        )));
2116    }
2117
2118    // 匹配字符串常量
2119    if tokens[0].len() == 1 && tokens[0].first().unwrap() == TokenType::STRING {
2120        return Ok(Some(ASTNode::new(
2121            ASTNodeType::String(tokens[0].first().unwrap().token().clone()),
2122            span_from_tokens(&tokens),
2123            vec![],
2124        )));
2125    }
2126
2127    // 匹配数字常量
2128    if tokens[0].len() == 1 && tokens[0].first().unwrap() == TokenType::NUMBER {
2129        return Ok(Some(ASTNode::new(
2130            ASTNodeType::Number(tokens[0].first().unwrap().token().clone()),
2131            span_from_tokens(&tokens),
2132            vec![],
2133        )));
2134    }
2135
2136    // 匹配b64
2137    if tokens[0].len() == 1 && tokens[0].first().unwrap() == TokenType::BASE64 {
2138        return Ok(Some(ASTNode::new(
2139            ASTNodeType::Base64(tokens[0].first().unwrap().token().clone()),
2140            span_from_tokens(&tokens),
2141            vec![],
2142        )));
2143    }
2144
2145    // 匹配布尔值(true)
2146    if is_identifier(&tokens[0], "true") {
2147        return Ok(Some(ASTNode::new(
2148            ASTNodeType::Boolean(true),
2149            span_from_tokens(&tokens),
2150            vec![],
2151        )));
2152    }
2153
2154    // 匹配布尔值(false)
2155    if is_identifier(&tokens[0], "false") {
2156        return Ok(Some(ASTNode::new(
2157            ASTNodeType::Boolean(false),
2158            span_from_tokens(&tokens),
2159            vec![],
2160        )));
2161    }
2162
2163    // 匹配空值(null)
2164    if is_identifier(&tokens[0], "null") {
2165        return Ok(Some(ASTNode::new(
2166            ASTNodeType::Null,
2167            span_from_tokens(&tokens),
2168            vec![],
2169        )));
2170    }
2171
2172    // undefined
2173    if is_identifier(&tokens[0], "undefined") {
2174        return Ok(Some(ASTNode::new(
2175            ASTNodeType::Undefined,
2176            span_from_tokens(&tokens),
2177            vec![],
2178        )));
2179    }
2180
2181    // 匹配普通变量名
2182    if tokens[0].len() == 1 && tokens[0][0] == TokenType::IDENTIFIER {
2183        return Ok(Some(ASTNode::new(
2184            ASTNodeType::Variable(tokens[0][0].token().clone()),
2185            span_from_tokens(&tokens),
2186            vec![],
2187        )));
2188    }
2189    Ok(None)
2190}