taitan_orm_parser/template_parser/structs/exprs/
generic_expr.rs

1use crate::template::{BoolValue, MatchOp, TextValue};
2use crate::template_parser::structs::operators::{
3    ArithmeticUnaryOp, CompareOp, ListInOp, LogicOp, Paren,
4};
5use crate::template_parser::{ArithmeticExpr, ArithmeticOp, LogicExpr, MaybeValue, TextExpr};
6use crate::{Atomic, AtomicStream, Operator, Sign, VariableChain};
7use proc_macro2::fallback::unforce;
8use std::fmt::Debug;
9
10use crate::template_parser::error::TemplateParseError;
11use crate::template_parser::structs::atomics::{
12    AtomicTrait, GenericAtomic, GenericAtomicStream, MySqlAtomic,
13};
14use crate::template_parser::structs::operators::ConnectOp;
15use tracing::{debug, error};
16
17pub type ParseResult<T> = std::result::Result<T, TemplateParseError>;
18
19#[derive(Debug, Clone, PartialEq)]
20pub enum GenericExpr {
21    Atomic(GenericAtomic),
22    ArithmeticExpr {
23        left: Box<GenericExpr>,
24        op: ArithmeticOp,
25        right: Box<GenericExpr>,
26    },
27    AnnotatedArithmeticExpr {
28        unary_op: ArithmeticUnaryOp,
29        expr: Box<GenericExpr>,
30    },
31    CompareExpr {
32        left: Box<GenericExpr>,
33        op: CompareOp,
34        right: Box<GenericExpr>,
35    },
36    Not(Box<GenericExpr>),
37    LogicExpr {
38        left: Box<GenericExpr>,
39        op: LogicOp,
40        right: Box<GenericExpr>,
41    },
42    CommaExpr {
43        left: Box<GenericExpr>,
44        op: ConnectOp,
45        right: Box<GenericExpr>,
46    },
47    NestedExpr(Box<GenericExpr>),
48    FnCallExpr {
49        name: VariableChain,
50        args: Box<GenericExpr>, // must be CommaExpr
51    },
52    ListInExpr {
53        left: Box<GenericExpr>,
54        op: ListInOp,
55        right: Box<GenericExpr>,
56    },
57}
58
59impl GenericExpr {
60    pub fn parse_str<T>(input: &str) -> ParseResult<GenericExpr>
61    where
62        T: AtomicTrait + Clone + PartialEq + Debug + Into<GenericAtomic>,
63    {
64        let stream = GenericAtomicStream::parse::<T>(input)?;
65        let (remaining, parsed) = Self::parse(stream.atomics)?;
66        Ok(parsed)
67    }
68
69    fn is_inner_comma_expr(&self) -> bool {
70        match self {
71            GenericExpr::CommaExpr { .. } => true,
72            GenericExpr::Atomic(_) => true,
73            GenericExpr::NestedExpr(inner) => inner.is_inner_comma_expr(),
74            _ => false,
75        }
76    }
77    fn is_nested_comma_expr(&self) -> bool {
78        match self {
79            GenericExpr::NestedExpr(inner) => inner.is_inner_comma_expr(),
80            _ => false,
81        }
82    }
83
84    fn is_unary_op(arithmetic_op: ArithmeticOp, prev: &Option<GenericAtomic>) -> bool {
85        // 如果 + 或 - 出现在以下位置,则是一元操作符:
86        // 1. 表达式的开头
87        // 2. 在另一个操作符之后
88        // 3. 在左括号之后
89        match arithmetic_op {
90            ArithmeticOp::Add | ArithmeticOp::Sub => {}
91            _ => return false,
92        }
93
94        match prev {
95            None => true,
96            Some(atomic) => match atomic {
97                GenericAtomic::Operator(_) => true,
98                _ => false,
99            },
100        }
101    }
102
103    fn is_unary_op_sign(sign: &Sign, prev: &Option<GenericAtomic>) -> bool {
104        // 如果 + 或 - 出现在以下位置,则是一元操作符:
105        // 1. 表达式的开头
106        // 2. 在另一个操作符之后
107        // 3. 在左括号之后
108        match sign {
109            Sign::Plus | Sign::Minus => {}
110            _ => return false,
111        }
112
113        match prev {
114            None => true,
115            Some(atomic) => match atomic {
116                GenericAtomic::Operator(_) => true,
117                _ => false,
118            },
119        }
120    }
121
122    fn reduce_recursive(
123        operator: &Operator,
124        operands: &mut Vec<GenericExpr>,
125        operators: &mut Vec<Operator>,
126    ) -> ParseResult<()> {
127        while let Some(top) = operators.last() {
128            // 遇到左括号( 或 FnCallOp,停止规约
129            if let Operator::Paren(Paren::Left) | Operator::FnCall(_) = top {
130                return Ok(());
131            }
132            // 栈顶优先级更低,停止规约
133            if precedence(top) < precedence(&operator) {
134                return Ok(());
135            }
136            // 栈顶优先级更高,弹出并构建表达式
137            Self::reduce(operands, operators)?;
138        }
139        Ok(())
140    }
141    fn consume_token(
142        token: GenericAtomic,
143        index: usize,
144        prev: &Option<GenericAtomic>,
145        operands: &mut Vec<GenericExpr>,
146        operators: &mut Vec<Operator>,
147    ) -> ParseResult<Option<GenericExpr>> {
148        match token {
149            GenericAtomic::Keyword(_) => Ok(Some(GenericExpr::Atomic(token.clone()))),
150
151            GenericAtomic::Null
152            | GenericAtomic::Number(_)
153            | GenericAtomic::Text(_)
154            | GenericAtomic::Bool(_)
155            | GenericAtomic::Maybe(_) => {
156                // 操作数直接压入操作数栈
157                debug!("GenericExpr::parse() push operands: {:?}", &token);
158                operands.push(GenericExpr::Atomic(token.clone()));
159                Ok(None)
160            }
161
162            GenericAtomic::Sign(sign) => {
163                // 如果处于开头位置,或者上一个token是select,识别为sign,而不识别为乘法符号
164                if let Sign::Star = sign {
165                    if index == 0  || &Some(GenericAtomic::Keyword("SELECT")) == prev {
166                        return Ok(Some(GenericExpr::Atomic(GenericAtomic::Sign(sign))));
167                    }
168                    operators.push(Operator::Arithmetic(ArithmeticOp::Add));
169                }
170                if let Sign::Plus = sign {
171                    if index == 0 || Self::is_unary_op_sign(&sign, &prev) {
172                        operators.push(Operator::ArithmeticUnary(ArithmeticUnaryOp::Add));
173                    }
174                } else if let Sign::Minus = sign {
175                    if index == 0 || Self::is_unary_op_sign(&sign, &prev) {
176                        operators.push(Operator::ArithmeticUnary(ArithmeticUnaryOp::Sub));
177                    }
178                } else {
179                    operands.push(GenericExpr::Atomic(GenericAtomic::Sign(sign.clone())));
180                }
181                Ok(None)
182            }
183            GenericAtomic::Operator(operator) => {
184                match operator {
185                    Operator::Paren(Paren::Left) => {
186                        // 检查是否是函数调用
187                        if let Some(GenericExpr::Atomic(GenericAtomic::Maybe(
188                            MaybeValue::VariableChain(v),
189                        ))) = operands.last()
190                        {
191                            // 如果是 VariableChain,压入 FnCallOp
192                            operators.push(Operator::FnCall(v.clone()));
193                        } else {
194                            // 否则,压入普通左括号
195                            operators.push(Operator::Paren(Paren::Left));
196                        }
197                        Ok(None)
198                    }
199                    Operator::Paren(Paren::Right) => {
200                        // 右括号:弹出操作符并构建表达式,直到遇到左括号或 FnCallOp
201                        while let Some(top) = operators.last() {
202                            match top {
203                                Operator::Paren(Paren::Left) | Operator::FnCall(_) => break,
204                                _ => Self::reduce(operands, operators)?,
205                            }
206                        }
207                        // 弹出左括号或 FnCallOp
208                        debug!("GenericExpr::parse() pop left paren or FnCallOp");
209                        if let Some(op) = operators.pop() {
210                            match op {
211                                Operator::Paren(Paren::Left) | Operator::FnCall(_) => {
212                                    // 处理函数调用
213                                    Self::reduce(operands, operators)?;
214                                    Ok(None)
215                                }
216                                _ => return Err("Mismatched parentheses".into()),
217                            }
218                        } else {
219                            return Err("Mismatched parentheses".into());
220                        }
221                    }
222                    Operator::Arithmetic(arithmetic_op) => {
223                        // 检查是否是二元操作符或一元操作符
224                        let is_unary = Self::is_unary_op(arithmetic_op.clone(), &prev);
225
226                        if is_unary {
227                            // 压入一元操作符
228                            match arithmetic_op {
229                                ArithmeticOp::Add => operators
230                                    .push(Operator::ArithmeticUnary(ArithmeticUnaryOp::Add)),
231                                ArithmeticOp::Sub => operators
232                                    .push(Operator::ArithmeticUnary(ArithmeticUnaryOp::Sub)),
233                                _ => unreachable!(),
234                            }
235                        } else {
236                            Self::reduce_recursive(&operator, operands, operators)?;
237                            // 当前操作符入栈
238                            operators.push(operator.clone());
239                        }
240                        debug!(
241                            "GenericExpr::parse() operators len[{}]: {:?}",
242                            operators.len(),
243                            operators
244                        );
245                        Ok(None)
246                    }
247                    _ => {
248                        // 处理其他操作符
249                        Self::reduce_recursive(&operator, operands, operators)?;
250                        // 当前操作符入栈
251                        operators.push(operator.clone());
252                        debug!(
253                            "GenericExpr::parse() operators len[{}]: {:?}",
254                            operators.len(),
255                            operators
256                        );
257                        Ok(None)
258                    }
259                }
260            }
261        }
262    }
263    pub fn parse(
264        mut atomics: Vec<GenericAtomic>,
265    ) -> ParseResult<(Vec<GenericAtomic>, GenericExpr)> {
266        debug!("GenericExpr::parse({:?})", atomics);
267        let mut operands: Vec<GenericExpr> = Vec::new(); // 操作数栈
268        let mut operators: Vec<Operator> = Vec::new(); // 操作符栈
269        let mut prev: Option<GenericAtomic> = None;
270
271        for token in atomics.clone() {
272            let current = token.clone();
273            match token {
274                GenericAtomic::Keyword(_) => {
275                    return Ok((atomics, GenericExpr::Atomic(token.clone())));
276                }
277                GenericAtomic::Null
278                | GenericAtomic::Number(_)
279                | GenericAtomic::Text(_)
280                | GenericAtomic::Bool(_)
281                | GenericAtomic::Maybe(_) => {
282                    // 操作数直接压入操作数栈
283                    debug!("GenericExpr::parse() push atomic: {:?}", &token);
284                    operands.push(GenericExpr::Atomic(token.clone()));
285                }
286                GenericAtomic::Sign(sign) => {
287                    if let Sign::Star = sign {}
288                    operands.push(GenericExpr::Atomic(GenericAtomic::Sign(sign.clone())));
289                }
290                GenericAtomic::Operator(operator) => {
291                    match operator {
292                        Operator::Paren(Paren::Left) => {
293                            // 检查是否是函数调用
294                            if let Some(GenericExpr::Atomic(GenericAtomic::Maybe(
295                                MaybeValue::VariableChain(v),
296                            ))) = operands.last()
297                            {
298                                // 如果是 VariableChain,压入 FnCallOp
299                                operators.push(Operator::FnCall(v.clone()));
300                            } else {
301                                // 否则,压入普通左括号
302                                operators.push(Operator::Paren(Paren::Left));
303                            }
304                        }
305                        Operator::Paren(Paren::Right) => {
306                            // 右括号:弹出操作符并构建表达式,直到遇到左括号或 FnCallOp
307                            while let Some(top) = operators.last() {
308                                match top {
309                                    Operator::Paren(Paren::Left) | Operator::FnCall(_) => break,
310                                    _ => Self::reduce(&mut operands, &mut operators)?,
311                                }
312                            }
313                            // 弹出左括号或 FnCallOp
314                            debug!("GenericExpr::parse() pop left paren or FnCallOp");
315                            if let Some(op) = operators.pop() {
316                                match op {
317                                    Operator::Paren(Paren::Left) | Operator::FnCall(_) => {
318                                        // 处理函数调用
319                                        Self::reduce(&mut operands, &mut operators)?
320                                    }
321                                    _ => return Err("Mismatched parentheses".into()),
322                                }
323                            } else {
324                                return Err("Mismatched parentheses".into());
325                            }
326                        }
327                        Operator::Arithmetic(arithmetic_op) => {
328                            // 检查是否是二元操作符或一元操作符
329                            let is_unary = Self::is_unary_op(arithmetic_op.clone(), &prev);
330
331                            if is_unary {
332                                // 压入一元操作符
333                                match arithmetic_op {
334                                    ArithmeticOp::Add => operators
335                                        .push(Operator::ArithmeticUnary(ArithmeticUnaryOp::Add)),
336                                    ArithmeticOp::Sub => operators
337                                        .push(Operator::ArithmeticUnary(ArithmeticUnaryOp::Sub)),
338                                    _ => unreachable!(),
339                                }
340                            } else {
341                                Self::reduce_recursive(&operator, &mut operands, &mut operators)?;
342                                // 当前操作符入栈
343                                operators.push(operator.clone());
344                            }
345                            debug!(
346                                "GenericExpr::parse() operators len[{}]: {:?}",
347                                operators.len(),
348                                operators
349                            );
350                        }
351                        _ => {
352                            // 处理其他操作符
353                            Self::reduce_recursive(&operator, &mut operands, &mut operators)?;
354                            // 当前操作符入栈
355                            operators.push(operator.clone());
356                            debug!(
357                                "GenericExpr::parse() operators len[{}]: {:?}",
358                                operators.len(),
359                                operators
360                            );
361                        }
362                    }
363                }
364            }
365            prev = Some(current);
366        }
367
368        // 处理剩余的操作符
369        while let Some(op) = operators.last() {
370            if let Operator::Paren(Paren::Left) | Operator::FnCall(_) = op {
371                return Err("Mismatched parentheses".into());
372            }
373            debug!("GenericExpr::parse remaining operator: {:?}", &operators);
374            Self::reduce(&mut operands, &mut operators)?;
375        }
376
377        // 最终操作数栈中应只有一个表达式
378        if operands.len() != 1 {
379            // error!("GenericExpr::parse() operands len: {:?}", &operands.len());
380            // error!("GenericExpr::parse() operands {:?}", &operands);
381            // error!("GenericExpr::parse() operators {:?}", &operators);
382            return Err("Invalid expression".into());
383        }
384
385        let expr = operands.pop().unwrap();
386        Ok((Vec::new(), expr))
387    }
388
389    fn reduce(
390        operands: &mut Vec<GenericExpr>,
391        operators: &mut Vec<Operator>,
392    ) -> Result<(), String> {
393        if let Some(op) = operators.pop() {
394            debug!(
395                "GenericExpr::reduce op: ({:?}) remaining len[{:?}]",
396                op,
397                operators.len()
398            );
399            match op {
400                Operator::ArithmeticUnary(unary_op) => match unary_op {
401                    ArithmeticUnaryOp::Add => {
402                        let operand = operands
403                            .pop()
404                            .ok_or("Missing operand for UnaryPlus".to_string())?;
405                        operands.push(GenericExpr::AnnotatedArithmeticExpr {
406                            unary_op: ArithmeticUnaryOp::Add,
407                            expr: Box::new(operand),
408                        });
409                    }
410                    ArithmeticUnaryOp::Sub => {
411                        let operand = operands
412                            .pop()
413                            .ok_or("Missing operand for UnaryMinus".to_string())?;
414                        operands.push(GenericExpr::AnnotatedArithmeticExpr {
415                            unary_op: ArithmeticUnaryOp::Sub,
416                            expr: Box::new(operand),
417                        });
418                    }
419                },
420                Operator::Arithmetic(arithmetic_op) => {
421                    let right = operands.pop().ok_or("Missing right operand".to_string())?;
422                    let left = operands.pop().ok_or("Missing left operand".to_string())?;
423                    operands.push(GenericExpr::ArithmeticExpr {
424                        left: Box::new(left),
425                        op: arithmetic_op,
426                        right: Box::new(right),
427                    });
428                }
429                Operator::Compare(compare_op) => {
430                    let right = operands.pop().ok_or("Missing right operand".to_string())?;
431                    let left = operands.pop().ok_or("Missing left operand".to_string())?;
432                    operands.push(GenericExpr::CompareExpr {
433                        left: Box::new(left),
434                        op: compare_op,
435                        right: Box::new(right),
436                    });
437                }
438                Operator::Logic(logic_op) => match logic_op {
439                    LogicOp::Not => {
440                        let operand = operands
441                            .pop()
442                            .ok_or("Missing operand for Not".to_string())?;
443                        operands.push(GenericExpr::Not(Box::new(operand)));
444                    }
445                    _ => {
446                        let right = operands.pop().ok_or("Missing right operand".to_string())?;
447                        let left = operands.pop().ok_or("Missing left operand".to_string())?;
448                        operands.push(GenericExpr::LogicExpr {
449                            left: Box::new(left),
450                            op: logic_op,
451                            right: Box::new(right),
452                        });
453                    }
454                },
455                Operator::ListInOp(list_in_op) => {
456                    let right = operands.pop().ok_or("Missing right operand".to_string())?;
457                    if !right.is_inner_comma_expr() {
458                        return Err("right operand must be comma expr".to_string());
459                    }
460                    let left = operands.pop().ok_or("Missing left operand".to_string())?;
461                    operands.push(GenericExpr::ListInExpr {
462                        left: Box::new(left),
463                        op: list_in_op,
464                        right: Box::new(right),
465                    });
466                }
467                Operator::Connect(connect_op) => {
468                    let right = operands.pop().ok_or("Missing right operand".to_string())?;
469                    let left = operands.pop().ok_or("Missing left operand".to_string())?;
470                    operands.push(GenericExpr::CommaExpr {
471                        left: Box::new(left),
472                        op: connect_op,
473                        right: Box::new(right),
474                    });
475                }
476                Operator::FnCall(variable_chain) => {
477                    // 弹出参数列表
478                    let args = operands.pop().ok_or("Missing fn call args".to_string())?;
479                    if !args.is_inner_comma_expr() {
480                        return Err("Function arguments must be a comma expression".to_string());
481                    }
482
483                    // 构建 FnCallExpr
484                    let fn_call = GenericExpr::FnCallExpr {
485                        name: variable_chain,
486                        args: Box::new(args),
487                    };
488                    operands.push(fn_call);
489                }
490                Operator::Paren(p) => match p {
491                    Paren::Left => {
492                        let inner = operands.pop().ok_or("Missing right operand".to_string())?;
493                        operands.push(GenericExpr::NestedExpr(Box::new(inner)));
494                    }
495                    Paren::Right => return Err("Unexpected parenthesis in reduce".to_string()),
496                },
497            }
498        }
499        Ok(())
500    }
501}
502
503// 归约操作:从操作数栈和操作符栈中构建表达式
504
505// 操作符优先级
506fn precedence(op: &Operator) -> u8 {
507    match op {
508        Operator::ArithmeticUnary(_) => 8, // 一元操作符的优先级高于二元操作符
509        Operator::Arithmetic(arithmetic_op) => match arithmetic_op {
510            ArithmeticOp::Mul | ArithmeticOp::Div | ArithmeticOp::Mod => 7,
511            ArithmeticOp::Add | ArithmeticOp::Sub => 6,
512        },
513        Operator::Compare(_) => 5,
514        Operator::ListInOp(_) => 5,
515        Operator::Logic(logic_op) => match logic_op {
516            LogicOp::Not => 4,
517            LogicOp::And => 3,
518            LogicOp::Or => 2,
519        },
520        Operator::Connect(_) => 1,
521        Operator::Paren(_) | Operator::FnCall(_) => 0, // 括号优先级最低
522    }
523}