1use crate::ast::*;
2use crate::error::ParseError;
3use crate::lexer::{tokenize, Spanned, Token};
4
5mod clauses;
6mod expr;
7mod pattern;
8mod projection;
9
10pub struct Parser {
11 tokens: Vec<Spanned>,
12 pos: usize,
13}
14
15impl Parser {
16 fn new(tokens: Vec<Spanned>) -> Self {
17 Self { tokens, pos: 0 }
18 }
19
20 fn peek(&self) -> &Token {
21 &self.tokens[self.pos].token
22 }
23
24 fn span(&self) -> (u32, u32) {
25 let s = &self.tokens[self.pos];
26 (s.line, s.col)
27 }
28
29 fn bump(&mut self) -> &Token {
30 let tok = &self.tokens[self.pos].token;
31 if self.pos + 1 < self.tokens.len() {
32 self.pos += 1;
33 }
34 tok
35 }
36
37 fn expect(&mut self, expected: &Token) -> Result<(), ParseError> {
38 if self.peek() == expected {
39 self.bump();
40 Ok(())
41 } else {
42 let (line, col) = self.span();
43 Err(ParseError::new(
44 format!("expected {:?}, got {:?}", expected, self.peek()),
45 line,
46 col,
47 ))
48 }
49 }
50
51 fn eat(&mut self, tok: &Token) -> bool {
52 if self.peek() == tok {
53 self.bump();
54 true
55 } else {
56 false
57 }
58 }
59
60 fn at_eof(&self) -> bool {
61 matches!(self.peek(), Token::Eof)
62 }
63
64 fn peek_offset(&self, n: usize) -> &Token {
66 let idx = (self.pos + n).min(self.tokens.len() - 1);
67 &self.tokens[idx].token
68 }
69
70 fn parse_ident(&mut self) -> Result<String, ParseError> {
71 match self.peek().clone() {
72 Token::Ident(s) => {
73 self.bump();
74 Ok(s)
75 }
76 _ => {
77 let (line, col) = self.span();
78 Err(ParseError::new(
79 format!("expected identifier, got {:?}", self.peek()),
80 line,
81 col,
82 ))
83 }
84 }
85 }
86
87 fn parse_integer(&mut self) -> Result<i64, ParseError> {
88 match self.peek().clone() {
89 Token::Integer(n) => {
90 self.bump();
91 Ok(n)
92 }
93 _ => {
94 let (line, col) = self.span();
95 Err(ParseError::new(
96 format!("expected integer, got {:?}", self.peek()),
97 line,
98 col,
99 ))
100 }
101 }
102 }
103
104 fn parse_string_literal(&mut self) -> Result<String, ParseError> {
105 match self.peek().clone() {
106 Token::Str(s) => {
107 self.bump();
108 Ok(s)
109 }
110 _ => {
111 let (line, col) = self.span();
112 Err(ParseError::new(
113 format!("expected string literal, got {:?}", self.peek()),
114 line,
115 col,
116 ))
117 }
118 }
119 }
120}
121
122pub fn parse(input: &str) -> Result<Query, ParseError> {
123 let tokens = tokenize(input)?;
124 let mut parser = Parser::new(tokens);
125 parser.parse_query()
126}
127
128#[cfg(test)]
129mod tests;