1use std::collections::{BTreeMap, BTreeSet, LinkedList};
12use std::iter::FromIterator;
13
14use chrono::{DateTime, Utc};
15use num::BigInt;
16use ordered_float::OrderedFloat;
17use uuid::Uuid;
18
19use crate::entities::*;
20use crate::query;
21use crate::query::FromValue;
22use crate::symbols::*;
23use crate::types::{Span, SpannedValue, ValueAndSpan};
24
25pub type ParseError = peg::error::ParseError<peg::str::LineCol>;
26
27peg::parser! {
34 grammar inner() for str {
35
36 pub rule nil() -> SpannedValue = "nil" { SpannedValue::Nil }
37 pub rule nan() -> SpannedValue = "#f" whitespace()+ "NaN" { SpannedValue::Float(OrderedFloat(f64::NAN)) }
38
39 pub rule infinity() -> SpannedValue = "#f" whitespace()+ s:$(sign()) "Infinity"
40 { SpannedValue::Float(OrderedFloat(if s == "+" { f64::INFINITY } else { f64::NEG_INFINITY })) }
41
42 pub rule boolean() -> SpannedValue
43 = "true" { SpannedValue::Boolean(true) }
44 / "false" { SpannedValue::Boolean(false) }
45
46 rule digit() = ['0'..='9']
47 rule alphanumeric() = ['0'..='9' | 'a'..='z' | 'A'..='Z']
48 rule octaldigit() = ['0'..='7']
49 rule validbase() = ['3'] ['0'..='6'] / ['1' | '2'] ['0'..='9'] / ['2'..='9']
50 rule hex() = ['0'..='9' | 'a'..='f' | 'A'..='F']
51 rule sign() = ['+' | '-']
52
53 pub rule raw_bigint() -> BigInt = b:$( sign()? digit()+ ) "N"
54 { b.parse::<BigInt>().unwrap() }
55 pub rule raw_octalinteger() -> i64 = "0" i:$( octaldigit()+ )
56 { i64::from_str_radix(i, 8).unwrap() }
57 pub rule raw_hexinteger() -> i64 = "0x" i:$( hex()+ )
58 { i64::from_str_radix(i, 16).unwrap() }
59 pub rule raw_basedinteger() -> i64 = b:$( validbase() ) "r" i:$( alphanumeric()+ )
60 { i64::from_str_radix(i, b.parse::<u32>().unwrap()).unwrap() }
61 pub rule raw_integer() -> i64 = i:$( sign()? digit()+ ) !("." / (['e' | 'E']))
62 { i.parse::<i64>().unwrap() }
63 pub rule raw_float() -> OrderedFloat<f64> = f:$(sign()? digit()+ ("." digit()+)? (['e' | 'E'] sign()? digit()+)?)
64 { OrderedFloat(f.parse::<f64>().unwrap()) }
65
66 pub rule bigint() -> SpannedValue = v:raw_bigint() { SpannedValue::BigInteger(v) }
67 pub rule octalinteger() -> SpannedValue = v:raw_octalinteger() { SpannedValue::Integer(v) }
68 pub rule hexinteger() -> SpannedValue = v:raw_hexinteger() { SpannedValue::Integer(v) }
69 pub rule basedinteger() -> SpannedValue = v:raw_basedinteger() { SpannedValue::Integer(v) }
70 pub rule integer() -> SpannedValue = v:raw_integer() { SpannedValue::Integer(v) }
71 pub rule float() -> SpannedValue = v:raw_float() { SpannedValue::Float(v) }
72
73 rule number() -> SpannedValue = ( bigint() / basedinteger() / hexinteger() / octalinteger() / integer() / float() )
74
75 rule string_special_char() -> &'input str = "\\" s:$(['\\' | '"' | 'n' | 't' | 'r']) { s }
78 rule string_normal_chars() -> &'input str = $([^ '"' | '\\']+)
79
80 pub rule raw_text() -> String = "\"" t:((string_special_char() / string_normal_chars())*) "\""
84 { t.join("").to_string() }
85
86 pub rule text() -> SpannedValue
87 = v:raw_text() { SpannedValue::Text(v) }
88
89 rule inst_string() -> DateTime<Utc> =
93 "#inst" whitespace()+ "\"" d:$(
94 ['0'..='9']*<4> "-" ['0'..='2'] ['0'..='9'] "-" ['0'..='3'] ['0'..='9']
95 "T"
96 ['0'..='2'] ['0'..='9'] ":" ['0'..='5'] ['0'..='9'] ":" ['0'..='6'] ['0'..='9']
97 ("." ['0'..='9']+)?
98 ("Z" / (("+" / "-") ['0'..='2'] ['0'..='9'] ":" ['0'..='5'] ['0'..='9']))
99 )
100 "\"" {?
101 DateTime::parse_from_rfc3339(d)
102 .map(|t| t.with_timezone(&Utc))
103 .map_err(|_| "invalid datetime")
104 }
105
106 rule inst_micros() -> DateTime<Utc> =
107 "#instmicros" whitespace()+ d:$( digit()+ ) {
108 let micros = d.parse::<i64>().unwrap();
109 let seconds: i64 = micros / 1000000;
110 let nanos: u32 = ((micros % 1000000).unsigned_abs() as u32) * 1000;
111 DateTime::from_timestamp(seconds, nanos).unwrap()
112 }
113
114 rule inst_millis() -> DateTime<Utc> =
115 "#instmillis" whitespace()+ d:$( digit()+ ) {
116 let millis = d.parse::<i64>().unwrap();
117 let seconds: i64 = millis / 1000;
118 let nanos: u32 = ((millis % 1000).unsigned_abs() as u32) * 1000000;
119 DateTime::from_timestamp(seconds, nanos).unwrap()
120 }
121
122 rule inst() -> SpannedValue = t:(inst_millis() / inst_micros() / inst_string())
123 { SpannedValue::Instant(t) }
124
125 rule uuid_string() -> Uuid =
126 "\"" u:$( ['a'..='f' | '0'..='9']*<8> "-" ['a'..='f' | '0'..='9']*<4> "-" ['a'..='f' | '0'..='9']*<4> "-" ['a'..='f' | '0'..='9']*<4> "-" ['a'..='f' | '0'..='9']*<12> ) "\"" {
127 Uuid::parse_str(u).expect("this is a valid UUID string")
128 }
129
130 pub rule uuid() -> SpannedValue = "#uuid" whitespace()+ u:uuid_string()
131 { SpannedValue::Uuid(u) }
132
133 rule namespace_divider() = "."
134 rule namespace_separator() = "/"
135
136 rule symbol_char_initial() = ['a'..='z' | 'A'..='Z' | '0'..='9' | '*' | '!' | '_' | '?' | '$' | '%' | '&' | '=' | '<' | '>']
140 rule symbol_char_subsequent() = ['+' | 'a'..='z' | 'A'..='Z' | '0'..='9' | '*' | '!' | '_' | '?' | '$' | '%' | '&' | '=' | '<' | '>' | '-']
141
142 rule symbol_namespace() = symbol_char_initial() symbol_char_subsequent()* (namespace_divider() symbol_char_subsequent()+)*
143 rule symbol_name() = ( symbol_char_initial()+ symbol_char_subsequent()* )
144 rule plain_symbol_name() = symbol_name() / "..." / "."
145
146 rule keyword_prefix() = ":"
147
148 pub rule symbol() -> SpannedValue =
149 ns:( sns:$(symbol_namespace()) namespace_separator() { sns })?
150 n:$(plain_symbol_name())
151 { SpannedValue::from_symbol(ns, n) }
152 / expected!("symbol")
153
154 pub rule keyword() -> SpannedValue =
155 keyword_prefix()
156 ns:( sns:$(symbol_namespace()) namespace_separator() { sns })?
157 n:$(symbol_name())
158 { SpannedValue::from_keyword(ns, n) }
159 / expected!("keyword")
160
161 pub rule list() -> SpannedValue = "(" __() v:(value())* __() ")"
162 { SpannedValue::List(LinkedList::from_iter(v)) }
163
164 pub rule vector() -> SpannedValue = "[" __() v:(value())* __() "]"
165 { SpannedValue::Vector(v) }
166
167 pub rule set() -> SpannedValue = "#{" __() v:(value())* __() "}"
168 { SpannedValue::Set(BTreeSet::from_iter(v)) }
169
170 rule pair() -> (ValueAndSpan, ValueAndSpan) =
171 k:(value()) v:(value()) {
172 (k, v)
173 }
174
175 pub rule map() -> SpannedValue = "{" __() v:(pair())* __() "}"
176 { SpannedValue::Map(BTreeMap::from_iter(v)) }
177
178 pub rule value() -> ValueAndSpan =
181 __() start:position!() v:(nil() / nan() / infinity() / boolean() / number() / inst() / uuid() / text() / keyword() / symbol() / list() / vector() / map() / set()) end:position!() __() {
182 ValueAndSpan {
183 inner: v,
184 span: Span::new(start, end)
185 }
186 }
187 / expected!("value")
188
189 rule atom() -> ValueAndSpan
190 = v:value() {? if v.is_atom() { Ok(v) } else { Err("expected atom") } }
191
192 rule whitespace() = quiet!{[' ' | '\r' | '\n' | '\t' | ',']}
195 rule comment() = quiet!{";" [^ '\r' | '\n']* ['\r' | '\n']?}
196
197 rule __() = (whitespace() / comment())*
198
199 pub rule op() -> OpType
202 = ":db/add" { OpType::Add }
203 / ":db/retract" { OpType::Retract }
204
205 rule raw_keyword() -> Keyword =
206 keyword_prefix()
207 ns:( sns:$(symbol_namespace()) namespace_separator() { sns })?
208 n:$(symbol_name()) {
209 match ns {
210 Some(ns) => Keyword::namespaced(ns, n),
211 None => Keyword::plain(n),
212 }
213 }
214 / expected!("keyword")
215
216 rule raw_forward_keyword() -> Keyword
217 = v:raw_keyword() {? if v.is_forward() { Ok(v) } else { Err("expected :forward or :forward/keyword") } }
218
219 rule raw_backward_keyword() -> Keyword
220 = v:raw_keyword() {? if v.is_backward() { Ok(v) } else { Err("expected :_backword or :backward/_keyword") } }
221
222 rule raw_namespaced_keyword() -> Keyword
223 = keyword_prefix() ns:$(symbol_namespace()) namespace_separator() n:$(symbol_name()) { Keyword::namespaced(ns, n) }
224 / expected!("namespaced keyword")
225
226 rule raw_forward_namespaced_keyword() -> Keyword
227 = v:raw_namespaced_keyword() {? if v.is_forward() { Ok(v) } else { Err("expected namespaced :forward/keyword") } }
228
229 rule raw_backward_namespaced_keyword() -> Keyword
230 = v:raw_namespaced_keyword() {? if v.is_backward() { Ok(v) } else { Err("expected namespaced :backward/_keyword") } }
231
232 rule entid() -> EntidOrIdent
233 = v:( raw_basedinteger() / raw_hexinteger() / raw_octalinteger() / raw_integer() ) { EntidOrIdent::Entid(v) }
234 / v:raw_namespaced_keyword() { EntidOrIdent::Ident(v) }
235 / expected!("entid")
236
237 rule forward_entid() -> EntidOrIdent
238 = v:( raw_basedinteger() / raw_hexinteger() / raw_octalinteger() / raw_integer() ) { EntidOrIdent::Entid(v) }
239 / v:raw_forward_namespaced_keyword() { EntidOrIdent::Ident(v) }
240 / expected!("forward entid")
241
242 rule backward_entid() -> EntidOrIdent
243 = v:raw_backward_namespaced_keyword() { EntidOrIdent::Ident(v.to_reversed()) }
244 / expected!("backward entid")
245
246 rule lookup_ref() -> LookupRef<ValueAndSpan>
247 = "(" __() "lookup-ref" __() a:(entid()) __() v:(value()) __() ")" { LookupRef { a: AttributePlace::Entid(a), v } }
248 / expected!("lookup-ref")
249
250 rule tx_function() -> TxFunction
251 = "(" __() n:$(symbol_name()) __() ")" { TxFunction { op: PlainSymbol::plain(n) } }
252
253 rule entity_place() -> EntityPlace<ValueAndSpan>
254 = v:raw_text() { EntityPlace::TempId(TempId::External(v).into()) }
255 / v:entid() { EntityPlace::Entid(v) }
256 / v:lookup_ref() { EntityPlace::LookupRef(v) }
257 / v:tx_function() { EntityPlace::TxFunction(v) }
258
259 rule value_place_pair() -> (EntidOrIdent, ValuePlace<ValueAndSpan>)
260 = k:(entid()) __() v:(value_place()) { (k, v) }
261
262 rule map_notation() -> MapNotation<ValueAndSpan>
263 = "{" __() kvs:(value_place_pair()*) __() "}" { kvs.into_iter().collect() }
264
265 rule value_place() -> ValuePlace<ValueAndSpan>
266 = __() v:lookup_ref() __() { ValuePlace::LookupRef(v) }
267 / __() v:tx_function() __() { ValuePlace::TxFunction(v) }
268 / __() "[" __() vs:(value_place()*) __() "]" __() { ValuePlace::Vector(vs) }
269 / __() v:map_notation() __() { ValuePlace::MapNotation(v) }
270 / __() v:atom() __() { ValuePlace::Atom(v) }
271
272 pub rule entity() -> Entity<ValueAndSpan>
273 = __() "[" __() op:(op()) __() e:(entity_place()) __() a:(forward_entid()) __() v:(value_place()) __() "]" __() { Entity::AddOrRetract { op, e, a: AttributePlace::Entid(a), v } }
274 / __() "[" __() op:(op()) __() e:(value_place()) __() a:(backward_entid()) __() v:(entity_place()) __() "]" __() { Entity::AddOrRetract { op, e: v, a: AttributePlace::Entid(a), v: e } }
275 / __() map:map_notation() __() { Entity::MapNotation(map) }
276 / expected!("entity")
277
278 pub rule entities() -> Vec<Entity<ValueAndSpan>>
279 = __() "[" __() es:(entity()*) __() "]" __() { es }
280
281 rule query_function() -> query::QueryFunction
294 = __() n:$(symbol_name() / "/" / "+" / "-") __() {? query::QueryFunction::from_symbol(&PlainSymbol::plain(n)).ok_or("expected query function") }
295
296 rule sexpr() -> query::FnArg
297 = __() "(" func:query_function() args:fn_arg()* ")" __() { query::FnArg::SExpr(func.0, args) }
298
299 rule fn_arg() -> query::FnArg
300 = sexpr()
301 / v:value() {? query::FnArg::from_value(&v).ok_or("expected query function argument") }
302
303 rule find_elem() -> query::Element
304 = __() v:variable() __() { query::Element::Variable(v) }
305 / __() "(" __() "the" v:variable() ")" __() { query::Element::Corresponding(v) }
306 / __() "(" __() "pull" var:variable() "[" patterns:pull_attribute()+ "]" __() ")" __() { query::Element::Pull(query::Pull { var, patterns }) }
307 / __() "(" func:query_function() args:fn_arg()* ")" __() { query::Element::Aggregate(query::Aggregate { func, args }) }
308
309 rule find_spec() -> query::FindSpec
310 = f:find_elem() "." __() { query::FindSpec::FindScalar(f) }
311 / fs:find_elem()+ { query::FindSpec::FindRel(fs) }
312 / __() "[" f:find_elem() __() "..." __() "]" __() { query::FindSpec::FindColl(f) }
313 / __() "[" fs:find_elem()+ "]" __() { query::FindSpec::FindTuple(fs) }
314
315 rule pull_attribute() -> query::PullAttributeSpec
316 = __() "*" __() { query::PullAttributeSpec::Wildcard }
317 / __() k:raw_forward_namespaced_keyword() __() alias:(":as" __() alias:raw_forward_keyword() __() { alias })? {
318 let attribute = query::PullConcreteAttribute::Ident(::std::sync::Arc::new(k));
319 let alias = alias.map(::std::sync::Arc::new);
320 query::PullAttributeSpec::Attribute(
321 query::NamedPullAttribute {
322 attribute,
323 alias,
324 })
325 }
326
327 rule limit() -> query::Limit
328 = __() v:variable() __() { query::Limit::Variable(v) }
329 / __() n:(raw_octalinteger() / raw_hexinteger() / raw_basedinteger() / raw_integer()) __() {?
330 if n > 0 {
331 Ok(query::Limit::Fixed(n as u64))
332 } else {
333 Err("expected positive integer")
334 }
335 }
336
337 rule order() -> query::Order
338 = __() "[" v:variable() __() ":desc" __() "]" __() { query::Order(query::Direction::Descending, v) }
339 / __() "[" v:variable() __() ":asc" __() "]" __() { query::Order(query::Direction::Ascending, v) }
340 / __() "[" v:variable() __() "]" __() { query::Order(query::Direction::Ascending, v) }
341
342
343 rule pattern_value_place() -> query::PatternValuePlace
344 = v:value() {? query::PatternValuePlace::from_value(&v).ok_or("expected pattern_value_place") }
345
346 rule pattern_non_value_place() -> query::PatternNonValuePlace
347 = v:value() {? query::PatternNonValuePlace::from_value(&v).ok_or("expected pattern_non_value_place") }
348
349 rule pattern() -> query::WhereClause
350 = __() "["
351 src:src_var()?
352 e:pattern_non_value_place()
353 a:pattern_non_value_place()
354 v:pattern_value_place()?
355 tx:pattern_non_value_place()?
356 "]" __()
357 {?
358 let v = v.unwrap_or(query::PatternValuePlace::Placeholder);
359 let tx = tx.unwrap_or(query::PatternNonValuePlace::Placeholder);
360
361 query::Pattern::new(src, e, a, v, tx)
365 .map(query::WhereClause::Pattern)
366 .ok_or("expected pattern")
367 }
368
369 rule rule_vars() -> BTreeSet<query::Variable>
371 = vs:variable()+ {?
372 let given = vs.len();
373 let set: BTreeSet<query::Variable> = vs.into_iter().collect();
374 if given != set.len() {
375 Err("expected unique variables")
376 } else {
377 Ok(set)
378 }
379 }
380
381 rule or_pattern_clause() -> query::OrWhereClause
382 = clause:where_clause() { query::OrWhereClause::Clause(clause) }
383
384 rule or_and_clause() -> query::OrWhereClause
385 = __() "(" __() "and" clauses:where_clause()+ ")" __() { query::OrWhereClause::And(clauses) }
386
387 rule or_where_clause() -> query::OrWhereClause
388 = or_pattern_clause()
389 / or_and_clause()
390
391 rule or_clause() -> query::WhereClause
392 = __() "(" __() "or" clauses:or_where_clause()+ ")" __() {
393 query::WhereClause::OrJoin(query::OrJoin::new(query::UnifyVars::Implicit, clauses))
394 }
395
396 rule or_join_clause() -> query::WhereClause
397 = __() "(" __() "or-join" __() "[" vars:rule_vars() "]" clauses:or_where_clause()+ ")" __() {
398 query::WhereClause::OrJoin(query::OrJoin::new(query::UnifyVars::Explicit(vars), clauses))
399 }
400
401 rule not_clause() -> query::WhereClause
402 = __() "(" __() "not" clauses:where_clause()+ ")" __() {
403 query::WhereClause::NotJoin(query::NotJoin::new(query::UnifyVars::Implicit, clauses))
404 }
405
406 rule not_join_clause() -> query::WhereClause
407 = __() "(" __() "not-join" __() "[" vars:rule_vars() "]" clauses:where_clause()+ ")" __() {
408 query::WhereClause::NotJoin(query::NotJoin::new(query::UnifyVars::Explicit(vars), clauses))
409 }
410
411 rule type_annotation() -> query::WhereClause
412 = __() "[" __() "(" __() "type" var:variable() __() ty:raw_keyword() __() ")" __() "]" __() {
413 query::WhereClause::TypeAnnotation(
414 query::TypeAnnotation {
415 value_type: ty,
416 variable: var,
417 })
418 }
419
420 rule pred() -> query::WhereClause
421 = __() "[" __() expr:sexpr() __() "]" __() {
422 query::WhereClause::Pred(
423 query::Predicate {
424 expr,
425 })
426 }
427
428 pub rule where_fn() -> query::WhereClause
429 = __() "[" __() expr:sexpr() __() binding:binding() "]" __() {
430 query::WhereClause::WhereFn(
431 query::WhereFn {
432 expr,
433 binding,
434 })
435 }
436
437 rule where_clause() -> query::WhereClause
438 = pattern()
440 / or_join_clause()
441 / or_clause()
442 / not_join_clause()
443 / not_clause()
444 / type_annotation()
445 / pred()
446 / where_fn()
447
448 rule query_part() -> query::QueryPart
449 = __() ":find" fs:find_spec() { query::QueryPart::FindSpec(fs) }
450 / __() ":in" bs:binding()* { query::QueryPart::InBindings(bs) }
451 / __() ":limit" l:limit() { query::QueryPart::Limit(l) }
452 / __() ":order" os:order()+ { query::QueryPart::Order(os) }
453 / __() ":where" ws:where_clause()+ { query::QueryPart::WhereClauses(ws) }
454 / __() ":with" with_vars:variable()+ { query::QueryPart::WithVars(with_vars) }
455
456 rule map_query_part() -> query::QueryPart
457 = __() ":find" __() "[" fs:find_spec() "]" __() { query::QueryPart::FindSpec(fs) }
458 / __() ":in" __() "[" __() bs:binding()* "]" __() { query::QueryPart::InBindings(bs) }
459 / __() ":where" __() "[" ws:where_clause()+ "]" __() { query::QueryPart::WhereClauses(ws) }
460 / __() ":order" __() "[" os:order()+ "]" __() { query::QueryPart::Order(os) }
461 / __() ":limit" l:limit() { query::QueryPart::Limit(l) }
462
463 pub rule parse_query() -> query::ParsedQuery
464 = __() "[" qps:query_part()+ "]" __() {? query::ParsedQuery::from_parts(qps) }
465 / __() "{" qps:map_query_part()+ "}" __() {? query::ParsedQuery::from_parts(qps) }
466
467 rule variable() -> query::Variable
468 = v:value() {? query::Variable::from_value(&v).ok_or("expected variable") }
469
470 rule src_var() -> query::SrcVar
471 = v:value() {? query::SrcVar::from_value(&v).ok_or("expected src_var") }
472
473 rule variable_or_placeholder() -> query::VariableOrPlaceholder
474 = v:variable() { query::VariableOrPlaceholder::Variable(v) }
475 / __() "_" __() { query::VariableOrPlaceholder::Placeholder }
476
477 rule binding() -> query::Binding
478 = __() "[" __() "[" vs:variable_or_placeholder()+ "]" __() "]" __() { query::Binding::BindRel(vs) }
479 / __() "[" v:variable() "..." __() "]" __() { query::Binding::BindColl(v) }
480 / __() "[" vs:variable_or_placeholder()+ "]" __() { query::Binding::BindTuple(vs) }
481 / v:variable() { query::Binding::BindScalar(v) }
482 }
483}
484
485pub use inner::*;