sqlite3_parser/parser/
mod.rs1use bumpalo::{collections::Vec, Bump};
3
4pub mod ast;
5pub mod parse {
6 #![expect(unused_braces)]
7 #![expect(clippy::absurd_extreme_comparisons)] #![expect(clippy::needless_return)]
9 #![expect(clippy::upper_case_acronyms)]
10 #![expect(clippy::manual_range_patterns)]
11
12 include!(concat!(env!("OUT_DIR"), "/parse.rs"));
13}
14mod stack;
15
16use crate::dialect::Token;
17use ast::{Cmd, ExplainKind, Name, Stmt};
18
19#[derive(Debug, PartialEq)]
21pub enum ParserError {
22 SyntaxError(String),
24 UnexpectedEof,
26 Custom(String),
28}
29
30impl std::fmt::Display for ParserError {
31 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
32 match self {
33 Self::SyntaxError(s) => {
34 write!(f, "near \"{s}\": syntax error")
35 }
36 Self::UnexpectedEof => f.write_str("unexpected end of input"),
37 Self::Custom(s) => f.write_str(s),
38 }
39 }
40}
41
42impl std::error::Error for ParserError {}
43
44#[macro_export]
46macro_rules! custom_err {
47 ($msg:literal $(,)?) => {
48 $crate::parser::ParserError::Custom($msg.to_owned())
49 };
50 ($err:expr $(,)?) => {
51 $crate::parser::ParserError::Custom(format!($err))
52 };
53 ($fmt:expr, $($arg:tt)*) => {
54 $crate::parser::ParserError::Custom(format!($fmt, $($arg)*))
55 };
56}
57
58pub struct Context<'input> {
60 bump: &'input Bump,
61 input: &'input [u8],
62 explain: Option<ExplainKind>,
63 stmt: Option<Stmt<'input>>,
64 constraint_name: Option<Name<'input>>, module_arg: Option<(usize, usize)>, module_args: Option<Vec<'input, &'input str>>, done: bool,
68 error: Option<ParserError>,
69}
70
71impl<'input> Context<'input> {
72 pub fn new(bump: &'input Bump, input: &'input [u8]) -> Self {
73 Context {
74 bump,
75 input,
76 explain: None,
77 stmt: None,
78 constraint_name: None,
79 module_arg: None,
80 module_args: None,
81 done: false,
82 error: None,
83 }
84 }
85
86 pub fn new_vec<T>(&mut self, e: T) -> Vec<'input, T> {
87 let mut vec = Vec::new_in(self.bump);
88 vec.push(e);
89 vec
90 }
91
92 pub fn cmd(&mut self) -> Option<Cmd<'input>> {
94 if let Some(stmt) = self.stmt.take() {
95 match self.explain.take() {
96 Some(ExplainKind::Explain) => Some(Cmd::Explain(stmt)),
97 Some(ExplainKind::QueryPlan) => Some(Cmd::ExplainQueryPlan(stmt)),
98 None => Some(Cmd::Stmt(stmt)),
99 }
100 } else {
101 None
102 }
103 }
104
105 fn constraint_name(&mut self) -> Option<Name<'input>> {
106 self.constraint_name.take()
107 }
108 fn no_constraint_name(&self) -> bool {
109 self.constraint_name.is_none()
110 }
111
112 fn vtab_arg_init(&mut self) {
113 self.add_module_arg();
114 self.module_arg = None;
115 }
116 fn vtab_arg_extend(&mut self, any: Token) {
117 if let Some((_, ref mut n)) = self.module_arg {
118 *n = any.2;
119 } else {
120 self.module_arg = Some((any.0, any.2));
121 }
122 }
123 fn add_module_arg(&mut self) {
124 if let Some((start, end)) = self.module_arg.take() {
125 if let Ok(arg) = std::str::from_utf8(&self.input[start..end]) {
126 self.module_args
127 .get_or_insert(Vec::new_in(self.bump))
128 .push(self.bump.alloc_str(arg));
129 } }
131 }
132 fn module_args(&mut self) -> Option<Vec<'input, &'input str>> {
133 self.add_module_arg();
134 self.module_args.take()
135 }
136
137 fn sqlite3_finish_coding(&mut self) {
139 self.done = true;
140 }
141
142 pub fn done(&self) -> bool {
144 self.done || self.error.is_some()
145 }
146
147 pub fn is_ok(&self) -> bool {
148 self.error.is_none()
149 }
150
151 pub fn error(&mut self) -> Option<ParserError> {
153 self.error.take()
154 }
155
156 pub fn reset(&mut self) {
157 self.explain = None;
158 self.stmt = None;
159 self.constraint_name = None;
160 self.module_arg = None;
161 self.module_args = None;
162 self.done = false;
163 self.error = None;
164 }
165}