alopex_sql/
dialect.rs

1use crate::ast::{Expr, Statement};
2use crate::error::Result;
3use crate::parser::Parser;
4use crate::parser::precedence::Precedence;
5
6/// SQL方言ごとのカスタマイズポイントを提供するトrait。
7pub trait Dialect: std::fmt::Debug {
8    /// 識別子の先頭として利用可能な文字かを判定する。
9    fn is_identifier_start(&self, ch: char) -> bool;
10
11    /// 識別子の残りの文字として利用可能な文字かを判定する。
12    fn is_identifier_part(&self, ch: char) -> bool;
13
14    /// 方言固有のステートメントパースを行う。対応しない場合は`None`を返す。
15    fn parse_statement(&self, parser: &mut Parser<'_>) -> Option<Result<Statement>>;
16
17    /// 方言固有のプレフィックスパース(例: ベクトルリテラル)を行う。
18    fn parse_prefix(&self, parser: &mut Parser<'_>) -> Option<Result<Expr>>;
19
20    /// 優先順位の数値を返す。方言で演算子優先順位を調整する場合に使う。
21    fn prec_value(&self, prec: Precedence) -> u8;
22}
23
24/// Alopex標準のSQL方言。
25#[derive(Debug, Default, Clone)]
26pub struct AlopexDialect;
27
28impl Dialect for AlopexDialect {
29    fn is_identifier_start(&self, ch: char) -> bool {
30        ch == '_' || ch.is_ascii_alphabetic()
31    }
32
33    fn is_identifier_part(&self, ch: char) -> bool {
34        ch == '_' || ch.is_ascii_alphanumeric()
35    }
36
37    fn parse_statement(&self, _parser: &mut Parser<'_>) -> Option<Result<Statement>> {
38        None
39    }
40
41    fn parse_prefix(&self, parser: &mut Parser<'_>) -> Option<Result<Expr>> {
42        if matches!(
43            parser.peek().token,
44            crate::tokenizer::token::Token::LBracket
45        ) {
46            return Some(parser.parse_vector_literal());
47        }
48        None
49    }
50
51    fn prec_value(&self, prec: Precedence) -> u8 {
52        prec.value()
53    }
54}