1use crate::ast::{
12 Access, App, Attrs, Binary, Expr, Field, Limit, Order, OrderBy, Query, Source, SourceKind,
13 Unary, Value,
14};
15use crate::error::ParserError;
16use crate::token::{Operator, Sym, Symbol, Token};
17use crate::{Binding, GroupBy, Raw};
18
19pub type ParseResult<A> = Result<A, ParserError>;
23
24pub struct Parser<'a> {
29 input: &'a [Token<'a>],
30 offset: usize,
31}
32
33impl<'a> Parser<'a> {
34 pub fn new(input: &'a [Token<'a>]) -> Self {
45 Self { input, offset: 0 }
46 }
47
48 fn peek<'b>(&'b self) -> Token<'a> {
49 self.input[self.offset]
50 }
51
52 fn shift<'b>(&'b mut self) -> Token<'a> {
53 let res = self.input[self.offset];
54
55 if self.offset + 1 < self.input.len() {
56 self.offset += 1;
57 }
58
59 res
60 }
61
62 fn parse_ident(&mut self) -> ParseResult<String> {
63 let token = self.shift();
64
65 if let Sym::Id(id) = token.sym {
66 return Ok(id.to_owned());
67 }
68
69 Err(ParserError::ExpectedIdent(
70 token.line,
71 token.col,
72 token.sym.to_string(),
73 ))
74 }
75
76 fn parse_source_kind(&mut self) -> ParseResult<SourceKind<Raw>> {
77 let token = self.shift();
78 match token.sym {
79 Sym::Id(id) => Ok(SourceKind::Name(id.to_owned())),
80 Sym::String(sub) => Ok(SourceKind::Subject(sub.to_owned())),
81 Sym::Symbol(Symbol::OpenParen) => {
82 let query = self.parse_query()?;
83 expect_symbol(self.shift(), Symbol::CloseParen)?;
84
85 Ok(SourceKind::Subquery(Box::new(query)))
86 }
87 _ => Err(ParserError::UnexpectedToken(
88 token.line,
89 token.col,
90 token.sym.to_string(),
91 )),
92 }
93 }
94
95 fn parse_source(&mut self) -> ParseResult<Source<Raw>> {
96 expect_keyword(self.shift(), "from")?;
97
98 let token = self.shift();
99 let binding = if let Sym::Id(name) = token.sym {
100 Binding {
101 name: name.to_owned(),
102 pos: token.into(),
103 }
104 } else {
105 return Err(ParserError::ExpectedIdent(
106 token.line,
107 token.col,
108 token.sym.to_string(),
109 ));
110 };
111
112 expect_keyword(self.shift(), "in")?;
113 let kind = self.parse_source_kind()?;
114
115 Ok(Source { binding, kind })
116 }
117
118 fn parse_where_clause(&mut self) -> ParseResult<Expr> {
119 expect_keyword(self.shift(), "where")?;
120 self.parse_expr()
121 }
122
123 fn parse_group_by(&mut self) -> ParseResult<GroupBy> {
124 expect_keyword(self.shift(), "group")?;
125 expect_keyword(self.shift(), "by")?;
126
127 let expr = self.parse_expr()?;
128
129 let predicate = if let Sym::Id(name) = self.peek().sym
130 && name.eq_ignore_ascii_case("having")
131 {
132 self.shift();
133
134 Some(self.parse_expr()?)
135 } else {
136 None
137 };
138
139 Ok(GroupBy { expr, predicate })
140 }
141
142 fn parse_order_by(&mut self) -> ParseResult<OrderBy> {
143 expect_keyword(self.shift(), "order")?;
144 expect_keyword(self.shift(), "by")?;
145
146 let expr = self.parse_expr()?;
147 let token = self.shift();
148
149 if let Sym::Id(name) = token.sym {
150 let order = if name.eq_ignore_ascii_case("asc") {
151 Order::Asc
152 } else if name.eq_ignore_ascii_case("desc") {
153 Order::Desc
154 } else {
155 return Err(ParserError::UnexpectedToken(
156 token.line,
157 token.col,
158 name.to_owned(),
159 ));
160 };
161
162 return Ok(OrderBy { expr, order });
163 }
164
165 Err(ParserError::UnexpectedToken(
166 token.line,
167 token.col,
168 token.sym.to_string(),
169 ))
170 }
171
172 fn parse_limit(&mut self) -> ParseResult<Limit> {
173 let token = self.shift();
174 let limit = expect_keyword(token, "top")
175 .map(|_| "top")
176 .or_else(|_| expect_keyword(token, "skip").map(|_| "skip"))
177 .map_err(|_| {
178 ParserError::UnexpectedToken(token.line, token.col, token.sym.to_string())
179 })?;
180
181 let token = self.shift();
182 if let Sym::Number(value) = token.sym
183 && value.fract() == 0.0
184 {
185 return match limit {
186 "top" => Ok(Limit::Top(value as u64)),
187 "skip" => Ok(Limit::Skip(value as u64)),
188 _ => unreachable!(),
189 };
190 }
191
192 Err(ParserError::UnexpectedToken(
193 token.line,
194 token.col,
195 token.sym.to_string(),
196 ))
197 }
198
199 pub fn parse_expr(&mut self) -> ParseResult<Expr> {
217 let token = self.peek();
218
219 match token.sym {
220 Sym::Eof => Err(ParserError::UnexpectedEof),
221
222 Sym::Id(_)
223 | Sym::String(_)
224 | Sym::Number(_)
225 | Sym::Symbol(Symbol::OpenParen | Symbol::OpenBracket | Symbol::OpenBrace)
226 | Sym::Operator(Operator::Add | Operator::Sub | Operator::Not) => self.parse_binary(0),
227
228 _ => Err(ParserError::UnexpectedToken(
229 token.line,
230 token.col,
231 token.sym.to_string(),
232 )),
233 }
234 }
235
236 fn parse_primary(&mut self) -> ParseResult<Expr> {
237 let token = self.shift();
238
239 let value = match token.sym {
240 Sym::Id(name) => {
241 if name.eq_ignore_ascii_case("true") {
242 Value::Bool(true)
243 } else if name.eq_ignore_ascii_case("false") {
244 Value::Bool(false)
245 } else if matches!(self.peek().sym, Sym::Symbol(Symbol::OpenParen)) {
246 self.shift();
247
248 let mut args = vec![];
249
250 if !matches!(self.peek().sym, Sym::Symbol(Symbol::CloseParen)) {
251 args.push(self.parse_expr()?);
252
253 while matches!(self.peek().sym, Sym::Symbol(Symbol::Comma)) {
254 self.shift();
255 args.push(self.parse_expr()?);
256 }
257 }
258
259 expect_symbol(self.shift(), Symbol::CloseParen)?;
260
261 Value::App(App {
262 func: name.to_owned(),
263 args,
264 })
265 } else if matches!(self.peek().sym, Sym::Symbol(Symbol::Dot)) {
266 self.shift();
267 let mut access = Access {
268 target: Box::new(Expr {
269 attrs: Attrs::new(token.into()),
270 value: Value::Id(name.to_owned()),
271 }),
272 field: self.parse_ident()?,
273 };
274
275 while matches!(self.peek().sym, Sym::Symbol(Symbol::Dot)) {
276 self.shift();
277 access = Access {
278 target: Box::new(Expr {
279 attrs: access.target.attrs,
280 value: Value::Access(access),
281 }),
282 field: self.parse_ident()?,
283 };
284 }
285
286 Value::Access(access)
287 } else {
288 Value::Id(name.to_owned())
289 }
290 }
291
292 Sym::String(s) => Value::String(s.to_owned()),
293 Sym::Number(n) => Value::Number(n),
294
295 Sym::Symbol(Symbol::OpenParen) => {
296 let expr = self.parse_expr()?;
297 expect_symbol(self.shift(), Symbol::CloseParen)?;
298
299 Value::Group(Box::new(expr))
300 }
301
302 Sym::Symbol(Symbol::OpenBracket) => {
303 let mut elems = vec![];
304
305 if !matches!(self.peek().sym, Sym::Symbol(Symbol::CloseBracket)) {
306 elems.push(self.parse_expr()?);
307
308 while matches!(self.peek().sym, Sym::Symbol(Symbol::Comma)) {
309 self.shift();
310 elems.push(self.parse_expr()?);
311 }
312 }
313
314 expect_symbol(self.shift(), Symbol::CloseBracket)?;
315
316 Value::Array(elems)
317 }
318
319 Sym::Symbol(Symbol::OpenBrace) => {
320 let mut fields = vec![];
321
322 if !matches!(self.peek().sym, Sym::Symbol(Symbol::CloseBrace)) {
323 let name = self.parse_ident()?;
324 expect_symbol(self.shift(), Symbol::Colon)?;
325 let value = self.parse_expr()?;
326
327 fields.push(Field { name, value });
328
329 while matches!(self.peek().sym, Sym::Symbol(Symbol::Comma)) {
330 self.shift();
331
332 let name = self.parse_ident()?;
333 expect_symbol(self.shift(), Symbol::Colon)?;
334 let value = self.parse_expr()?;
335
336 fields.push(Field { name, value });
337 }
338 }
339
340 expect_symbol(self.shift(), Symbol::CloseBrace)?;
341
342 Value::Record(fields)
343 }
344
345 Sym::Operator(op) if matches!(op, Operator::Add | Operator::Sub | Operator::Not) => {
346 Value::Unary(Unary {
347 operator: op,
348 expr: Box::new(self.parse_expr()?),
349 })
350 }
351
352 _ => {
353 return Err(ParserError::UnexpectedToken(
354 token.line,
355 token.col,
356 token.sym.to_string(),
357 ));
358 }
359 };
360
361 Ok(Expr {
362 attrs: Attrs::new(token.into()),
363 value,
364 })
365 }
366
367 fn parse_binary(&mut self, min_bind: u64) -> ParseResult<Expr> {
368 let mut lhs = self.parse_primary()?;
369
370 loop {
371 let token = self.peek();
372 let operator = if let Sym::Operator(op) = token.sym {
373 op
374 } else {
375 break;
376 };
377
378 let (lhs_bind, rhs_bind) = binding_pow(operator);
379
380 if lhs_bind < min_bind {
381 break;
382 }
383
384 self.shift();
385 let rhs = self.parse_binary(rhs_bind)?;
386
387 if matches!(operator, Operator::As) && !matches!(rhs.value, Value::Id(_)) {
388 return Err(ParserError::ExpectedType(
389 rhs.attrs.pos.line,
390 rhs.attrs.pos.col,
391 ));
392 }
393
394 lhs = Expr {
395 attrs: lhs.attrs,
396 value: Value::Binary(Binary {
397 lhs: Box::new(lhs),
398 operator,
399 rhs: Box::new(rhs),
400 }),
401 };
402 }
403
404 Ok(lhs)
405 }
406
407 fn parse_query(&mut self) -> ParseResult<Query<Raw>> {
408 let mut sources = vec![];
409 let pos = self.peek().into();
410
411 while let Sym::Id(name) = self.peek().sym
412 && name.eq_ignore_ascii_case("from")
413 {
414 sources.push(self.parse_source()?);
415 }
416
417 if sources.is_empty() {
418 let token = self.peek();
419 return Err(ParserError::MissingFromStatement(token.line, token.col));
420 }
421
422 let predicate = if let Sym::Id(name) = self.peek().sym
423 && name.eq_ignore_ascii_case("where")
424 {
425 Some(self.parse_where_clause()?)
426 } else {
427 None
428 };
429
430 let group_by = if let Sym::Id(name) = self.peek().sym
431 && name.eq_ignore_ascii_case("group")
432 {
433 Some(self.parse_group_by()?)
434 } else {
435 None
436 };
437
438 let order_by = if let Sym::Id(name) = self.peek().sym
439 && name.eq_ignore_ascii_case("order")
440 {
441 Some(self.parse_order_by()?)
442 } else {
443 None
444 };
445
446 let limit = if let Sym::Id(name) = self.peek().sym
447 && (name.eq_ignore_ascii_case("skip") || name.eq_ignore_ascii_case("top"))
448 {
449 Some(self.parse_limit()?)
450 } else {
451 None
452 };
453
454 expect_keyword(self.shift(), "project")?;
455 expect_keyword(self.shift(), "into")?;
456
457 let distinct = if let Sym::Id(name) = self.peek().sym
458 && name.eq_ignore_ascii_case("distinct")
459 {
460 self.shift();
461 true
462 } else {
463 false
464 };
465
466 let projection = self.parse_expr()?;
467
468 Ok(Query {
469 attrs: Attrs::new(pos),
470 sources,
471 predicate,
472 group_by,
473 order_by,
474 limit,
475 projection,
476 distinct,
477 meta: Raw,
478 })
479 }
480}
481
482fn expect_keyword(token: Token, keyword: &'static str) -> ParseResult<()> {
483 if let Sym::Id(id) = token.sym
484 && id.eq_ignore_ascii_case(keyword)
485 {
486 return Ok(());
487 }
488
489 Err(ParserError::ExpectedKeyword(
490 token.line,
491 token.col,
492 keyword,
493 token.sym.to_string(),
494 ))
495}
496
497fn expect_symbol(token: Token, expect: Symbol) -> ParseResult<()> {
498 if let Sym::Symbol(sym) = token.sym
499 && sym == expect
500 {
501 return Ok(());
502 }
503
504 Err(ParserError::ExpectedSymbol(
505 token.line,
506 token.col,
507 expect,
508 token.sym.to_string(),
509 ))
510}
511
512fn binding_pow(op: Operator) -> (u64, u64) {
514 match op {
515 Operator::Add | Operator::Sub => (20, 21),
516 Operator::Mul | Operator::Div => (30, 31),
517 Operator::Contains => (40, 39),
518 Operator::As => (50, 49),
519 Operator::Eq
520 | Operator::Neq
521 | Operator::Gt
522 | Operator::Lt
523 | Operator::Gte
524 | Operator::Lte => (10, 11),
525 Operator::And | Operator::Or | Operator::Xor | Operator::Not => (1, 2),
526 }
527}
528
529pub fn parse<'a>(input: &'a [Token<'a>]) -> ParseResult<Query<Raw>> {
562 let mut parser = Parser::new(input);
563
564 parser.parse_query()
565}