1use crate::ast::{BinaryOp, Expr, ExprKind, Literal, Spanned, UnaryOp};
2use crate::error::{ParserError, Result};
3use crate::tokenizer::keyword::Keyword;
4use crate::tokenizer::token::{Token, Word};
5
6use super::Parser;
7use super::precedence::{PREC_UNKNOWN, Precedence};
8
9impl<'a> Parser<'a> {
10 pub(crate) fn parse_subexpr(&mut self, precedence: u8) -> Result<Expr> {
11 let _guard = self.recursion.try_decrease()?;
12
13 let mut expr = self.parse_prefix()?;
14
15 loop {
16 let next_prec = self.next_precedence();
17 if precedence >= next_prec || next_prec == PREC_UNKNOWN {
18 break;
19 }
20 expr = self.parse_infix(expr, next_prec)?;
21 }
22
23 Ok(expr)
24 }
25
26 fn parse_prefix(&mut self) -> Result<Expr> {
27 if let Some(res) = self.dialect.parse_prefix(self) {
28 return res;
29 }
30
31 let token = self.peek().clone();
32 match &token.token {
33 Token::Number(n) => {
34 self.advance();
35 Ok(Expr::new(
36 ExprKind::Literal(Literal::Number(n.clone())),
37 token.span,
38 ))
39 }
40 Token::SingleQuotedString(s) => {
41 self.advance();
42 Ok(Expr::new(
43 ExprKind::Literal(Literal::String(s.clone())),
44 token.span,
45 ))
46 }
47 Token::Word(Word { keyword, value, .. }) => match keyword {
48 Keyword::TRUE => {
49 self.advance();
50 Ok(Expr::new(
51 ExprKind::Literal(Literal::Boolean(true)),
52 token.span,
53 ))
54 }
55 Keyword::FALSE => {
56 self.advance();
57 Ok(Expr::new(
58 ExprKind::Literal(Literal::Boolean(false)),
59 token.span,
60 ))
61 }
62 Keyword::NULL => {
63 self.advance();
64 Ok(Expr::new(ExprKind::Literal(Literal::Null), token.span))
65 }
66 Keyword::NOT => {
67 self.advance();
68 let operand =
69 self.parse_subexpr(self.dialect.prec_value(Precedence::UnaryNot))?;
70 let span = token.span.union(&operand.span());
71 Ok(Expr::new(
72 ExprKind::UnaryOp {
73 op: UnaryOp::Not,
74 operand: Box::new(operand),
75 },
76 span,
77 ))
78 }
79 Keyword::NoKeyword => {
80 self.advance();
82 let ident_span = token.span;
83 if let Token::LParen = self.peek().token {
84 self.advance(); let mut args = Vec::new();
86 let mut distinct = false;
87 let mut star = false;
88 if !matches!(self.peek().token, Token::RParen) {
89 if matches!(self.peek().token, Token::Mul) {
90 self.advance();
91 star = true;
92 } else {
93 if self.consume_keyword(Keyword::DISTINCT) {
94 distinct = true;
95 }
96 loop {
97 args.push(self.parse_subexpr(PREC_UNKNOWN)?);
98 if matches!(self.peek().token, Token::Comma) {
99 self.advance();
100 continue;
101 }
102 break;
103 }
104 }
105 }
106 self.expect_token("')'", |t| matches!(t, Token::RParen))?;
107 let end_span = self.prev().map(|t| t.span).unwrap_or(ident_span);
108 Ok(Expr::new(
109 ExprKind::FunctionCall {
110 name: value.clone(),
111 args,
112 distinct,
113 star,
114 },
115 ident_span.union(&end_span),
116 ))
117 } else if matches!(self.peek().token, Token::Period) {
118 self.advance(); let second = self.expect_token("identifier", |t| {
120 matches!(
121 t,
122 Token::Word(Word {
123 keyword: Keyword::NoKeyword,
124 ..
125 })
126 )
127 })?;
128 let end_span = second.span;
129 let col = match second.token {
130 Token::Word(Word { value, .. }) => value,
131 _ => unreachable!(),
132 };
133 Ok(Expr::new(
134 ExprKind::ColumnRef {
135 table: Some(value.clone()),
136 column: col,
137 },
138 ident_span.union(&end_span),
139 ))
140 } else {
141 Ok(Expr::new(
142 ExprKind::ColumnRef {
143 table: None,
144 column: value.clone(),
145 },
146 ident_span,
147 ))
148 }
149 }
150 _ => Err(ParserError::UnexpectedToken {
151 line: token.span.start.line,
152 column: token.span.start.column,
153 expected: "identifier or literal".into(),
154 found: format!("{:?}", token.token),
155 }),
156 },
157 Token::LParen => {
158 self.advance();
159 let expr = self.parse_subexpr(PREC_UNKNOWN)?;
160 self.expect_token("')'", |t| matches!(t, Token::RParen))?;
161 let end_span = self.prev().map(|t| t.span).unwrap_or(expr.span());
162 Ok(Expr::new(expr.kind.clone(), expr.span().union(&end_span)))
163 }
164 Token::Minus => {
165 self.advance();
166 let operand = self.parse_subexpr(self.dialect.prec_value(Precedence::UnaryNot))?;
167 let span = token.span.union(&operand.span());
168 Ok(Expr::new(
169 ExprKind::UnaryOp {
170 op: UnaryOp::Minus,
171 operand: Box::new(operand),
172 },
173 span,
174 ))
175 }
176 _ => Err(ParserError::UnexpectedToken {
177 line: token.span.start.line,
178 column: token.span.start.column,
179 expected: "expression".into(),
180 found: format!("{:?}", token.token),
181 }),
182 }
183 }
184
185 pub(crate) fn parse_vector_literal(&mut self) -> Result<Expr> {
186 let start = self.peek().span;
187 self.advance(); let mut values = Vec::new();
190 if matches!(self.peek().token, Token::RBracket) {
191 return Err(ParserError::InvalidVector {
192 line: start.start.line,
193 column: start.start.column,
194 });
195 }
196 loop {
197 let sign = if matches!(self.peek().token, Token::Minus) {
198 self.advance();
199 -1.0
200 } else {
201 1.0
202 };
203
204 let tok = self.expect_token("number", |t| matches!(t, Token::Number(_)))?;
205 let num = match tok.token {
206 Token::Number(n) => n.parse::<f64>().map_err(|_| ParserError::InvalidVector {
207 line: tok.span.start.line,
208 column: tok.span.start.column,
209 })?,
210 _ => unreachable!(),
211 } * sign;
212 values.push(num);
213 if matches!(self.peek().token, Token::Comma) {
214 self.advance();
215 continue;
216 }
217 break;
218 }
219 let end = self
220 .expect_token("']'", |t| matches!(t, Token::RBracket))?
221 .span;
222
223 Ok(Expr::new(
224 ExprKind::VectorLiteral(values),
225 start.union(&end),
226 ))
227 }
228
229 fn parse_infix(&mut self, left: Expr, precedence: u8) -> Result<Expr> {
230 let op_token = self.peek().clone();
231 match &op_token.token {
232 Token::Plus
233 | Token::Minus
234 | Token::Mul
235 | Token::Div
236 | Token::Mod
237 | Token::StringConcat => {
238 self.advance();
239 let op = match op_token.token {
240 Token::Plus => BinaryOp::Add,
241 Token::Minus => BinaryOp::Sub,
242 Token::Mul => BinaryOp::Mul,
243 Token::Div => BinaryOp::Div,
244 Token::Mod => BinaryOp::Mod,
245 Token::StringConcat => BinaryOp::StringConcat,
246 _ => unreachable!(),
247 };
248 let right = self.parse_subexpr(precedence)?;
249 let span = left.span().union(&right.span());
250 Ok(Expr::new(
251 ExprKind::BinaryOp {
252 left: Box::new(left),
253 op,
254 right: Box::new(right),
255 },
256 span,
257 ))
258 }
259 Token::Eq | Token::Neq | Token::Lt | Token::Gt | Token::LtEq | Token::GtEq => {
260 self.advance();
261 let op = match op_token.token {
262 Token::Eq => BinaryOp::Eq,
263 Token::Neq => BinaryOp::Neq,
264 Token::Lt => BinaryOp::Lt,
265 Token::Gt => BinaryOp::Gt,
266 Token::LtEq => BinaryOp::LtEq,
267 Token::GtEq => BinaryOp::GtEq,
268 _ => unreachable!(),
269 };
270 let right = self.parse_subexpr(precedence)?;
271 let span = left.span().union(&right.span());
272 Ok(Expr::new(
273 ExprKind::BinaryOp {
274 left: Box::new(left),
275 op,
276 right: Box::new(right),
277 },
278 span,
279 ))
280 }
281 Token::Word(Word { keyword, .. }) => match keyword {
282 Keyword::AND | Keyword::OR => {
283 self.advance();
284 let op = if *keyword == Keyword::AND {
285 BinaryOp::And
286 } else {
287 BinaryOp::Or
288 };
289 let right = self.parse_subexpr(precedence)?;
290 let span = left.span().union(&right.span());
291 Ok(Expr::new(
292 ExprKind::BinaryOp {
293 left: Box::new(left),
294 op,
295 right: Box::new(right),
296 },
297 span,
298 ))
299 }
300 Keyword::BETWEEN => {
301 self.advance();
302 let low = self.parse_subexpr(self.dialect.prec_value(Precedence::Between))?;
303 self.expect_keyword("AND", Keyword::AND)?;
304 let high = self.parse_subexpr(self.dialect.prec_value(Precedence::Between))?;
305 let span = left.span().union(&high.span());
306 Ok(Expr::new(
307 ExprKind::Between {
308 expr: Box::new(left),
309 low: Box::new(low),
310 high: Box::new(high),
311 negated: false,
312 },
313 span,
314 ))
315 }
316 Keyword::LIKE => {
317 self.advance();
318 let pattern = self.parse_subexpr(self.dialect.prec_value(Precedence::Like))?;
319 let escape = if self.consume_keyword(Keyword::ESCAPE) {
320 Some(Box::new(
321 self.parse_subexpr(self.dialect.prec_value(Precedence::Like))?,
322 ))
323 } else {
324 None
325 };
326 let span = left.span().union(&pattern.span());
327 let span = if let Some(ref esc) = escape {
328 span.union(&esc.span())
329 } else {
330 span
331 };
332 Ok(Expr::new(
333 ExprKind::Like {
334 expr: Box::new(left),
335 pattern: Box::new(pattern),
336 escape,
337 negated: false,
338 },
339 span,
340 ))
341 }
342 Keyword::IN => {
343 self.advance();
344 self.expect_token("'('", |t| matches!(t, Token::LParen))?;
345 let mut list = Vec::new();
346 if !matches!(self.peek().token, Token::RParen) {
347 loop {
348 list.push(self.parse_subexpr(PREC_UNKNOWN)?);
349 if matches!(self.peek().token, Token::Comma) {
350 self.advance();
351 continue;
352 }
353 break;
354 }
355 }
356 let end_span = self
357 .expect_token("')'", |t| matches!(t, Token::RParen))?
358 .span;
359 let span = left.span().union(&end_span);
360 Ok(Expr::new(
361 ExprKind::InList {
362 expr: Box::new(left),
363 list,
364 negated: false,
365 },
366 span,
367 ))
368 }
369 Keyword::IS => {
370 self.advance();
371 let negated = self.consume_keyword(Keyword::NOT);
372 self.expect_keyword("NULL", Keyword::NULL)?;
373 let span = left.span().union(&self.prev().unwrap().span);
374 Ok(Expr::new(
375 ExprKind::IsNull {
376 expr: Box::new(left),
377 negated,
378 },
379 span,
380 ))
381 }
382 Keyword::NOT => {
383 if let Some(next_kw) = self.peek_keyword_ahead(1) {
385 match next_kw {
386 Keyword::BETWEEN => {
387 self.advance(); self.advance(); let low = self
390 .parse_subexpr(self.dialect.prec_value(Precedence::Between))?;
391 self.expect_keyword("AND", Keyword::AND)?;
392 let high = self
393 .parse_subexpr(self.dialect.prec_value(Precedence::Between))?;
394 let span = left.span().union(&high.span());
395 return Ok(Expr::new(
396 ExprKind::Between {
397 expr: Box::new(left),
398 low: Box::new(low),
399 high: Box::new(high),
400 negated: true,
401 },
402 span,
403 ));
404 }
405 Keyword::LIKE => {
406 self.advance(); self.advance(); let pattern =
409 self.parse_subexpr(self.dialect.prec_value(Precedence::Like))?;
410 let escape = if self.consume_keyword(Keyword::ESCAPE) {
411 Some(Box::new(self.parse_subexpr(
412 self.dialect.prec_value(Precedence::Like),
413 )?))
414 } else {
415 None
416 };
417 let span = left.span().union(&pattern.span());
418 let span = if let Some(ref esc) = escape {
419 span.union(&esc.span())
420 } else {
421 span
422 };
423 return Ok(Expr::new(
424 ExprKind::Like {
425 expr: Box::new(left),
426 pattern: Box::new(pattern),
427 escape,
428 negated: true,
429 },
430 span,
431 ));
432 }
433 Keyword::IN => {
434 self.advance(); self.advance(); self.expect_token("'('", |t| matches!(t, Token::LParen))?;
437 let mut list = Vec::new();
438 if !matches!(self.peek().token, Token::RParen) {
439 loop {
440 list.push(self.parse_subexpr(PREC_UNKNOWN)?);
441 if matches!(self.peek().token, Token::Comma) {
442 self.advance();
443 continue;
444 }
445 break;
446 }
447 }
448 let end_span = self
449 .expect_token("')'", |t| matches!(t, Token::RParen))?
450 .span;
451 let span = left.span().union(&end_span);
452 return Ok(Expr::new(
453 ExprKind::InList {
454 expr: Box::new(left),
455 list,
456 negated: true,
457 },
458 span,
459 ));
460 }
461 _ => {}
462 }
463 }
464 Err(ParserError::UnexpectedToken {
465 line: op_token.span.start.line,
466 column: op_token.span.start.column,
467 expected: "BETWEEN, LIKE, IN".into(),
468 found: "NOT".into(),
469 })
470 }
471 _ => Err(ParserError::UnexpectedToken {
472 line: op_token.span.start.line,
473 column: op_token.span.start.column,
474 expected: "operator".into(),
475 found: format!("{:?}", op_token.token),
476 }),
477 },
478 _ => Err(ParserError::UnexpectedToken {
479 line: op_token.span.start.line,
480 column: op_token.span.start.column,
481 expected: "operator".into(),
482 found: format!("{:?}", op_token.token),
483 }),
484 }
485 }
486}