databend_common_ast/parser/
input.rs1use std::iter::Enumerate;
16use std::ops::Bound;
17use std::ops::RangeBounds;
18
19use enum_as_inner::EnumAsInner;
20use nom::Needed;
21
22use crate::parser::Backtrace;
23use crate::parser::token::Token;
24
25#[derive(Debug, Clone, Copy)]
28pub struct Input<'a> {
29 pub tokens: &'a [Token<'a>],
30 pub dialect: Dialect,
31 pub mode: ParseMode,
32 pub backtrace: &'a Backtrace,
33}
34
35impl<'a> std::ops::Deref for Input<'a> {
36 type Target = [Token<'a>];
37
38 fn deref(&self) -> &Self::Target {
39 self.tokens
40 }
41}
42
43impl<'a> Input<'a> {
44 pub fn slice<R>(&self, range: R) -> Self
45 where R: RangeBounds<usize> {
46 let len = self.tokens.len();
47 let start = match range.start_bound() {
48 Bound::Included(&idx) => idx,
49 Bound::Excluded(&idx) => idx + 1,
50 Bound::Unbounded => 0,
51 };
52 let end = match range.end_bound() {
53 Bound::Included(&idx) => idx + 1,
54 Bound::Excluded(&idx) => idx,
55 Bound::Unbounded => len,
56 };
57
58 Input {
59 tokens: &self.tokens[start.min(len)..end.min(len)],
60 ..*self
61 }
62 }
63}
64
65impl nom::Offset for Input<'_> {
66 fn offset(&self, second: &Self) -> usize {
67 let fst = self.tokens.as_ptr();
68 let snd = second.tokens.as_ptr();
69
70 (snd as usize - fst as usize) / std::mem::size_of::<Token>()
71 }
72}
73
74impl<'a> nom::Input for Input<'a> {
75 type Item = &'a Token<'a>;
76 type Iter = std::slice::Iter<'a, Token<'a>>;
77 type IterIndices = Enumerate<Self::Iter>;
78
79 fn input_len(&self) -> usize {
80 self.tokens.len()
81 }
82
83 fn take(&self, index: usize) -> Self {
84 self.slice(0..index)
85 }
86
87 fn take_from(&self, index: usize) -> Self {
88 self.slice(index..)
89 }
90
91 fn take_split(&self, index: usize) -> (Self, Self) {
92 let (prefix, suffix) = self.tokens.split_at(index);
93
94 (
95 Input {
96 tokens: prefix,
97 ..*self
98 },
99 Input {
100 tokens: suffix,
101 ..*self
102 },
103 )
104 }
105
106 fn position<P>(&self, predicate: P) -> Option<usize>
107 where P: Fn(Self::Item) -> bool {
108 self.tokens.iter().position(predicate)
109 }
110
111 fn iter_elements(&self) -> Self::Iter {
112 self.tokens.iter()
113 }
114
115 fn iter_indices(&self) -> Self::IterIndices {
116 self.iter_elements().enumerate()
117 }
118
119 fn slice_index(&self, count: usize) -> Result<usize, Needed> {
120 if self.tokens.len() >= count {
121 Ok(count)
122 } else {
123 Err(Needed::new(count - self.tokens.len()))
124 }
125 }
126}
127
128#[derive(Clone, Debug)]
129pub struct WithSpan<'a, T> {
130 pub(crate) span: Input<'a>,
131 pub(crate) elem: T,
132}
133
134#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, EnumAsInner)]
135pub enum ParseMode {
136 #[default]
137 Default,
138 Template,
139}
140
141#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, EnumAsInner)]
142pub enum Dialect {
143 #[default]
144 PostgreSQL,
145 MySQL,
146 Hive,
147 PRQL,
148 Experimental,
149}
150
151impl Dialect {
152 pub fn is_ident_quote(&self, c: char) -> bool {
153 match self {
154 Dialect::MySQL => c == '`',
155 Dialect::Hive => c == '`',
156 Dialect::Experimental | Dialect::PostgreSQL | Dialect::PRQL => c == '"' || c == '`',
158 }
159 }
160
161 pub fn is_string_quote(&self, c: char) -> bool {
162 match self {
163 Dialect::MySQL => c == '\'' || c == '"',
164 Dialect::Hive => c == '\'' || c == '"',
165 Dialect::Experimental | Dialect::PostgreSQL | Dialect::PRQL => c == '\'',
166 }
167 }
168
169 pub fn substr_index_zero_literal_as_one(&self) -> bool {
170 match self {
171 Dialect::MySQL => false,
172 Dialect::Hive => true,
173 Dialect::Experimental | Dialect::PostgreSQL | Dialect::PRQL => false,
174 }
175 }
176
177 pub fn default_ident_quote(&self) -> char {
178 match self {
179 Dialect::MySQL | Dialect::Hive => '`',
180 Dialect::Experimental | Dialect::PostgreSQL | Dialect::PRQL => '"',
181 }
182 }
183}