sqlite3_parser/lexer/
scan.rs1use log::debug;
4
5use std::error::Error;
6use std::fmt;
7use std::io;
8
9#[derive(Debug)]
11pub struct Pos {
12 pub line: usize,
14 pub column: usize,
16}
17
18impl Pos {
19 pub fn from(input: &[u8], offset: usize) -> Self {
20 let (mut line, mut column) = (1, 1);
21 for byte in &input[..offset] {
22 if *byte == b'\n' {
23 line += 1;
24 column = 1;
25 } else {
26 column += 1;
27 }
28 }
29 Self { line, column }
30 }
31}
32
33impl fmt::Display for Pos {
34 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
35 write!(f, "line: {}, column: {}", self.line, self.column)
36 }
37}
38
39pub trait ScanError: Error + From<io::Error> + Sized {
41 fn position(&mut self, p: Pos);
43}
44
45type SplitResult<'input, TokenType, Error> =
48 Result<(Option<(&'input [u8], TokenType)>, usize), Error>;
49
50pub trait Splitter: Sized {
52 type Error: ScanError;
54 type TokenType: std::fmt::Debug;
57
58 fn split<'input>(
66 &mut self,
67 data: &'input [u8],
68 ) -> SplitResult<'input, Self::TokenType, Self::Error>;
69}
70
71pub struct Scanner<S: Splitter> {
79 offset: usize,
81 mark: usize,
83 splitter: S,
85}
86
87impl<S: Splitter> Scanner<S> {
88 pub fn new(splitter: S) -> Self {
90 Self {
91 offset: 0,
92 mark: 0,
93 splitter,
94 }
95 }
96
97 pub fn position(&self, input: &[u8]) -> Pos {
99 Pos::from(input, self.offset)
100 }
101
102 pub fn splitter(&self) -> &S {
104 &self.splitter
105 }
106 pub fn mark(&mut self) {
108 self.mark = self.offset;
109 }
110 pub fn reset_to_mark(&mut self) {
112 self.offset = self.mark;
113 }
114
115 pub fn reset(&mut self) {
117 self.offset = 0;
118 }
119}
120
121type ScanResult<'input, TokenType, Error> =
122 Result<(usize, Option<(&'input [u8], TokenType)>, usize), Error>;
123
124impl<S: Splitter> Scanner<S> {
125 pub fn scan<'input>(
130 &mut self,
131 input: &'input [u8],
132 ) -> ScanResult<'input, S::TokenType, S::Error> {
133 debug!(target: "scanner", "scan({})", Pos::from(input, self.offset));
134 loop {
136 if self.offset < input.len() {
138 let data = &input[self.offset..];
139 match self.splitter.split(data) {
140 Err(mut e) => {
141 e.position(Pos::from(input, self.offset));
142 return Err(e);
143 }
144 Ok((None, 0)) => {
145 }
147 Ok((None, amt)) => {
148 self.consume(data, amt);
150 continue;
151 }
152 Ok((tok, amt)) => {
153 let start = self.offset;
154 self.consume(data, amt);
155 debug!(target: "scanner", "scan(start: {}, tok: {:?}, offset: {})", start, tok, self.offset);
156 return Ok((start, tok, self.offset));
157 }
158 }
159 }
160 return Ok((self.offset, None, self.offset));
163 }
164 }
165
166 fn consume(&mut self, data: &[u8], amt: usize) {
168 debug!(target: "scanner", "consume({amt})");
169 debug_assert!(amt <= data.len());
170 self.offset += amt;
171 }
172}
173
174impl<S: Splitter> fmt::Debug for Scanner<S> {
175 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
176 f.debug_struct("Scanner")
177 .field("offset", &self.offset)
178 .field("mark", &self.mark)
179 .finish()
180 }
181}