libsql_sqlite3_parser/parser/
mod.rs1use log::error;
3
4pub mod ast;
5pub mod parse {
6 #![allow(unused_braces)]
7 #![allow(unused_comparisons)] #![allow(clippy::collapsible_if)]
9 #![allow(clippy::if_same_then_else)]
10 #![allow(clippy::absurd_extreme_comparisons)] #![allow(clippy::needless_return)]
12 #![allow(clippy::upper_case_acronyms)]
13 #![allow(clippy::manual_range_patterns)]
14 #![allow(unexpected_cfgs)]
15 include!(concat!(env!("OUT_DIR"), "/parse.rs"));
16}
17
18use crate::dialect::Token;
19use ast::{Cmd, ExplainKind, Name, Stmt};
20
21#[derive(Debug)]
23pub enum ParserError {
24 StackOverflow,
25 SyntaxError {
26 token_type: &'static str,
27 found: Option<String>,
28 },
29 UnexpectedEof,
30 Custom(String),
31}
32
33impl std::fmt::Display for ParserError {
34 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
35 match self {
36 ParserError::StackOverflow => f.write_str("parser overflowed its stack"),
37 ParserError::SyntaxError { token_type, found } => {
38 write!(f, "near {}, \"{:?}\": syntax error", token_type, found)
39 }
40 ParserError::UnexpectedEof => f.write_str("unexpected end of input"),
41 ParserError::Custom(s) => f.write_str(s),
42 }
43 }
44}
45
46impl std::error::Error for ParserError {}
47
48pub struct Context<'input> {
50 input: &'input [u8],
51 explain: Option<ExplainKind>,
52 stmt: Option<Stmt>,
53 constraint_name: Option<Name>, module_arg: Option<(usize, usize)>, module_args: Option<Vec<String>>, done: bool,
57 error: Option<ParserError>,
58}
59
60impl<'input> Context<'input> {
61 pub fn new(input: &'input [u8]) -> Context<'input> {
62 Context {
63 input,
64 explain: None,
65 stmt: None,
66 constraint_name: None,
67 module_arg: None,
68 module_args: None,
69 done: false,
70 error: None,
71 }
72 }
73
74 pub fn cmd(&mut self) -> Option<Cmd> {
76 if let Some(stmt) = self.stmt.take() {
77 match self.explain.take() {
78 Some(ExplainKind::Explain) => Some(Cmd::Explain(stmt)),
79 Some(ExplainKind::QueryPlan) => Some(Cmd::ExplainQueryPlan(stmt)),
80 None => Some(Cmd::Stmt(stmt)),
81 }
82 } else {
83 None
84 }
85 }
86
87 fn constraint_name(&mut self) -> Option<Name> {
88 self.constraint_name.take()
89 }
90 fn no_constraint_name(&self) -> bool {
91 self.constraint_name.is_none()
92 }
93
94 fn vtab_arg_init(&mut self) {
95 self.add_module_arg();
96 self.module_arg = None;
97 }
98 fn vtab_arg_extend(&mut self, any: Token) {
99 if let Some((_, ref mut n)) = self.module_arg {
100 *n = any.2
101 } else {
102 self.module_arg = Some((any.0, any.2))
103 }
104 }
105 fn add_module_arg(&mut self) {
106 if let Some((start, end)) = self.module_arg.take() {
107 if let Ok(arg) = std::str::from_utf8(&self.input[start..end]) {
108 self.module_args.get_or_insert(vec![]).push(arg.to_owned());
109 } }
111 }
112 fn module_args(&mut self) -> Option<Vec<String>> {
113 self.add_module_arg();
114 self.module_args.take()
115 }
116
117 fn sqlite3_error_msg(&mut self, msg: &str) {
118 error!("parser error: {}", msg);
119 }
120
121 fn sqlite3_finish_coding(&mut self) {
123 self.done = true;
124 }
125
126 pub fn done(&self) -> bool {
128 self.done || self.error.is_some()
129 }
130
131 pub fn is_ok(&self) -> bool {
132 self.error.is_none()
133 }
134
135 pub fn error(&mut self) -> Option<ParserError> {
137 self.error.take()
138 }
139
140 pub fn reset(&mut self) {
141 self.explain = None;
142 self.stmt = None;
143 self.constraint_name = None;
144 self.module_arg = None;
145 self.module_args = None;
146 self.done = false;
147 self.error = None;
148 }
149}