ll_sparql_parser/parser/
mod.rs1mod grammar;
2
3use std::cell::Cell;
4
5use crate::SyntaxKind;
6use grammar::{parse_QueryUnit, parse_UpdateUnit};
7use logos::Logos;
8use rowan::{GreenNode, GreenNodeBuilder};
9
10pub struct Parser {
11 tokens: Vec<Token>,
12 pos: usize,
13 fuel: Cell<u32>,
14 events: Vec<Event>,
15}
16
17#[derive(Debug, Clone)]
18struct Token {
19 kind: SyntaxKind,
20 text: std::string::String,
21}
22
23impl Token {
24 fn is_trivia(&self) -> bool {
25 matches!(self.kind, SyntaxKind::WHITESPACE | SyntaxKind::Comment)
26 }
27}
28
29pub fn parse_text(input: &str, entry: TopEntryPoint) -> GreenNode {
30 let tokens = lex(input);
31 let parse_input = tokens
32 .iter()
33 .filter(|token| !token.is_trivia())
34 .cloned()
35 .collect();
36 let output = entry.parse(parse_input);
37 build_tree(tokens, output)
38}
39
40fn build_tree(tokens: Vec<Token>, events: Vec<Event>) -> GreenNode {
41 let mut tokens = tokens.into_iter().peekable();
42 let mut builder = GreenNodeBuilder::new();
43
44 for event in &events[..events.len() - 1] {
48 match event {
49 Event::Open { kind } => {
50 while *kind != SyntaxKind::QueryUnit
51 && tokens.peek().map_or(false, |next| next.is_trivia())
52 {
53 let token = tokens.next().unwrap();
54 builder.token(token.kind.into(), &token.text);
55 }
56 builder.start_node((*kind).into());
57 }
58 Event::Close => {
59 builder.finish_node();
60 }
61
62 Event::Advance => {
63 while tokens.peek().map_or(false, |next| next.is_trivia()) {
64 let token = tokens.next().unwrap();
65 builder.token(token.kind.into(), &token.text);
66 }
67 let token = tokens.next().unwrap();
68 builder.token(token.kind.into(), &token.text);
69 }
70 }
71 }
72 assert!(matches!(events.last(), Some(Event::Close)));
74 while tokens.peek().map_or(false, |next| next.is_trivia()) {
75 let token = tokens.next().unwrap();
76 builder.token(token.kind.into(), &token.text);
77 }
78 builder.finish_node();
79 builder.finish()
80}
81
82impl Parser {
83 fn new(input: Vec<Token>) -> Self {
84 Self {
85 tokens: input,
86 pos: 0,
87 fuel: 256.into(),
88 events: Vec::new(),
89 }
90 }
91}
92
93enum Event {
94 Open { kind: SyntaxKind },
95 Close,
96 Advance,
97}
98
99struct MarkOpened {
100 index: usize,
101}
102
103impl Parser {
104 fn open(&mut self) -> MarkOpened {
105 let mark = MarkOpened {
106 index: self.events.len(),
107 };
108 self.events.push(Event::Open {
109 kind: SyntaxKind::Error,
110 });
111 mark
112 }
113
114 fn close(&mut self, m: MarkOpened, kind: SyntaxKind) {
115 self.events[m.index] = Event::Open { kind };
116 self.events.push(Event::Close);
117 }
118
119 fn advance(&mut self) {
120 assert!(!self.eof());
121 self.fuel.set(256);
122 self.events.push(Event::Advance);
123 self.pos += 1;
124 }
125
126 fn eof(&self) -> bool {
127 self.pos == self.tokens.len()
128 }
129
130 fn nth(&self, lookahead: usize) -> SyntaxKind {
131 if self.fuel.get() == 0 {
132 panic!("parser is stuck")
133 }
134 self.fuel.set(self.fuel.get() - 1);
135 self.tokens
136 .get(self.pos + lookahead)
137 .map_or(SyntaxKind::Eof, |it| it.kind)
138 }
139
140 fn at(&self, kind: SyntaxKind) -> bool {
141 self.nth(0) == kind
142 }
143
144 fn at_any(&self, kinds: &[SyntaxKind]) -> bool {
145 kinds.iter().any(|kind| self.at(*kind))
146 }
147
148 fn eat(&mut self, kind: SyntaxKind) -> bool {
149 if self.at(kind) {
150 self.advance();
151 true
152 } else {
153 false
154 }
155 }
156
157 fn expect(&mut self, kind: SyntaxKind) {
158 if self.eat(kind) {
159 return;
160 }
161 eprintln!("expected {kind:?}");
163 }
164
165 fn advance_with_error(&mut self, error: &str) {
166 let m = self.open();
167 eprintln!("{error}");
169 self.advance();
170 self.close(m, SyntaxKind::Error);
171 }
172}
173
174#[derive(Debug)]
175pub enum TopEntryPoint {
176 QueryUnit,
177 UpdateUnit,
178}
179
180impl TopEntryPoint {
181 fn parse(&self, input: Vec<Token>) -> Vec<Event> {
182 let mut parser = Parser::new(input);
183 match self {
184 TopEntryPoint::QueryUnit => parse_QueryUnit(&mut parser),
185 TopEntryPoint::UpdateUnit => parse_UpdateUnit(&mut parser),
186 }
187 parser.events
188 }
189}
190
191fn lex(text: &str) -> Vec<Token> {
192 let mut lexer = SyntaxKind::lexer(text);
193 let mut tokens = Vec::new();
194
195 while let Some(result) = lexer.next() {
196 tokens.push(Token {
197 kind: result.unwrap_or(SyntaxKind::Error),
198 text: lexer.slice().to_string(),
199 });
200 }
201 tokens
202}
203
204pub fn guess_operation_type(input: &str) -> Option<TopEntryPoint> {
205 let tokens = lex(input);
206 tokens.iter().find_map(|token| match token.kind {
207 SyntaxKind::SELECT | SyntaxKind::CONSTRUCT | SyntaxKind::ASK | SyntaxKind::DESCRIBE => {
208 Some(TopEntryPoint::QueryUnit)
209 }
210 SyntaxKind::LOAD
211 | SyntaxKind::CLEAR
212 | SyntaxKind::DROP
213 | SyntaxKind::CREATE
214 | SyntaxKind::ADD
215 | SyntaxKind::MOVE
216 | SyntaxKind::COPY
217 | SyntaxKind::INSERT
218 | SyntaxKind::INSERT_DATA
219 | SyntaxKind::DELETE
220 | SyntaxKind::DELETE_DATA
221 | SyntaxKind::DELETE_WHERE => Some(TopEntryPoint::UpdateUnit),
222 _ => None,
223 })
224}
225
226#[cfg(test)]
227mod tests;