1#![allow(clippy::ignored_unit_patterns)]
2
3use crate::algebra::*;
4use crate::query::*;
5use crate::term::*;
6use crate::update::*;
7use oxilangtag::LanguageTag;
8use oxiri::{Iri, IriParseError};
9use oxrdf::vocab::{rdf, xsd};
10use peg::parser;
11use peg::str::LineCol;
12use rand::random;
13#[cfg(feature = "standard-unicode-escaping")]
14use std::borrow::Cow;
15use std::char;
16use std::collections::{HashMap, HashSet};
17use std::mem::take;
18#[cfg(feature = "standard-unicode-escaping")]
19use std::str::Chars;
20use std::str::FromStr;
21
22#[must_use]
33#[derive(Clone, Default)]
34pub struct SparqlParser {
35 base_iri: Option<Iri<String>>,
36 prefixes: HashMap<String, String>,
37 custom_aggregate_functions: HashSet<NamedNode>,
38}
39
40impl SparqlParser {
41 #[inline]
42 pub fn new() -> Self {
43 Self::default()
44 }
45
46 #[inline]
56 pub fn with_base_iri(mut self, base_iri: impl Into<String>) -> Result<Self, IriParseError> {
57 self.base_iri = Some(Iri::parse(base_iri.into())?);
58 Ok(self)
59 }
60
61 #[inline]
76 pub fn with_prefix(
77 mut self,
78 prefix_name: impl Into<String>,
79 prefix_iri: impl Into<String>,
80 ) -> Result<Self, IriParseError> {
81 self.prefixes.insert(
82 prefix_name.into(),
83 Iri::parse(prefix_iri.into())?.into_inner(),
84 );
85 Ok(self)
86 }
87
88 #[inline]
102 pub fn with_custom_aggregate_function(mut self, name: impl Into<NamedNode>) -> Self {
103 self.custom_aggregate_functions.insert(name.into());
104 self
105 }
106
107 #[cfg_attr(
118 not(feature = "standard-unicode-escaping"),
119 expect(clippy::needless_borrow)
120 )]
121 pub fn parse_query(self, query: &str) -> Result<Query, SparqlSyntaxError> {
122 let mut state = ParserState::new(
123 self.base_iri,
124 self.prefixes,
125 self.custom_aggregate_functions,
126 );
127 #[cfg(feature = "standard-unicode-escaping")]
128 let query = unescape_unicode_codepoints(query);
129 Ok(parser::QueryUnit(&query, &mut state).map_err(SparqlSyntaxErrorKind::Syntax)?)
130 }
131
132 #[cfg_attr(
143 not(feature = "standard-unicode-escaping"),
144 expect(clippy::needless_borrow)
145 )]
146 pub fn parse_update(self, update: &str) -> Result<Update, SparqlSyntaxError> {
147 let mut state = ParserState::new(
148 self.base_iri,
149 self.prefixes,
150 self.custom_aggregate_functions,
151 );
152 #[cfg(feature = "standard-unicode-escaping")]
153 let update = unescape_unicode_codepoints(update);
154 let operations =
155 parser::UpdateInit(&update, &mut state).map_err(SparqlSyntaxErrorKind::Syntax)?;
156 check_if_insert_data_are_sharing_blank_nodes(&operations)?;
157 Ok(Update {
158 operations,
159 base_iri: state.base_iri,
160 })
161 }
162}
163
164#[derive(Debug, thiserror::Error)]
166#[error(transparent)]
167pub struct SparqlSyntaxError {
168 #[from]
169 kind: SparqlSyntaxErrorKind,
170}
171
172impl SparqlSyntaxError {
173 pub(crate) fn from_bad_base_iri(e: IriParseError) -> Self {
174 SparqlSyntaxErrorKind::InvalidBaseIri(e).into()
175 }
176}
177
178#[derive(Debug, thiserror::Error)]
179enum SparqlSyntaxErrorKind {
180 #[error("Invalid SPARQL base IRI provided: {0}")]
181 InvalidBaseIri(#[from] IriParseError),
182 #[error(transparent)]
183 Syntax(#[from] peg::error::ParseError<LineCol>),
184 #[error("The blank node {0} cannot be shared by multiple blocks")]
185 SharedBlankNode(BlankNode),
186}
187
188#[cfg(feature = "standard-unicode-escaping")]
189fn unescape_unicode_codepoints(input: &str) -> Cow<'_, str> {
190 if needs_unescape_unicode_codepoints(input) {
191 UnescapeUnicodeCharIterator::new(input).collect()
192 } else {
193 input.into()
194 }
195}
196
197#[cfg(feature = "standard-unicode-escaping")]
198fn needs_unescape_unicode_codepoints(input: &str) -> bool {
199 let bytes = input.as_bytes();
200 for i in 1..bytes.len() {
201 if (bytes[i] == b'u' || bytes[i] == b'U') && bytes[i - 1] == b'\\' {
202 return true;
203 }
204 }
205 false
206}
207
208#[cfg(feature = "standard-unicode-escaping")]
209struct UnescapeUnicodeCharIterator<'a> {
210 iter: Chars<'a>,
211 buffer: String,
212}
213
214#[cfg(feature = "standard-unicode-escaping")]
215impl<'a> UnescapeUnicodeCharIterator<'a> {
216 fn new(string: &'a str) -> Self {
217 Self {
218 iter: string.chars(),
219 buffer: String::with_capacity(9),
220 }
221 }
222}
223
224#[cfg(feature = "standard-unicode-escaping")]
225impl Iterator for UnescapeUnicodeCharIterator<'_> {
226 type Item = char;
227
228 fn next(&mut self) -> Option<char> {
229 let c = if self.buffer.is_empty() {
230 self.iter.next()?
231 } else {
232 self.buffer.remove(0)
233 };
234 match c {
235 '\\' => match self.iter.next() {
236 Some('u') => {
237 self.buffer.push('u');
238 for _ in 0..4 {
239 if let Some(c) = self.iter.next() {
240 self.buffer.push(c);
241 } else {
242 return Some('\\');
243 }
244 }
245 if let Some(c) = u32::from_str_radix(&self.buffer[1..], 16)
246 .ok()
247 .and_then(char::from_u32)
248 {
249 self.buffer.clear();
250 Some(c)
251 } else {
252 Some('\\')
253 }
254 }
255 Some('U') => {
256 self.buffer.push('U');
257 for _ in 0..8 {
258 if let Some(c) = self.iter.next() {
259 self.buffer.push(c);
260 } else {
261 return Some('\\');
262 }
263 }
264 if let Some(c) = u32::from_str_radix(&self.buffer[1..], 16)
265 .ok()
266 .and_then(char::from_u32)
267 {
268 self.buffer.clear();
269 Some(c)
270 } else {
271 Some('\\')
272 }
273 }
274 Some(c) => {
275 self.buffer.push(c);
276 Some('\\')
277 }
278 None => Some('\\'),
279 },
280 _ => Some(c),
281 }
282 }
283}
284
285struct ReifiedTerm {
286 term: TermPattern,
287 reifiers: Vec<TermPattern>,
288}
289
290#[derive(Default)]
291struct FocusedTriplePattern<F> {
292 focus: F,
293 patterns: Vec<TriplePattern>,
294}
295
296impl<F> FocusedTriplePattern<F> {
297 fn new(focus: impl Into<F>) -> Self {
298 Self {
299 focus: focus.into(),
300 patterns: Vec::new(),
301 }
302 }
303}
304
305impl<F> From<FocusedTriplePattern<F>> for FocusedTriplePattern<Vec<F>> {
306 fn from(input: FocusedTriplePattern<F>) -> Self {
307 Self {
308 focus: vec![input.focus],
309 patterns: input.patterns,
310 }
311 }
312}
313
314#[derive(Clone, Debug)]
315enum VariableOrPropertyPath {
316 Variable(Variable),
317 PropertyPath(PropertyPathExpression),
318}
319
320impl From<Variable> for VariableOrPropertyPath {
321 fn from(var: Variable) -> Self {
322 Self::Variable(var)
323 }
324}
325
326impl From<NamedNodePattern> for VariableOrPropertyPath {
327 fn from(pattern: NamedNodePattern) -> Self {
328 match pattern {
329 NamedNodePattern::NamedNode(node) => PropertyPathExpression::from(node).into(),
330 NamedNodePattern::Variable(v) => v.into(),
331 }
332 }
333}
334
335impl From<PropertyPathExpression> for VariableOrPropertyPath {
336 fn from(path: PropertyPathExpression) -> Self {
337 Self::PropertyPath(path)
338 }
339}
340
341#[cfg_attr(feature = "sparql-12", expect(clippy::unnecessary_wraps))]
342fn add_to_triple_patterns(
343 subject: TermPattern,
344 predicate: NamedNodePattern,
345 object: ReifiedTerm,
346 patterns: &mut Vec<TriplePattern>,
347) -> Result<(), &'static str> {
348 let triple = TriplePattern::new(subject, predicate, object.term);
349 #[cfg(feature = "sparql-12")]
350 for reifier in object.reifiers {
351 patterns.push(TriplePattern {
352 subject: reifier.clone(),
353 predicate: rdf::REIFIES.into_owned().into(),
354 object: triple.clone().into(),
355 });
356 }
357 #[cfg(not(feature = "sparql-12"))]
358 if !object.reifiers.is_empty() {
359 return Err("Triple terms are only available in SPARQL 1.2");
360 }
361 patterns.push(triple);
362 Ok(())
363}
364
365fn add_to_triple_or_path_patterns(
366 subject: TermPattern,
367 predicate: impl Into<VariableOrPropertyPath>,
368 object: ReifiedTerm,
369 patterns: &mut Vec<TripleOrPathPattern>,
370) -> Result<(), &'static str> {
371 match predicate.into() {
372 VariableOrPropertyPath::Variable(p) => {
373 add_triple_to_triple_or_path_patterns(subject, p, object, patterns)?;
374 }
375 VariableOrPropertyPath::PropertyPath(p) => match p {
376 PropertyPathExpression::NamedNode(p) => {
377 add_triple_to_triple_or_path_patterns(subject, p, object, patterns)?;
378 }
379 PropertyPathExpression::Reverse(p) => add_to_triple_or_path_patterns(
380 object.term,
381 *p,
382 ReifiedTerm {
383 term: subject,
384 reifiers: object.reifiers,
385 },
386 patterns,
387 )?,
388 PropertyPathExpression::Sequence(a, b) => {
389 if !object.reifiers.is_empty() {
390 return Err("Reifiers are not allowed on property paths");
391 }
392 let middle = BlankNode::default();
393 add_to_triple_or_path_patterns(
394 subject,
395 *a,
396 ReifiedTerm {
397 term: middle.clone().into(),
398 reifiers: Vec::new(),
399 },
400 patterns,
401 )?;
402 add_to_triple_or_path_patterns(
403 middle.into(),
404 *b,
405 ReifiedTerm {
406 term: object.term,
407 reifiers: Vec::new(),
408 },
409 patterns,
410 )?;
411 }
412 path => {
413 if !object.reifiers.is_empty() {
414 return Err("Reifiers are not allowed on property paths");
415 }
416 patterns.push(TripleOrPathPattern::Path {
417 subject,
418 path,
419 object: object.term,
420 })
421 }
422 },
423 }
424 Ok(())
425}
426
427#[cfg_attr(feature = "sparql-12", expect(clippy::unnecessary_wraps))]
428fn add_triple_to_triple_or_path_patterns(
429 subject: TermPattern,
430 predicate: impl Into<NamedNodePattern>,
431 object: ReifiedTerm,
432 patterns: &mut Vec<TripleOrPathPattern>,
433) -> Result<(), &'static str> {
434 let triple = TriplePattern::new(subject, predicate, object.term);
435 #[cfg(feature = "sparql-12")]
436 for reifier in object.reifiers {
437 patterns.push(
438 TriplePattern {
439 subject: reifier.clone(),
440 predicate: rdf::REIFIES.into_owned().into(),
441 object: triple.clone().into(),
442 }
443 .into(),
444 );
445 }
446 #[cfg(not(feature = "sparql-12"))]
447 if !object.reifiers.is_empty() {
448 return Err("Triple terms are only available in SPARQL 1.2");
449 }
450 patterns.push(triple.into());
451 Ok(())
452}
453
454fn build_bgp(patterns: Vec<TripleOrPathPattern>) -> GraphPattern {
455 let mut bgp = Vec::new();
456 let mut elements = Vec::with_capacity(patterns.len());
457 for pattern in patterns {
458 match pattern {
459 TripleOrPathPattern::Triple(t) => bgp.push(t),
460 TripleOrPathPattern::Path {
461 subject,
462 path,
463 object,
464 } => {
465 if !bgp.is_empty() {
466 elements.push(GraphPattern::Bgp {
467 patterns: take(&mut bgp),
468 });
469 }
470 elements.push(GraphPattern::Path {
471 subject,
472 path,
473 object,
474 })
475 }
476 }
477 }
478 if !bgp.is_empty() {
479 elements.push(GraphPattern::Bgp { patterns: bgp });
480 }
481 elements.into_iter().reduce(new_join).unwrap_or_default()
482}
483
484#[derive(Debug)]
485enum TripleOrPathPattern {
486 Triple(TriplePattern),
487 Path {
488 subject: TermPattern,
489 path: PropertyPathExpression,
490 object: TermPattern,
491 },
492}
493
494impl From<TriplePattern> for TripleOrPathPattern {
495 fn from(tp: TriplePattern) -> Self {
496 Self::Triple(tp)
497 }
498}
499
500#[derive(Debug, Default)]
501struct FocusedTripleOrPathPattern<F> {
502 focus: F,
503 patterns: Vec<TripleOrPathPattern>,
504}
505
506impl<F> FocusedTripleOrPathPattern<F> {
507 fn new(focus: impl Into<F>) -> Self {
508 Self {
509 focus: focus.into(),
510 patterns: Vec::new(),
511 }
512 }
513}
514
515impl<F> From<FocusedTripleOrPathPattern<F>> for FocusedTripleOrPathPattern<Vec<F>> {
516 fn from(input: FocusedTripleOrPathPattern<F>) -> Self {
517 Self {
518 focus: vec![input.focus],
519 patterns: input.patterns,
520 }
521 }
522}
523
524impl<F, T: From<F>> From<FocusedTriplePattern<F>> for FocusedTripleOrPathPattern<T> {
525 fn from(input: FocusedTriplePattern<F>) -> Self {
526 Self {
527 focus: input.focus.into(),
528 patterns: input.patterns.into_iter().map(Into::into).collect(),
529 }
530 }
531}
532
533#[derive(Eq, PartialEq, Debug, Clone, Hash)]
534enum PartialGraphPattern {
535 Optional(GraphPattern, Option<Expression>),
536 #[cfg(feature = "sep-0006")]
537 Lateral(GraphPattern),
538 Minus(GraphPattern),
539 Bind(Expression, Variable),
540 Filter(Expression),
541 Other(GraphPattern),
542}
543
544fn new_join(l: GraphPattern, r: GraphPattern) -> GraphPattern {
545 if let GraphPattern::Bgp { patterns: pl } = &l {
547 if pl.is_empty() {
548 return r;
549 }
550 }
551 if let GraphPattern::Bgp { patterns: pr } = &r {
552 if pr.is_empty() {
553 return l;
554 }
555 }
556
557 match (l, r) {
558 (GraphPattern::Bgp { patterns: mut pl }, GraphPattern::Bgp { patterns: pr }) => {
559 pl.extend(pr);
560 GraphPattern::Bgp { patterns: pl }
561 }
562 (GraphPattern::Bgp { patterns }, other) | (other, GraphPattern::Bgp { patterns })
563 if patterns.is_empty() =>
564 {
565 other
566 }
567 (l, r) => GraphPattern::Join {
568 left: Box::new(l),
569 right: Box::new(r),
570 },
571 }
572}
573
574fn not_empty_fold<T>(
575 iter: impl Iterator<Item = T>,
576 combine: impl Fn(T, T) -> T,
577) -> Result<T, &'static str> {
578 iter.fold(None, |a, b| match a {
579 Some(av) => Some(combine(av, b)),
580 None => Some(b),
581 })
582 .ok_or("The iterator should not be empty")
583}
584
585#[derive(Default)]
586enum SelectionOption {
587 Distinct,
588 Reduced,
589 #[default]
590 Default,
591}
592
593enum SelectionMember {
594 Variable(Variable),
595 Expression(Expression, Variable),
596}
597
598#[derive(Default)]
599enum SelectionVariables {
600 Explicit(Vec<SelectionMember>),
601 #[default]
602 Star,
603}
604
605#[derive(Default)]
606struct Selection {
607 pub option: SelectionOption,
608 pub variables: SelectionVariables,
609}
610
611fn build_select(
612 select: Selection,
613 r#where: GraphPattern,
614 mut group: Option<(Vec<Variable>, Vec<(Expression, Variable)>)>,
615 having: Option<Expression>,
616 order_by: Option<Vec<OrderExpression>>,
617 offset_limit: Option<(usize, Option<usize>)>,
618 values: Option<GraphPattern>,
619 state: &mut ParserState,
620) -> Result<GraphPattern, &'static str> {
621 let mut p = r#where;
622 let mut with_aggregate = false;
623
624 let aggregates = state.aggregates.pop().unwrap_or_default();
626 if group.is_none() && !aggregates.is_empty() {
627 group = Some((vec![], vec![]));
628 }
629
630 if let Some((clauses, binds)) = group {
631 for (expression, variable) in binds {
632 p = GraphPattern::Extend {
633 inner: Box::new(p),
634 variable,
635 expression,
636 };
637 }
638 p = GraphPattern::Group {
639 inner: Box::new(p),
640 variables: clauses,
641 aggregates,
642 };
643 with_aggregate = true;
644 }
645
646 if let Some(expr) = having {
648 p = GraphPattern::Filter {
649 expr,
650 inner: Box::new(p),
651 };
652 }
653
654 if let Some(data) = values {
656 p = new_join(p, data);
657 }
658
659 let mut pv = Vec::new();
661 let with_project = match select.variables {
662 SelectionVariables::Explicit(sel_items) => {
663 let mut visible = HashSet::new();
664 p.on_in_scope_variable(|v| {
665 visible.insert(v.clone());
666 });
667 for sel_item in sel_items {
668 let v = match sel_item {
669 SelectionMember::Variable(v) => {
670 if with_aggregate && !visible.contains(&v) {
671 return Err("The SELECT contains a variable that is unbound");
673 }
674 v
675 }
676 SelectionMember::Expression(expression, variable) => {
677 if visible.contains(&variable) {
678 return Err(
680 "The SELECT overrides an existing variable using an expression",
681 );
682 }
683 if with_aggregate && !are_variables_bound(&expression, &visible) {
684 return Err(
686 "The SELECT contains an expression with a variable that is unbound",
687 );
688 }
689 p = GraphPattern::Extend {
690 inner: Box::new(p),
691 variable: variable.clone(),
692 expression,
693 };
694 variable
695 }
696 };
697 if pv.contains(&v) {
698 return Err("Duplicated variable name in SELECT");
699 }
700 pv.push(v)
701 }
702 true
703 }
704 SelectionVariables::Star => {
705 if with_aggregate {
706 return Err("SELECT * is not authorized with GROUP BY");
707 }
708 p.on_in_scope_variable(|v| {
710 if !pv.contains(v) {
711 pv.push(v.clone());
712 }
713 });
714 pv.sort();
715 true
716 }
717 };
718
719 let mut m = p;
720
721 if let Some(expression) = order_by {
723 m = GraphPattern::OrderBy {
724 inner: Box::new(m),
725 expression,
726 };
727 }
728
729 if with_project {
731 m = GraphPattern::Project {
732 inner: Box::new(m),
733 variables: pv,
734 };
735 }
736 match select.option {
737 SelectionOption::Distinct => m = GraphPattern::Distinct { inner: Box::new(m) },
738 SelectionOption::Reduced => m = GraphPattern::Reduced { inner: Box::new(m) },
739 SelectionOption::Default => (),
740 }
741
742 if let Some((start, length)) = offset_limit {
744 m = GraphPattern::Slice {
745 inner: Box::new(m),
746 start,
747 length,
748 }
749 }
750 Ok(m)
751}
752
753fn are_variables_bound(expression: &Expression, variables: &HashSet<Variable>) -> bool {
754 match expression {
755 Expression::NamedNode(_)
756 | Expression::Literal(_)
757 | Expression::Bound(_)
758 | Expression::Coalesce(_)
759 | Expression::Exists(_) => true,
760 Expression::Variable(var) => variables.contains(var),
761 Expression::UnaryPlus(e) | Expression::UnaryMinus(e) | Expression::Not(e) => {
762 are_variables_bound(e, variables)
763 }
764 Expression::Or(a, b)
765 | Expression::And(a, b)
766 | Expression::Equal(a, b)
767 | Expression::SameTerm(a, b)
768 | Expression::Greater(a, b)
769 | Expression::GreaterOrEqual(a, b)
770 | Expression::Less(a, b)
771 | Expression::LessOrEqual(a, b)
772 | Expression::Add(a, b)
773 | Expression::Subtract(a, b)
774 | Expression::Multiply(a, b)
775 | Expression::Divide(a, b) => {
776 are_variables_bound(a, variables) && are_variables_bound(b, variables)
777 }
778 Expression::In(a, b) => {
779 are_variables_bound(a, variables) && b.iter().all(|b| are_variables_bound(b, variables))
780 }
781 Expression::FunctionCall(_, parameters) => {
782 parameters.iter().all(|p| are_variables_bound(p, variables))
783 }
784 Expression::If(a, b, c) => {
785 are_variables_bound(a, variables)
786 && are_variables_bound(b, variables)
787 && are_variables_bound(c, variables)
788 }
789 }
790}
791
792#[cfg(feature = "sep-0006")]
794fn add_defined_variables<'a>(pattern: &'a GraphPattern, set: &mut HashSet<&'a Variable>) {
795 match pattern {
796 GraphPattern::Bgp { .. } | GraphPattern::Path { .. } => {}
797 GraphPattern::Join { left, right }
798 | GraphPattern::LeftJoin { left, right, .. }
799 | GraphPattern::Lateral { left, right }
800 | GraphPattern::Union { left, right }
801 | GraphPattern::Minus { left, right } => {
802 add_defined_variables(left, set);
803 add_defined_variables(right, set);
804 }
805 GraphPattern::Graph { inner, .. } => {
806 add_defined_variables(inner, set);
807 }
808 GraphPattern::Extend {
809 inner, variable, ..
810 } => {
811 set.insert(variable);
812 add_defined_variables(inner, set);
813 }
814 GraphPattern::Group {
815 variables,
816 aggregates,
817 inner,
818 } => {
819 for (v, _) in aggregates {
820 set.insert(v);
821 }
822 let mut inner_variables = HashSet::new();
823 add_defined_variables(inner, &mut inner_variables);
824 for v in inner_variables {
825 if variables.contains(v) {
826 set.insert(v);
827 }
828 }
829 }
830 GraphPattern::Values { variables, .. } => {
831 for v in variables {
832 set.insert(v);
833 }
834 }
835 GraphPattern::Project { variables, inner } => {
836 let mut inner_variables = HashSet::new();
837 add_defined_variables(inner, &mut inner_variables);
838 for v in inner_variables {
839 if variables.contains(v) {
840 set.insert(v);
841 }
842 }
843 }
844 GraphPattern::Service { inner, .. }
845 | GraphPattern::Filter { inner, .. }
846 | GraphPattern::OrderBy { inner, .. }
847 | GraphPattern::Distinct { inner }
848 | GraphPattern::Reduced { inner }
849 | GraphPattern::Slice { inner, .. } => add_defined_variables(inner, set),
850 }
851}
852
853fn copy_graph(from: impl Into<GraphName>, to: impl Into<GraphNamePattern>) -> GraphUpdateOperation {
854 let bgp = GraphPattern::Bgp {
855 patterns: vec![TriplePattern::new(
856 Variable::new_unchecked("s"),
857 Variable::new_unchecked("p"),
858 Variable::new_unchecked("o"),
859 )],
860 };
861 GraphUpdateOperation::DeleteInsert {
862 delete: Vec::new(),
863 insert: vec![QuadPattern::new(
864 Variable::new_unchecked("s"),
865 Variable::new_unchecked("p"),
866 Variable::new_unchecked("o"),
867 to,
868 )],
869 using: None,
870 pattern: Box::new(match from.into() {
871 GraphName::NamedNode(from) => GraphPattern::Graph {
872 name: from.into(),
873 inner: Box::new(bgp),
874 },
875 GraphName::DefaultGraph => bgp,
876 }),
877 }
878}
879
880fn check_if_insert_data_are_sharing_blank_nodes(
881 update: &[GraphUpdateOperation],
882) -> Result<(), SparqlSyntaxError> {
883 #[cfg(feature = "sparql-12")]
884 fn add_triple_blank_nodes<'a>(triple: &'a Triple, bnodes: &mut HashSet<&'a BlankNode>) {
885 if let NamedOrBlankNode::BlankNode(bnode) = &triple.subject {
886 bnodes.insert(bnode);
887 }
888 if let Term::BlankNode(bnode) = &triple.object {
889 bnodes.insert(bnode);
890 } else if let Term::Triple(triple) = &triple.object {
891 add_triple_blank_nodes(triple, bnodes);
892 }
893 }
894
895 if update
896 .iter()
897 .filter(|op| matches!(op, GraphUpdateOperation::InsertData { .. }))
898 .count()
899 < 2
900 {
901 return Ok(());
903 }
904
905 let mut existing_blank_nodes = HashSet::new();
906 for operation in update {
907 if let GraphUpdateOperation::InsertData { data } = operation {
908 let mut new_blank_nodes = HashSet::new();
909 for quad in data {
910 if let NamedOrBlankNode::BlankNode(bnode) = &quad.subject {
911 new_blank_nodes.insert(bnode);
912 }
913 if let Term::BlankNode(bnode) = &quad.object {
914 new_blank_nodes.insert(bnode);
915 }
916 #[cfg(feature = "sparql-12")]
917 if let Term::Triple(triple) = &quad.object {
918 add_triple_blank_nodes(triple, &mut new_blank_nodes);
919 }
920 }
921 if let Some(error) = existing_blank_nodes.intersection(&new_blank_nodes).next() {
922 return Err(SparqlSyntaxErrorKind::SharedBlankNode((**error).clone()).into());
923 }
924 existing_blank_nodes.extend(new_blank_nodes);
925 }
926 }
927 Ok(())
928}
929
930enum Either<L, R> {
931 Left(L),
932 Right(R),
933}
934
935pub struct ParserState {
936 base_iri: Option<Iri<String>>,
937 prefixes: HashMap<String, String>,
938 custom_aggregate_functions: HashSet<NamedNode>,
939 used_bnodes: HashSet<BlankNode>,
940 currently_used_bnodes: HashSet<BlankNode>,
941 aggregates: Vec<Vec<(Variable, AggregateExpression)>>,
942}
943
944impl ParserState {
945 pub(crate) fn new(
946 base_iri: Option<Iri<String>>,
947 prefixes: HashMap<String, String>,
948 custom_aggregate_functions: HashSet<NamedNode>,
949 ) -> Self {
950 Self {
951 base_iri,
952 prefixes,
953 custom_aggregate_functions,
954 used_bnodes: HashSet::new(),
955 currently_used_bnodes: HashSet::new(),
956 aggregates: Vec::new(),
957 }
958 }
959
960 fn parse_iri(&self, iri: String) -> Result<Iri<String>, IriParseError> {
961 if let Some(base_iri) = &self.base_iri {
962 base_iri.resolve(&iri)
963 } else {
964 Iri::parse(iri)
965 }
966 }
967
968 fn new_aggregation(&mut self, agg: AggregateExpression) -> Result<Variable, &'static str> {
969 let aggregates = self.aggregates.last_mut().ok_or("Unexpected aggregate")?;
970 Ok(aggregates
971 .iter()
972 .find_map(|(v, a)| (a == &agg).then_some(v))
973 .cloned()
974 .unwrap_or_else(|| {
975 let new_var = variable();
976 aggregates.push((new_var.clone(), agg));
977 new_var
978 }))
979 }
980}
981
982fn unescape_iriref(mut input: &str) -> Result<String, &'static str> {
983 let mut output = String::with_capacity(input.len());
984 while let Some((before, after)) = input.split_once('\\') {
985 output.push_str(before);
986 let mut after = after.chars();
987 let (escape, after) = match after.next() {
988 Some('u') => read_hex_char::<4>(after.as_str())?,
989 Some('U') => read_hex_char::<8>(after.as_str())?,
990 Some(_) => {
991 return Err(
992 "IRIs are only allowed to contain escape sequences \\uXXXX and \\UXXXXXXXX",
993 );
994 }
995 None => return Err("IRIs are not allowed to end with a '\'"),
996 };
997 output.push(escape);
998 input = after;
999 }
1000 output.push_str(input);
1001 Ok(output)
1002}
1003
1004fn unescape_string(mut input: &str) -> Result<String, &'static str> {
1005 let mut output = String::with_capacity(input.len());
1006 while let Some((before, after)) = input.split_once('\\') {
1007 output.push_str(before);
1008 let mut after = after.chars();
1009 let (escape, after) = match after.next() {
1010 Some('t') => ('\u{0009}', after.as_str()),
1011 Some('b') => ('\u{0008}', after.as_str()),
1012 Some('n') => ('\u{000A}', after.as_str()),
1013 Some('r') => ('\u{000D}', after.as_str()),
1014 Some('f') => ('\u{000C}', after.as_str()),
1015 Some('"') => ('\u{0022}', after.as_str()),
1016 Some('\'') => ('\u{0027}', after.as_str()),
1017 Some('\\') => ('\u{005C}', after.as_str()),
1018 Some('u') => read_hex_char::<4>(after.as_str())?,
1019 Some('U') => read_hex_char::<8>(after.as_str())?,
1020 Some(_) => return Err("The character that can be escaped in strings are tbnrf\"'\\"),
1021 None => return Err("strings are not allowed to end with a '\'"),
1022 };
1023 output.push(escape);
1024 input = after;
1025 }
1026 output.push_str(input);
1027 Ok(output)
1028}
1029
1030fn read_hex_char<const SIZE: usize>(input: &str) -> Result<(char, &str), &'static str> {
1031 if let Some(escape) = input.get(..SIZE) {
1032 if let Some(char) = u32::from_str_radix(escape, 16)
1033 .ok()
1034 .and_then(char::from_u32)
1035 {
1036 Ok((char, &input[SIZE..]))
1037 } else {
1038 Err("\\u escape sequence should be followed by hexadecimal digits")
1039 }
1040 } else {
1041 Err("\\u escape sequence should be followed by hexadecimal digits")
1042 }
1043}
1044
1045fn variable() -> Variable {
1046 Variable::new_unchecked(format!("{:x}", random::<u128>()))
1047}
1048
1049parser! {
1050 grammar parser(state: &mut ParserState) for str {
1052 pub rule QueryUnit() -> Query = Query()
1053
1054 rule Query() -> Query = _ Prologue() _ q:(SelectQuery() / ConstructQuery() / DescribeQuery() / AskQuery()) _ {
1055 q
1056 }
1057
1058 pub rule UpdateInit() -> Vec<GraphUpdateOperation> = Update()
1059
1060 rule Prologue() = (BaseDecl() _ / PrefixDecl() _ / VersionDecl() _)* {}
1061
1062 rule BaseDecl() = i("BASE") _ i:IRIREF() {
1063 state.base_iri = Some(i)
1064 }
1065
1066 rule PrefixDecl() = i("PREFIX") _ ns:PNAME_NS() _ i:IRIREF() {
1067 state.prefixes.insert(ns.into(), i.into_inner());
1068 }
1069
1070 rule VersionDecl() = i("VERSION") _ VersionSpecifier() {?
1071 if cfg!(feature = "sparql-12") {
1072 Ok(())
1073 } else {
1074 Err("The VERSION declaration is only supported in SPARQL 1.2")
1075 }
1076 }
1077
1078 rule VersionSpecifier() = STRING_LITERAL1() / STRING_LITERAL2() {}
1079
1080 rule SelectQuery() -> Query = s:SelectClause() _ d:DatasetClauses() _ w:WhereClause() _ g:GroupClause()? _ h:HavingClause()? _ o:OrderClause()? _ l:LimitOffsetClauses()? _ v:ValuesClause() {?
1081 Ok(Query::Select {
1082 dataset: d,
1083 pattern: build_select(s, w, g, h, o, l, v, state)?,
1084 base_iri: state.base_iri.clone()
1085 })
1086 }
1087
1088 rule SubSelect() -> GraphPattern = s:SelectClause() _ w:WhereClause() _ g:GroupClause()? _ h:HavingClause()? _ o:OrderClause()? _ l:LimitOffsetClauses()? _ v:ValuesClause() {?
1089 build_select(s, w, g, h, o, l, v, state)
1090 }
1091
1092 rule SelectClause() -> Selection = i("SELECT") _ Selection_init() o:SelectClause_option() _ v:SelectClause_variables() {
1093 Selection {
1094 option: o,
1095 variables: v
1096 }
1097 }
1098 rule Selection_init() = {
1099 state.aggregates.push(Vec::new())
1100 }
1101 rule SelectClause_option() -> SelectionOption =
1102 i("DISTINCT") { SelectionOption::Distinct } /
1103 i("REDUCED") { SelectionOption::Reduced } /
1104 { SelectionOption::Default }
1105 rule SelectClause_variables() -> SelectionVariables =
1106 "*" { SelectionVariables::Star } /
1107 p:SelectClause_member()+ { SelectionVariables::Explicit(p) }
1108 rule SelectClause_member() -> SelectionMember =
1109 v:Var() _ { SelectionMember::Variable(v) } /
1110 "(" _ e:Expression() _ i("AS") _ v:Var() _ ")" _ { SelectionMember::Expression(e, v) }
1111
1112 rule ConstructQuery() -> Query =
1113 i("CONSTRUCT") _ c:ConstructTemplate() ConstructQuery_clear() _ d:DatasetClauses() _ w:WhereClause() _ g:GroupClause()? _ h:HavingClause()? _ o:OrderClause()? _ l:LimitOffsetClauses()? _ v:ValuesClause() {?
1114 Ok(Query::Construct {
1115 template: c,
1116 dataset: d,
1117 pattern: build_select(Selection::default(), w, g, h, o, l, v, state)?,
1118 base_iri: state.base_iri.clone()
1119 })
1120 } /
1121 i("CONSTRUCT") _ d:DatasetClauses() _ i("WHERE") _ "{" _ c:ConstructQuery_optional_triple_template() _ "}" _ g:GroupClause()? _ h:HavingClause()? _ o:OrderClause()? _ l:LimitOffsetClauses()? _ v:ValuesClause() {?
1122 Ok(Query::Construct {
1123 template: c.clone(),
1124 dataset: d,
1125 pattern: build_select(
1126 Selection::default(),
1127 GraphPattern::Bgp { patterns: c },
1128 g, h, o, l, v, state
1129 )?,
1130 base_iri: state.base_iri.clone()
1131 })
1132 }
1133 rule ConstructQuery_clear() = {
1134 state.currently_used_bnodes.clear();
1135 }
1136
1137 rule ConstructQuery_optional_triple_template() -> Vec<TriplePattern> = TriplesTemplate() / { Vec::new() }
1138
1139 rule DescribeQuery() -> Query =
1140 i("DESCRIBE") _ "*" _ d:DatasetClauses() _ w:WhereClause()? _ g:GroupClause()? _ h:HavingClause()? _ o:OrderClause()? _ l:LimitOffsetClauses()? _ v:ValuesClause() {?
1141 Ok(Query::Describe {
1142 dataset: d,
1143 pattern: build_select(Selection::default(), w.unwrap_or_default(), g, h, o, l, v, state)?,
1144 base_iri: state.base_iri.clone()
1145 })
1146 } /
1147 i("DESCRIBE") _ p:DescribeQuery_item()+ _ d:DatasetClauses() _ w:WhereClause()? _ g:GroupClause()? _ h:HavingClause()? _ o:OrderClause()? _ l:LimitOffsetClauses()? _ v:ValuesClause() {?
1148 Ok(Query::Describe {
1149 dataset: d,
1150 pattern: build_select(Selection {
1151 option: SelectionOption::Default,
1152 variables: SelectionVariables::Explicit(p.into_iter().map(|var_or_iri| match var_or_iri {
1153 NamedNodePattern::NamedNode(n) => SelectionMember::Expression(n.into(), variable()),
1154 NamedNodePattern::Variable(v) => SelectionMember::Variable(v)
1155 }).collect())
1156 }, w.unwrap_or_default(), g, h, o, l, v, state)?,
1157 base_iri: state.base_iri.clone()
1158 })
1159 }
1160 rule DescribeQuery_item() -> NamedNodePattern = i:VarOrIri() _ { i }
1161
1162 rule AskQuery() -> Query = i("ASK") _ d:DatasetClauses() _ w:WhereClause() _ g:GroupClause()? _ h:HavingClause()? _ o:OrderClause()? _ l:LimitOffsetClauses()? _ v:ValuesClause() {?
1163 Ok(Query::Ask {
1164 dataset: d,
1165 pattern: build_select(Selection::default(), w, g, h, o, l, v, state)?,
1166 base_iri: state.base_iri.clone()
1167 })
1168 }
1169
1170 rule DatasetClause() -> (Option<NamedNode>, Option<NamedNode>) = i("FROM") _ d:(DefaultGraphClause() / NamedGraphClause()) { d }
1171 rule DatasetClauses() -> Option<QueryDataset> = d:DatasetClause() ** (_) {
1172 if d.is_empty() {
1173 return None;
1174 }
1175 let mut default = Vec::new();
1176 let mut named = Vec::new();
1177 for (d, n) in d {
1178 if let Some(d) = d {
1179 default.push(d);
1180 }
1181 if let Some(n) = n {
1182 named.push(n);
1183 }
1184 }
1185 Some(QueryDataset {
1186 default, named: Some(named)
1187 })
1188 }
1189
1190 rule DefaultGraphClause() -> (Option<NamedNode>, Option<NamedNode>) = s:SourceSelector() {
1191 (Some(s), None)
1192 }
1193
1194 rule NamedGraphClause() -> (Option<NamedNode>, Option<NamedNode>) = i("NAMED") _ s:SourceSelector() {
1195 (None, Some(s))
1196 }
1197
1198 rule SourceSelector() -> NamedNode = iri()
1199
1200 rule WhereClause() -> GraphPattern = i("WHERE")? _ p:GroupGraphPattern() {
1201 p
1202 }
1203
1204 rule GroupClause() -> (Vec<Variable>, Vec<(Expression,Variable)>) = i("GROUP") _ i("BY") _ c:GroupCondition_item()+ {
1205 let mut projections: Vec<(Expression,Variable)> = Vec::new();
1206 let clauses = c.into_iter().map(|(e, vo)| {
1207 if let Expression::Variable(v) = e {
1208 v
1209 } else {
1210 let v = vo.unwrap_or_else(variable);
1211 projections.push((e, v.clone()));
1212 v
1213 }
1214 }).collect();
1215 (clauses, projections)
1216 }
1217 rule GroupCondition_item() -> (Expression, Option<Variable>) = c:GroupCondition() _ { c }
1218
1219 rule GroupCondition() -> (Expression, Option<Variable>) =
1220 e:BuiltInCall() { (e, None) } /
1221 e:FunctionCall() { (e, None) } /
1222 "(" _ e:Expression() _ v:GroupCondition_as()? ")" { (e, v) } /
1223 e:Var() { (e.into(), None) }
1224 rule GroupCondition_as() -> Variable = i("AS") _ v:Var() _ { v }
1225
1226 rule HavingClause() -> Expression = i("HAVING") _ e:HavingCondition()+ {?
1227 not_empty_fold(e.into_iter(), |a, b| Expression::And(Box::new(a), Box::new(b)))
1228 }
1229
1230 rule HavingCondition() -> Expression = c:Constraint() _ { c }
1231
1232 rule OrderClause() -> Vec<OrderExpression> = i("ORDER") _ i("BY") _ c:OrderClause_item()+ { c }
1233 rule OrderClause_item() -> OrderExpression = c:OrderCondition() _ { c }
1234
1235 rule OrderCondition() -> OrderExpression =
1236 i("ASC") _ e: BrackettedExpression() { OrderExpression::Asc(e) } /
1237 i("DESC") _ e: BrackettedExpression() { OrderExpression::Desc(e) } /
1238 e: Constraint() { OrderExpression::Asc(e) } /
1239 v: Var() { OrderExpression::Asc(Expression::from(v)) }
1240
1241 rule LimitOffsetClauses() -> (usize, Option<usize>) =
1242 l:LimitClause() _ o:OffsetClause()? { (o.unwrap_or(0), Some(l)) } /
1243 o:OffsetClause() _ l:LimitClause()? { (o, l) }
1244
1245 rule LimitClause() -> usize = i("LIMIT") _ l:$(INTEGER()) {?
1246 usize::from_str(l).map_err(|_| "The query limit should be a non negative integer")
1247 }
1248
1249 rule OffsetClause() -> usize = i("OFFSET") _ o:$(INTEGER()) {?
1250 usize::from_str(o).map_err(|_| "The query offset should be a non negative integer")
1251 }
1252
1253 rule ValuesClause() -> Option<GraphPattern> =
1254 i("VALUES") _ p:DataBlock() { Some(p) } /
1255 { None }
1256
1257 rule Update() -> Vec<GraphUpdateOperation> = _ Prologue() _ u:(Update_item() ** (";" _)) ( ";" _)? { u.into_iter().flatten().collect() }
1258 rule Update_item() -> Vec<GraphUpdateOperation> = u:Update1() Update_clear() _ { u }
1259 rule Update_clear() = {
1260 state.used_bnodes.clear();
1261 state.currently_used_bnodes.clear();
1262 }
1263
1264 rule Update1() -> Vec<GraphUpdateOperation> = Load() / Clear() / Drop() / Add() / Move() / Copy() / Create() / InsertData() / DeleteData() / DeleteWhere() / Modify()
1265 rule Update1_silent() -> bool = i("SILENT") { true } / { false }
1266
1267 rule Load() -> Vec<GraphUpdateOperation> = i("LOAD") _ silent:Update1_silent() _ source:iri() _ destination:Load_to()? {
1268 vec![GraphUpdateOperation::Load { silent, source, destination: destination.map_or(GraphName::DefaultGraph, GraphName::NamedNode) }]
1269 }
1270 rule Load_to() -> NamedNode = i("INTO") _ g: GraphRef() { g }
1271
1272 rule Clear() -> Vec<GraphUpdateOperation> = i("CLEAR") _ silent:Update1_silent() _ graph:GraphRefAll() {
1273 vec![GraphUpdateOperation::Clear { silent, graph }]
1274 }
1275
1276 rule Drop() -> Vec<GraphUpdateOperation> = i("DROP") _ silent:Update1_silent() _ graph:GraphRefAll() {
1277 vec![GraphUpdateOperation::Drop { silent, graph }]
1278 }
1279
1280 rule Create() -> Vec<GraphUpdateOperation> = i("CREATE") _ silent:Update1_silent() _ graph:GraphRef() {
1281 vec![GraphUpdateOperation::Create { silent, graph }]
1282 }
1283
1284 rule Add() -> Vec<GraphUpdateOperation> = i("ADD") _ silent:Update1_silent() _ from:GraphOrDefault() _ i("TO") _ to:GraphOrDefault() {
1285 if from == to {
1287 Vec::new() } else {
1289 let bgp = GraphPattern::Bgp { patterns: vec![TriplePattern::new(Variable::new_unchecked("s"), Variable::new_unchecked("p"), Variable::new_unchecked("o"))] };
1290 vec![copy_graph(from, to)]
1291 }
1292 }
1293
1294 rule Move() -> Vec<GraphUpdateOperation> = i("MOVE") _ silent:Update1_silent() _ from:GraphOrDefault() _ i("TO") _ to:GraphOrDefault() {
1295 if from == to {
1297 Vec::new() } else {
1299 let bgp = GraphPattern::Bgp { patterns: vec![TriplePattern::new(Variable::new_unchecked("s"), Variable::new_unchecked("p"), Variable::new_unchecked("o"))] };
1300 vec![GraphUpdateOperation::Drop { silent: true, graph: to.clone().into() }, copy_graph(from.clone(), to), GraphUpdateOperation::Drop { silent, graph: from.into() }]
1301 }
1302 }
1303
1304 rule Copy() -> Vec<GraphUpdateOperation> = i("COPY") _ silent:Update1_silent() _ from:GraphOrDefault() _ i("TO") _ to:GraphOrDefault() {
1305 if from == to {
1307 Vec::new() } else {
1309 let bgp = GraphPattern::Bgp { patterns: vec![TriplePattern::new(Variable::new_unchecked("s"), Variable::new_unchecked("p"), Variable::new_unchecked("o"))] };
1310 vec![GraphUpdateOperation::Drop { silent: true, graph: to.clone().into() }, copy_graph(from, to)]
1311 }
1312 }
1313
1314 rule InsertData() -> Vec<GraphUpdateOperation> = i("INSERT") _ i("DATA") _ data:QuadData() {
1315 vec![GraphUpdateOperation::InsertData { data }]
1316 }
1317
1318 rule DeleteData() -> Vec<GraphUpdateOperation> = i("DELETE") _ i("DATA") _ data:GroundQuadData() {
1319 vec![GraphUpdateOperation::DeleteData { data }]
1320 }
1321
1322 rule DeleteWhere() -> Vec<GraphUpdateOperation> = i("DELETE") _ i("WHERE") _ d:QuadPattern() {?
1323 let pattern = d.iter().map(|q| {
1324 let bgp = GraphPattern::Bgp { patterns: vec![TriplePattern::new(q.subject.clone(), q.predicate.clone(), q.object.clone())] };
1325 match &q.graph_name {
1326 GraphNamePattern::NamedNode(graph_name) => GraphPattern::Graph { name: graph_name.clone().into(), inner: Box::new(bgp) },
1327 GraphNamePattern::DefaultGraph => bgp,
1328 GraphNamePattern::Variable(graph_name) => GraphPattern::Graph { name: graph_name.clone().into(), inner: Box::new(bgp) },
1329 }
1330 }).reduce(new_join).unwrap_or_default();
1331 let delete = d.into_iter().map(GroundQuadPattern::try_from).collect::<Result<Vec<_>,_>>().map_err(|()| "Blank nodes are not allowed in DELETE WHERE")?;
1332 Ok(vec![GraphUpdateOperation::DeleteInsert {
1333 delete,
1334 insert: Vec::new(),
1335 using: None,
1336 pattern: Box::new(pattern)
1337 }])
1338 }
1339
1340 rule Modify() -> Vec<GraphUpdateOperation> = with:Modify_with()? _ c:Modify_clauses() _ u:(UsingClause() ** (_)) _ i("WHERE") _ pattern:GroupGraphPattern() {
1341 let (delete, insert) = c;
1342 let mut delete = delete.unwrap_or_default();
1343 let mut insert = insert.unwrap_or_default();
1344 #[expect(clippy::shadow_same)]
1345 let mut pattern = pattern;
1346
1347 let mut using = if u.is_empty() {
1348 None
1349 } else {
1350 let mut default = Vec::new();
1351 let mut named = Vec::new();
1352 for (d, n) in u {
1353 if let Some(d) = d {
1354 default.push(d)
1355 }
1356 if let Some(n) = n {
1357 named.push(n)
1358 }
1359 }
1360 Some(QueryDataset { default, named: Some(named) })
1361 };
1362
1363 if let Some(with) = with {
1364 delete = delete.into_iter().map(|q| if q.graph_name == GraphNamePattern::DefaultGraph {
1366 GroundQuadPattern {
1367 subject: q.subject,
1368 predicate: q.predicate,
1369 object: q.object,
1370 graph_name: with.clone().into()
1371 }
1372 } else {
1373 q
1374 }).collect();
1375 insert = insert.into_iter().map(|q| if q.graph_name == GraphNamePattern::DefaultGraph {
1376 QuadPattern {
1377 subject: q.subject,
1378 predicate: q.predicate,
1379 object: q.object,
1380 graph_name: with.clone().into()
1381 }
1382 } else {
1383 q
1384 }).collect();
1385 if using.is_none() {
1386 using = Some(QueryDataset { default: vec![with], named: None });
1387 }
1388 }
1389
1390 vec![GraphUpdateOperation::DeleteInsert {
1391 delete,
1392 insert,
1393 using,
1394 pattern: Box::new(pattern)
1395 }]
1396 }
1397 rule Modify_with() -> NamedNode = i("WITH") _ i:iri() _ { i }
1398 rule Modify_clauses() -> (Option<Vec<GroundQuadPattern>>, Option<Vec<QuadPattern>>) = d:DeleteClause() Modify_clear() _ i:InsertClause()? Modify_clear() {
1399 (Some(d), i)
1400 } / i:InsertClause() Modify_clear() {
1401 (None, Some(i))
1402 }
1403 rule Modify_clear() = {
1404 state.currently_used_bnodes.clear();
1405 }
1406
1407 rule DeleteClause() -> Vec<GroundQuadPattern> = i("DELETE") _ q:QuadPattern() {?
1408 q.into_iter().map(GroundQuadPattern::try_from).collect::<Result<Vec<_>,_>>().map_err(|()| "Blank nodes are not allowed in DELETE WHERE")
1409 }
1410
1411 rule InsertClause() -> Vec<QuadPattern> = i("INSERT") _ q:QuadPattern() { q }
1412
1413 rule UsingClause() -> (Option<NamedNode>, Option<NamedNode>) = i("USING") _ d:(UsingClause_default() / UsingClause_named()) { d }
1414 rule UsingClause_default() -> (Option<NamedNode>, Option<NamedNode>) = i:iri() {
1415 (Some(i), None)
1416 }
1417 rule UsingClause_named() -> (Option<NamedNode>, Option<NamedNode>) = i("NAMED") _ i:iri() {
1418 (None, Some(i))
1419 }
1420
1421 rule GraphOrDefault() -> GraphName = i("DEFAULT") {
1422 GraphName::DefaultGraph
1423 } / (i("GRAPH") _)? g:iri() {
1424 GraphName::NamedNode(g)
1425 }
1426
1427 rule GraphRef() -> NamedNode = i("GRAPH") _ g:iri() { g }
1428
1429 rule GraphRefAll() -> GraphTarget = i: GraphRef() { i.into() }
1430 / i("DEFAULT") { GraphTarget::DefaultGraph }
1431 / i("NAMED") { GraphTarget::NamedGraphs }
1432 / i("ALL") { GraphTarget::AllGraphs }
1433
1434 rule QuadPattern() -> Vec<QuadPattern> = "{" _ q:Quads() _ "}" { q }
1435
1436 rule QuadData() -> Vec<Quad> = "{" _ q:Quads() _ "}" {?
1437 q.into_iter().map(Quad::try_from).collect::<Result<Vec<_>, ()>>().map_err(|()| "Variables are not allowed in INSERT DATA")
1438 }
1439 rule GroundQuadData() -> Vec<GroundQuad> = "{" _ q:Quads() _ "}" {?
1440 q.into_iter().map(|q| GroundQuad::try_from(Quad::try_from(q)?)).collect::<Result<Vec<_>, ()>>().map_err(|()| "Variables and blank nodes are not allowed in DELETE DATA")
1441 }
1442
1443 rule Quads() -> Vec<QuadPattern> = q:(Quads_TriplesTemplate() / Quads_QuadsNotTriples()) ** (_) {
1444 q.into_iter().flatten().collect()
1445 }
1446 rule Quads_TriplesTemplate() -> Vec<QuadPattern> = t:TriplesTemplate() {
1447 t.into_iter().map(|t| QuadPattern::new(t.subject, t.predicate, t.object, GraphNamePattern::DefaultGraph)).collect()
1448 } rule Quads_QuadsNotTriples() -> Vec<QuadPattern> = q:QuadsNotTriples() _ "."? { q }
1450
1451 rule QuadsNotTriples() -> Vec<QuadPattern> = i("GRAPH") _ g:VarOrIri() _ "{" _ t:TriplesTemplate()? _ "}" {
1452 t.unwrap_or_default().into_iter().map(|t| QuadPattern::new(t.subject, t.predicate, t.object, g.clone())).collect()
1453 }
1454
1455 rule TriplesTemplate() -> Vec<TriplePattern> = ts:TriplesTemplate_inner() ++ (".") ("." _)? {
1456 ts.into_iter().flatten().collect()
1457 }
1458 rule TriplesTemplate_inner() -> Vec<TriplePattern> = _ t:TriplesSameSubject() _ { t }
1459
1460 rule GroupGraphPattern() -> GraphPattern =
1461 "{" _ GroupGraphPattern_clear() p:GroupGraphPatternSub() GroupGraphPattern_clear() _ "}" { p } /
1462 "{" _ GroupGraphPattern_clear() p:SubSelect() GroupGraphPattern_clear() _ "}" { p }
1463 rule GroupGraphPattern_clear() = {
1464 state.used_bnodes.extend(state.currently_used_bnodes.iter().cloned());
1466 state.currently_used_bnodes.clear();
1467 }
1468
1469 rule GroupGraphPatternSub() -> GraphPattern = a:TriplesBlock()? _ b:GroupGraphPatternSub_item()* {?
1470 let mut filter: Option<Expression> = None;
1471 let mut g = a.map_or_else(GraphPattern::default, build_bgp);
1472 for e in b.into_iter().flatten() {
1473 match e {
1474 PartialGraphPattern::Optional(p, f) => {
1475 g = GraphPattern::LeftJoin { left: Box::new(g), right: Box::new(p), expression: f }
1476 }
1477 #[cfg(feature = "sep-0006")]
1478 PartialGraphPattern::Lateral(p) => {
1479 let mut defined_variables = HashSet::new();
1480 add_defined_variables(&p, &mut defined_variables);
1481 let mut contains = false;
1482 g.on_in_scope_variable(|v| {
1483 if defined_variables.contains(v) {
1484 contains = true;
1485 }
1486 });
1487 if contains {
1488 return Err("An existing variable is overridden in the right side of LATERAL");
1489 }
1490 g = GraphPattern::Lateral { left: Box::new(g), right: Box::new(p) }
1491 }
1492 PartialGraphPattern::Minus(p) => {
1493 g = GraphPattern::Minus { left: Box::new(g), right: Box::new(p) }
1494 }
1495 PartialGraphPattern::Bind(expression, variable) => {
1496 let mut contains = false;
1497 g.on_in_scope_variable(|v| {
1498 if *v == variable {
1499 contains = true;
1500 }
1501 });
1502 if contains {
1503 return Err("BIND is overriding an existing variable")
1504 }
1505 g = GraphPattern::Extend { inner: Box::new(g), variable, expression }
1506 }
1507 PartialGraphPattern::Filter(expr) => filter = Some(if let Some(f) = filter {
1508 Expression::And(Box::new(f), Box::new(expr))
1509 } else {
1510 expr
1511 }),
1512 PartialGraphPattern::Other(e) => g = new_join(g, e),
1513 }
1514 }
1515
1516 Ok(if let Some(expr) = filter {
1517 GraphPattern::Filter { expr, inner: Box::new(g) }
1518 } else {
1519 g
1520 })
1521 }
1522 rule GroupGraphPatternSub_item() -> Vec<PartialGraphPattern> = a:GraphPatternNotTriples() _ ("." _)? b:TriplesBlock()? _ {
1523 let mut result = vec![a];
1524 if let Some(v) = b {
1525 result.push(PartialGraphPattern::Other(build_bgp(v)));
1526 }
1527 result
1528 }
1529
1530 rule TriplesBlock() -> Vec<TripleOrPathPattern> = hs:TriplesBlock_inner() ++ (".") ("." _)? {
1531 hs.into_iter().flatten().collect()
1532 }
1533 rule TriplesBlock_inner() -> Vec<TripleOrPathPattern> = _ h:TriplesSameSubjectPath() _ { h }
1534
1535 rule ReifiedTripleBlock() -> Vec<TriplePattern> = s:ReifiedTriple() _ po:PropertyList() {?
1536 let mut patterns = po.patterns;
1537 patterns.extend(s.patterns);
1538 for (p, os) in po.focus {
1539 for o in os {
1540 add_to_triple_patterns(s.focus.clone(), p.clone(), o, &mut patterns)?;
1541 }
1542 }
1543 Ok(patterns)
1544 }
1545
1546 rule ReifiedTripleBlockPath() -> Vec<TripleOrPathPattern> = s:ReifiedTriple() _ po:PropertyListPath() {?
1547 let mut patterns = po.patterns;
1548 patterns.extend(s.patterns.into_iter().map(Into::into));
1549 for (p, os) in po.focus {
1550 for o in os {
1551 add_to_triple_or_path_patterns(s.focus.clone(), p.clone(), o, &mut patterns)?;
1552 }
1553 }
1554 Ok(patterns)
1555 }
1556
1557 rule GraphPatternNotTriples() -> PartialGraphPattern = GroupOrUnionGraphPattern() / OptionalGraphPattern() / LateralGraphPattern() / MinusGraphPattern() / GraphGraphPattern() / ServiceGraphPattern() / Filter() / Bind() / InlineData()
1558
1559 rule OptionalGraphPattern() -> PartialGraphPattern = i("OPTIONAL") _ p:GroupGraphPattern() {
1560 if let GraphPattern::Filter { expr, inner } = p {
1561 PartialGraphPattern::Optional(*inner, Some(expr))
1562 } else {
1563 PartialGraphPattern::Optional(p, None)
1564 }
1565 }
1566
1567 rule LateralGraphPattern() -> PartialGraphPattern = i("LATERAL") _ p:GroupGraphPattern() {?
1568 #[cfg(feature = "sep-0006")]{Ok(PartialGraphPattern::Lateral(p))}
1569 #[cfg(not(feature = "sep-0006"))]{Err("The LATERAL modifier is not supported")}
1570 }
1571
1572 rule GraphGraphPattern() -> PartialGraphPattern = i("GRAPH") _ name:VarOrIri() _ p:GroupGraphPattern() {
1573 PartialGraphPattern::Other(GraphPattern::Graph { name, inner: Box::new(p) })
1574 }
1575
1576 rule ServiceGraphPattern() -> PartialGraphPattern =
1577 i("SERVICE") _ i("SILENT") _ name:VarOrIri() _ p:GroupGraphPattern() { PartialGraphPattern::Other(GraphPattern::Service { name, inner: Box::new(p), silent: true }) } /
1578 i("SERVICE") _ name:VarOrIri() _ p:GroupGraphPattern() { PartialGraphPattern::Other(GraphPattern::Service{ name, inner: Box::new(p), silent: false }) }
1579
1580 rule Bind() -> PartialGraphPattern = i("BIND") _ "(" _ e:Expression() _ i("AS") _ v:Var() _ ")" {
1581 PartialGraphPattern::Bind(e, v)
1582 }
1583
1584 rule InlineData() -> PartialGraphPattern = i("VALUES") _ p:DataBlock() { PartialGraphPattern::Other(p) }
1585
1586 rule DataBlock() -> GraphPattern = l:(InlineDataOneVar() / InlineDataFull()) {
1587 GraphPattern::Values { variables: l.0, bindings: l.1 }
1588 }
1589
1590 rule InlineDataOneVar() -> (Vec<Variable>, Vec<Vec<Option<GroundTerm>>>) = var:Var() _ "{" _ d:InlineDataOneVar_value()* "}" {
1591 (vec![var], d)
1592 }
1593 rule InlineDataOneVar_value() -> Vec<Option<GroundTerm>> = t:DataBlockValue() _ { vec![t] }
1594
1595 rule InlineDataFull() -> (Vec<Variable>, Vec<Vec<Option<GroundTerm>>>) = "(" _ vars:InlineDataFull_var()* _ ")" _ "{" _ vals:InlineDataFull_values()* "}" {?
1596 if vars.iter().enumerate().any(|(i, vl)| vars[i+1..].contains(vl)) {
1597 Err("Repeated variables are not allowed in VALUES clauses.")
1598 } else if vals.iter().any(|vs| vs.len() != vars.len()) {
1599 Err("The VALUES clause rows should have exactly the same number of values as there are variables. To set a value to undefined use UNDEF.")
1600 } else {
1601 Ok((vars, vals))
1602 }
1603 }
1604 rule InlineDataFull_var() -> Variable = v:Var() _ { v }
1605 rule InlineDataFull_values() -> Vec<Option<GroundTerm>> = "(" _ v:InlineDataFull_value()* _ ")" _ { v }
1606 rule InlineDataFull_value() -> Option<GroundTerm> = v:DataBlockValue() _ { v }
1607
1608 rule DataBlockValue() -> Option<GroundTerm> =
1609 t:TripleTermData() {?
1610 #[cfg(feature = "sparql-12")]{Ok(Some(t.into()))}
1611 #[cfg(not(feature = "sparql-12"))]{Err("Triple terms are only available in SPARQL 1.2")}
1612 } /
1613 i:iri() { Some(i.into()) } /
1614 l:RDFLiteral() { Some(l.into()) } /
1615 l:NumericLiteral() { Some(l.into()) } /
1616 l:BooleanLiteral() { Some(l.into()) } /
1617 i("UNDEF") { None }
1618
1619 rule Reifier() -> TermPattern = "~" _ v:VarOrReifierId()? { v.unwrap_or_else(|| BlankNode::default().into()) }
1620
1621 rule VarOrReifierId() -> TermPattern =
1622 v:Var() { v.into() } /
1623 i:iri() { i.into() } /
1624 b:BlankNode() { b.into() }
1625
1626 rule MinusGraphPattern() -> PartialGraphPattern = i("MINUS") _ p: GroupGraphPattern() {
1627 PartialGraphPattern::Minus(p)
1628 }
1629
1630 rule GroupOrUnionGraphPattern() -> PartialGraphPattern = p:GroupOrUnionGraphPattern_item() **<1,> (i("UNION") _) {?
1631 not_empty_fold(p.into_iter(), |a, b| {
1632 GraphPattern::Union { left: Box::new(a), right: Box::new(b) }
1633 }).map(PartialGraphPattern::Other)
1634 }
1635 rule GroupOrUnionGraphPattern_item() -> GraphPattern = p:GroupGraphPattern() _ { p }
1636
1637 rule Filter() -> PartialGraphPattern = i("FILTER") _ c:Constraint() {
1638 PartialGraphPattern::Filter(c)
1639 }
1640
1641 rule Constraint() -> Expression = BrackettedExpression() / FunctionCall() / BuiltInCall()
1642
1643 rule FunctionCall() -> Expression = f:iri() _ a:ArgList() {?
1644 if state.custom_aggregate_functions.contains(&f) {
1645 Err("This custom function is an aggregate function and not a regular function")
1646 } else {
1647 Ok(Expression::FunctionCall(Function::Custom(f), a))
1648 }
1649 }
1650
1651 rule ArgList() -> Vec<Expression> =
1652 "(" _ e:ArgList_item() **<1,> ("," _) _ ")" { e } /
1653 NIL() { Vec::new() }
1654 rule ArgList_item() -> Expression = e:Expression() _ { e }
1655
1656 rule ExpressionList() -> Vec<Expression> =
1657 "(" _ e:ExpressionList_item() **<1,> ("," _) ")" { e } /
1658 NIL() { Vec::new() }
1659 rule ExpressionList_item() -> Expression = e:Expression() _ { e }
1660
1661 rule ConstructTemplate() -> Vec<TriplePattern> = "{" _ t:ConstructTriples() _ "}" { t }
1662
1663 rule ConstructTriples() -> Vec<TriplePattern> = p:ConstructTriples_item() ** ("." _) "."? {
1664 p.into_iter().flatten().collect()
1665 }
1666 rule ConstructTriples_item() -> Vec<TriplePattern> = t:TriplesSameSubject() _ { t }
1667
1668 rule TriplesSameSubject() -> Vec<TriplePattern> =
1669 ReifiedTripleBlock() /
1670 s:VarOrTerm() _ po:PropertyListNotEmpty() {?
1671 let mut patterns = po.patterns;
1672 for (p, os) in po.focus {
1673 for o in os {
1674 add_to_triple_patterns(s.clone(), p.clone(), o, &mut patterns)?
1675 }
1676 }
1677 Ok(patterns)
1678 } /
1679 s:TriplesNode() _ po:PropertyList() {?
1680 let mut patterns = s.patterns;
1681 patterns.extend(po.patterns);
1682 for (p, os) in po.focus {
1683 for o in os {
1684 add_to_triple_patterns(s.focus.clone(), p.clone(), o, &mut patterns)?
1685 }
1686 }
1687 Ok(patterns)
1688 }
1689
1690 rule PropertyList() -> FocusedTriplePattern<Vec<(NamedNodePattern,Vec<ReifiedTerm>)>> =
1691 PropertyListNotEmpty() /
1692 { FocusedTriplePattern::default() }
1693
1694 rule PropertyListNotEmpty() -> FocusedTriplePattern<Vec<(NamedNodePattern,Vec<ReifiedTerm>)>> = hp:Verb() _ ho:ObjectList() _ l:PropertyListNotEmpty_item()* {
1695 l.into_iter().flatten().fold(FocusedTriplePattern {
1696 focus: vec![(hp, ho.focus)],
1697 patterns: ho.patterns
1698 }, |mut a, b| {
1699 a.focus.push(b.focus);
1700 a.patterns.extend(b.patterns);
1701 a
1702 })
1703 }
1704 rule PropertyListNotEmpty_item() -> Option<FocusedTriplePattern<(NamedNodePattern,Vec<ReifiedTerm>)>> = ";" _ c:PropertyListNotEmpty_item_content()? {
1705 c
1706 }
1707 rule PropertyListNotEmpty_item_content() -> FocusedTriplePattern<(NamedNodePattern,Vec<ReifiedTerm>)> = p:Verb() _ o:ObjectList() _ {
1708 FocusedTriplePattern {
1709 focus: (p, o.focus),
1710 patterns: o.patterns
1711 }
1712 }
1713
1714 rule Verb() -> NamedNodePattern = VarOrIri() / "a" { rdf::TYPE.into_owned().into() }
1715
1716 rule ObjectList() -> FocusedTriplePattern<Vec<ReifiedTerm >> = o:ObjectList_item() **<1,> ("," _) {
1717 o.into_iter().fold(FocusedTriplePattern::<Vec<ReifiedTerm >>::default(), |mut a, b| {
1718 a.focus.push(b.focus);
1719 a.patterns.extend_from_slice(&b.patterns);
1720 a
1721 })
1722 }
1723 rule ObjectList_item() -> FocusedTriplePattern<ReifiedTerm> = o:Object() _ { o }
1724
1725 rule Object() -> FocusedTriplePattern<ReifiedTerm> = g:GraphNode() _ a:Annotation() {
1726 let mut patterns = g.patterns;
1727 patterns.extend(a.patterns);
1728 FocusedTriplePattern {
1729 focus: ReifiedTerm {
1730 term: g.focus,
1731 reifiers: a.focus
1732 },
1733 patterns
1734 }
1735 }
1736
1737 rule TriplesSameSubjectPath() -> Vec<TripleOrPathPattern> =
1738 ReifiedTripleBlockPath() /
1739 s:VarOrTerm() _ po:PropertyListPathNotEmpty() {?
1740 let mut patterns = po.patterns;
1741 for (p, os) in po.focus {
1742 for o in os {
1743 add_to_triple_or_path_patterns(s.clone(), p.clone(), o, &mut patterns)?;
1744 }
1745 }
1746 Ok(patterns)
1747 } /
1748 s:TriplesNodePath() _ po:PropertyListPath() {?
1749 let mut patterns = s.patterns;
1750 patterns.extend(po.patterns);
1751 for (p, os) in po.focus {
1752 for o in os {
1753 add_to_triple_or_path_patterns(s.focus.clone(), p.clone(), o, &mut patterns)?;
1754 }
1755 }
1756 Ok(patterns)
1757 }
1758
1759 rule PropertyListPath() -> FocusedTripleOrPathPattern<Vec<(VariableOrPropertyPath,Vec<ReifiedTerm>)>> =
1760 PropertyListPathNotEmpty() /
1761 { FocusedTripleOrPathPattern::default() }
1762
1763 rule PropertyListPathNotEmpty() -> FocusedTripleOrPathPattern<Vec<(VariableOrPropertyPath,Vec<ReifiedTerm>)>> = hp:(VerbPath() / VerbSimple()) _ ho:ObjectListPath() _ t:PropertyListPathNotEmpty_item()* {
1764 t.into_iter().flatten().fold(FocusedTripleOrPathPattern {
1765 focus: vec![(hp, ho.focus)],
1766 patterns: ho.patterns
1767 }, |mut a, b| {
1768 a.focus.push(b.focus);
1769 a.patterns.extend(b.patterns);
1770 a
1771 })
1772 }
1773 rule PropertyListPathNotEmpty_item() -> Option<FocusedTripleOrPathPattern<(VariableOrPropertyPath,Vec<ReifiedTerm>)>> = ";" _ c:PropertyListPathNotEmpty_item_content()? {
1774 c
1775 }
1776 rule PropertyListPathNotEmpty_item_content() -> FocusedTripleOrPathPattern<(VariableOrPropertyPath,Vec<ReifiedTerm>)> = p:(VerbPath() / VerbSimple()) _ o:ObjectListPath() _ {
1777 FocusedTripleOrPathPattern {
1778 focus: (p, o.focus),
1779 patterns: o.patterns
1780 }
1781 }
1782
1783 rule VerbPath() -> VariableOrPropertyPath = p:Path() {
1784 p.into()
1785 }
1786
1787 rule VerbSimple() -> VariableOrPropertyPath = v:Var() {
1788 v.into()
1789 }
1790
1791 rule ObjectListPath() -> FocusedTripleOrPathPattern<Vec<ReifiedTerm>> = o:ObjectListPath_item() **<1,> ("," _) {
1792 o.into_iter().fold(FocusedTripleOrPathPattern::<Vec<ReifiedTerm>>::default(), |mut a, b| {
1793 a.focus.push(b.focus);
1794 a.patterns.extend(b.patterns);
1795 a
1796 })
1797 }
1798 rule ObjectListPath_item() -> FocusedTripleOrPathPattern<ReifiedTerm> = o:ObjectPath() _ { o }
1799
1800 rule ObjectPath() -> FocusedTripleOrPathPattern<ReifiedTerm> = g:GraphNodePath() _ a:AnnotationPath() {
1801 let mut patterns = g.patterns;
1802 patterns.extend(a.patterns);
1803 FocusedTripleOrPathPattern {
1804 focus: ReifiedTerm {
1805 term: g.focus,
1806 reifiers: a.focus
1807 },
1808 patterns
1809 }
1810 }
1811
1812 rule Path() -> PropertyPathExpression = PathAlternative()
1813
1814 rule PathAlternative() -> PropertyPathExpression = p:PathAlternative_item() **<1,> ("|" _) {?
1815 not_empty_fold(p.into_iter(), |a, b| {
1816 PropertyPathExpression::Alternative(Box::new(a), Box::new(b))
1817 })
1818 }
1819 rule PathAlternative_item() -> PropertyPathExpression = p:PathSequence() _ { p }
1820
1821 rule PathSequence() -> PropertyPathExpression = p:PathSequence_item() **<1,> ("/" _) {?
1822 not_empty_fold(p.into_iter(), |a, b| {
1823 PropertyPathExpression::Sequence(Box::new(a), Box::new(b))
1824 })
1825 }
1826 rule PathSequence_item() -> PropertyPathExpression = p:PathEltOrInverse() _ { p }
1827
1828 rule PathElt() -> PropertyPathExpression = p:PathPrimary() _ o:PathElt_op()? {
1829 match o {
1830 Some('?') => PropertyPathExpression::ZeroOrOne(Box::new(p)),
1831 Some('*') => PropertyPathExpression::ZeroOrMore(Box::new(p)),
1832 Some('+') => PropertyPathExpression::OneOrMore(Box::new(p)),
1833 Some(_) => unreachable!(),
1834 None => p
1835 }
1836 }
1837 rule PathElt_op() -> char =
1838 "*" { '*' } /
1839 "+" { '+' } /
1840 "?" !(['0'..='9'] / PN_CHARS_U()) { '?' } rule PathEltOrInverse() -> PropertyPathExpression =
1843 "^" _ p:PathElt() { PropertyPathExpression::Reverse(Box::new(p)) } /
1844 PathElt()
1845
1846 rule PathPrimary() -> PropertyPathExpression =
1847 v:iri() { v.into() } /
1848 "a" { rdf::TYPE.into_owned().into() } /
1849 "!" _ p:PathNegatedPropertySet() { p } /
1850 "(" _ p:Path() _ ")" { p }
1851
1852 rule PathNegatedPropertySet() -> PropertyPathExpression =
1853 "(" _ p:PathNegatedPropertySet_item() **<1,> ("|" _) ")" {
1854 let mut direct = Vec::new();
1855 let mut inverse = Vec::new();
1856 for e in p {
1857 match e {
1858 Either::Left(a) => direct.push(a),
1859 Either::Right(b) => inverse.push(b)
1860 }
1861 }
1862 if inverse.is_empty() {
1863 PropertyPathExpression::NegatedPropertySet(direct)
1864 } else if direct.is_empty() {
1865 PropertyPathExpression::Reverse(Box::new(PropertyPathExpression::NegatedPropertySet(inverse)))
1866 } else {
1867 PropertyPathExpression::Alternative(
1868 Box::new(PropertyPathExpression::NegatedPropertySet(direct)),
1869 Box::new(PropertyPathExpression::Reverse(Box::new(PropertyPathExpression::NegatedPropertySet(inverse))))
1870 )
1871 }
1872 } /
1873 p:PathOneInPropertySet() {
1874 match p {
1875 Either::Left(a) => PropertyPathExpression::NegatedPropertySet(vec![a]),
1876 Either::Right(b) => PropertyPathExpression::Reverse(Box::new(PropertyPathExpression::NegatedPropertySet(vec![b]))),
1877 }
1878 }
1879 rule PathNegatedPropertySet_item() -> Either<NamedNode,NamedNode> = p:PathOneInPropertySet() _ { p }
1880
1881 rule PathOneInPropertySet() -> Either<NamedNode,NamedNode> =
1882 "^" _ v:iri() { Either::Right(v) } /
1883 "^" _ "a" { Either::Right(rdf::TYPE.into()) } /
1884 v:iri() { Either::Left(v) } /
1885 "a" { Either::Left(rdf::TYPE.into()) }
1886
1887 rule TriplesNode() -> FocusedTriplePattern<TermPattern> = Collection() / BlankNodePropertyList()
1888
1889 rule BlankNodePropertyList() -> FocusedTriplePattern<TermPattern> = "[" _ po:PropertyListNotEmpty() _ "]" {?
1890 let mut patterns = po.patterns;
1891 let mut bnode = TermPattern::from(BlankNode::default());
1892 for (p, os) in po.focus {
1893 for o in os {
1894 add_to_triple_patterns(bnode.clone(), p.clone(), o, &mut patterns)?;
1895 }
1896 }
1897 Ok(FocusedTriplePattern {
1898 focus: bnode,
1899 patterns
1900 })
1901 }
1902
1903 rule TriplesNodePath() -> FocusedTripleOrPathPattern<TermPattern> = CollectionPath() / BlankNodePropertyListPath()
1904
1905 rule BlankNodePropertyListPath() -> FocusedTripleOrPathPattern<TermPattern> = "[" _ po:PropertyListPathNotEmpty() _ "]" {?
1906 let mut patterns = po.patterns;
1907 let mut bnode = TermPattern::from(BlankNode::default());
1908 for (p, os) in po.focus {
1909 for o in os {
1910 add_to_triple_or_path_patterns(bnode.clone(), p.clone(), o, &mut patterns)?;
1911 }
1912 }
1913 Ok(FocusedTripleOrPathPattern {
1914 focus: bnode,
1915 patterns
1916 })
1917 }
1918
1919 rule Collection() -> FocusedTriplePattern<TermPattern> = "(" _ o:Collection_item()+ ")" {
1920 let mut patterns: Vec<TriplePattern> = Vec::new();
1921 let mut current_list_node = TermPattern::from(rdf::NIL.into_owned());
1922 for objWithPatterns in o.into_iter().rev() {
1923 let new_blank_node = TermPattern::from(BlankNode::default());
1924 patterns.push(TriplePattern::new(new_blank_node.clone(), rdf::FIRST.into_owned(), objWithPatterns.focus.clone()));
1925 patterns.push(TriplePattern::new(new_blank_node.clone(), rdf::REST.into_owned(), current_list_node));
1926 current_list_node = new_blank_node;
1927 patterns.extend_from_slice(&objWithPatterns.patterns);
1928 }
1929 FocusedTriplePattern {
1930 focus: current_list_node,
1931 patterns
1932 }
1933 }
1934 rule Collection_item() -> FocusedTriplePattern<TermPattern> = o:GraphNode() _ { o }
1935
1936 rule CollectionPath() -> FocusedTripleOrPathPattern<TermPattern> = "(" _ o:CollectionPath_item()+ _ ")" {
1937 let mut patterns: Vec<TripleOrPathPattern> = Vec::new();
1938 let mut current_list_node = TermPattern::from(rdf::NIL.into_owned());
1939 for objWithPatterns in o.into_iter().rev() {
1940 let new_blank_node = TermPattern::from(BlankNode::default());
1941 patterns.push(TriplePattern::new(new_blank_node.clone(), rdf::FIRST.into_owned(), objWithPatterns.focus.clone()).into());
1942 patterns.push(TriplePattern::new(new_blank_node.clone(), rdf::REST.into_owned(), current_list_node).into());
1943 current_list_node = new_blank_node;
1944 patterns.extend(objWithPatterns.patterns);
1945 }
1946 FocusedTripleOrPathPattern {
1947 focus: current_list_node,
1948 patterns
1949 }
1950 }
1951 rule CollectionPath_item() -> FocusedTripleOrPathPattern<TermPattern> = p:GraphNodePath() _ { p }
1952
1953 rule VarOrTerm() -> TermPattern =
1954 v:Var() { v.into() } /
1955 t:TripleTerm() {?
1956 #[cfg(feature = "sparql-12")]{Ok(t.into())}
1957 #[cfg(not(feature = "sparql-12"))]{Err("Triple terms are only available in SPARQL 1.2")}
1958 } /
1959 i:iri() { i.into() } /
1960 l:RDFLiteral() { l.into() } /
1961 l:NumericLiteral() { l.into() } /
1962 l:BooleanLiteral() { l.into() } /
1963 b:BlankNode() { b.into() } /
1964 NIL() { rdf::NIL.into_owned().into() }
1965
1966 rule AnnotationPath() -> FocusedTripleOrPathPattern<Vec<TermPattern>> = a:AnnotationPath_e()* {
1967 let mut output: FocusedTripleOrPathPattern<Vec<TermPattern>> = FocusedTripleOrPathPattern::new(Vec::new());
1968 for a in a {
1969 output.focus.push(a.focus);
1970 output.patterns.extend(a.patterns);
1971 }
1972 output
1973 }
1974 rule AnnotationPath_e() -> FocusedTripleOrPathPattern<TermPattern> =
1975 r:Reifier() _ a:AnnotationBlockPath()? _ {?
1976 let mut output: FocusedTripleOrPathPattern<TermPattern> = FocusedTripleOrPathPattern::new(r);
1977 if let Some(annotations) = a {
1978 for (p, os) in annotations.focus {
1979 for o in os {
1980 add_to_triple_or_path_patterns(output.focus.clone(), p.clone(), o, &mut output.patterns)?;
1981 }
1982 }
1983 output.patterns.extend(annotations.patterns);
1984 }
1985 Ok(output)
1986 } /
1987 a:AnnotationBlockPath() _ {?
1988 let mut output: FocusedTripleOrPathPattern<TermPattern> = FocusedTripleOrPathPattern::new(BlankNode::default());
1989 for (p, os) in a.focus {
1990 for o in os {
1991 add_to_triple_or_path_patterns(output.focus.clone(), p.clone(), o, &mut output.patterns)?;
1992 }
1993 }
1994 output.patterns.extend(a.patterns);
1995 Ok(output)
1996 }
1997
1998 rule AnnotationBlockPath() -> FocusedTripleOrPathPattern<Vec<(VariableOrPropertyPath,Vec<ReifiedTerm>)>> = "{|" _ a:PropertyListPathNotEmpty() _ "|}" { a }
1999
2000 rule Annotation() -> FocusedTriplePattern<Vec<TermPattern>> = a:Annotation_e()* {
2001 let mut output: FocusedTriplePattern<Vec<TermPattern>> = FocusedTriplePattern::new(Vec::new());
2002 for a in a {
2003 output.focus.push(a.focus);
2004 output.patterns.extend(a.patterns);
2005 }
2006 output
2007 }
2008 rule Annotation_e() -> FocusedTriplePattern<TermPattern> =
2009 r:Reifier() _ a:AnnotationBlock()? _ {?
2010 let mut output: FocusedTriplePattern<TermPattern> = FocusedTriplePattern::new(r);
2011 if let Some(annotations) = a {
2012 for (p, os) in annotations.focus {
2013 for o in os {
2014 add_to_triple_patterns(output.focus.clone(), p.clone(), o, &mut output.patterns)?;
2015 }
2016 }
2017 output.patterns.extend(annotations.patterns);
2018 }
2019 Ok(output)
2020 } /
2021 a:AnnotationBlock() _ {?
2022 let mut output: FocusedTriplePattern<TermPattern> = FocusedTriplePattern::new(BlankNode::default());
2023 for (p, os) in a.focus {
2024 for o in os {
2025 add_to_triple_patterns(output.focus.clone(), p.clone(), o, &mut output.patterns)?;
2026 }
2027 }
2028 output.patterns.extend(a.patterns);
2029 Ok(output)
2030 }
2031
2032 rule AnnotationBlock() -> FocusedTriplePattern<Vec<(NamedNodePattern,Vec<ReifiedTerm>)>> = "{|" _ a:PropertyListNotEmpty() _ "|}" { a }
2033
2034 rule GraphNode() -> FocusedTriplePattern<TermPattern> =
2035 ReifiedTriple() /
2036 t:VarOrTerm() { FocusedTriplePattern::new(t) } /
2037 TriplesNode()
2038
2039 rule GraphNodePath() -> FocusedTripleOrPathPattern<TermPattern> =
2040 t:ReifiedTriple() { t.into() } /
2041 t:VarOrTerm() { FocusedTripleOrPathPattern::new(t) } /
2042 TriplesNodePath()
2043
2044 rule ReifiedTriple() -> FocusedTriplePattern<TermPattern> = "<<" _ s:ReifiedTripleSubject() _ p:Verb() _ o:ReifiedTripleObject() _ r:Reifier()? _ ">>" {?
2045 #[cfg(feature = "sparql-12")]
2046 {
2047 let r = r.unwrap_or_else(|| BlankNode::default().into());
2048 let mut output = FocusedTriplePattern::new(r.clone());
2049 output.patterns.push(TriplePattern {
2050 subject: r,
2051 predicate: rdf::REIFIES.into_owned().into(),
2052 object: TriplePattern {
2053 subject: s.focus,
2054 predicate: p,
2055 object: o.focus
2056 }.into()
2057 });
2058 output.patterns.extend(s.patterns);
2059 output.patterns.extend(o.patterns);
2060 Ok(output)
2061 }
2062 #[cfg(not(feature = "sparql-12"))]
2063 {
2064 Err("Reified triples are only available in SPARQL 1.2")
2065 }
2066 }
2067
2068 rule ReifiedTripleSubject() -> FocusedTriplePattern<TermPattern> = ReifiedTripleObject()
2069
2070 rule ReifiedTripleObject() -> FocusedTriplePattern<TermPattern> =
2071 v:Var() { FocusedTriplePattern::new(v) } /
2072 t:TripleTerm() {?
2073 #[cfg(feature = "sparql-12")]{Ok(FocusedTriplePattern::new(t))}
2074 #[cfg(not(feature = "sparql-12"))]{Err("Triples terms are only available in SPARQL 1.2")}
2075 } /
2076 ReifiedTriple() /
2077 i:iri() { FocusedTriplePattern::new(i) } /
2078 l:RDFLiteral() { FocusedTriplePattern::new(l) } /
2079 l:NumericLiteral() { FocusedTriplePattern::new(l) } /
2080 l:BooleanLiteral() { FocusedTriplePattern::new(l) } /
2081 b:BlankNode() { FocusedTriplePattern::new(b) }
2082
2083 rule TripleTerm() -> TriplePattern = "<<(" _ s:TripleTermSubject() _ p:Verb() _ o:TripleTermObject() _ ")>>" {
2084 TriplePattern {
2085 subject: s,
2086 predicate: p,
2087 object: o
2088 }
2089 }
2090
2091 rule TripleTermSubject() -> TermPattern = TripleTermObject()
2092
2093 rule TripleTermObject() -> TermPattern =
2094 v:Var() { v.into() } /
2095 t:TripleTerm() {?
2096 #[cfg(feature = "sparql-12")]{Ok(t.into())}
2097 #[cfg(not(feature = "sparql-12"))]{Err("Triples terms are only available in SPARQL 1.2")}
2098 } /
2099 i:iri() { i.into() } /
2100 l:RDFLiteral() { l.into() } /
2101 l:NumericLiteral() { l.into() } /
2102 l:BooleanLiteral() { l.into() } /
2103 b:BlankNode() { b.into() }
2104
2105 rule TripleTermData() -> GroundTriple = "<<(" _ s:TripleTermDataSubject() _ p:TripleTermData_p() _ o:TripleTermDataObject() _ ")>>" {?
2106 Ok(GroundTriple {
2107 subject: if let GroundTerm::NamedNode(s) = s { s } else { return Err("Literals or triple terms are not allowed in subject position of nested patterns") },
2108 predicate: p,
2109 object: o
2110 })
2111 }
2112 rule TripleTermData_p() -> NamedNode = i: iri() { i } / "a" { rdf::TYPE.into() }
2113
2114 rule TripleTermDataSubject() -> GroundTerm = TripleTermDataObject()
2115
2116 rule TripleTermDataObject() -> GroundTerm =
2117 t:TripleTermData() {?
2118 #[cfg(feature = "sparql-12")]{Ok(t.into())}
2119 #[cfg(not(feature = "sparql-12"))]{Err("Triples terms are only available in SPARQL 1.2")}
2120 } /
2121 i:iri() { i.into() } /
2122 l:RDFLiteral() { l.into() } /
2123 l:NumericLiteral() { l.into() } /
2124 l:BooleanLiteral() { l.into() }
2125
2126 rule VarOrIri() -> NamedNodePattern =
2127 v:Var() { v.into() } /
2128 i:iri() { i.into() }
2129
2130 rule Var() -> Variable = name:(VAR1() / VAR2()) { Variable::new_unchecked(name) }
2131
2132 rule Expression() -> Expression = e:ConditionalOrExpression() {e}
2133
2134 rule ConditionalOrExpression() -> Expression = e:ConditionalOrExpression_item() **<1,> ("||" _) {?
2135 not_empty_fold(e.into_iter(), |a, b| Expression::Or(Box::new(a), Box::new(b)))
2136 }
2137 rule ConditionalOrExpression_item() -> Expression = e:ConditionalAndExpression() _ { e }
2138
2139 rule ConditionalAndExpression() -> Expression = e:ConditionalAndExpression_item() **<1,> ("&&" _) {?
2140 not_empty_fold(e.into_iter(), |a, b| Expression::And(Box::new(a), Box::new(b)))
2141 }
2142 rule ConditionalAndExpression_item() -> Expression = e:ValueLogical() _ { e }
2143
2144 rule ValueLogical() -> Expression = RelationalExpression()
2145
2146 rule RelationalExpression() -> Expression = a:NumericExpression() _ o: RelationalExpression_inner()? { match o {
2147 Some(("=", Some(b), None)) => Expression::Equal(Box::new(a), Box::new(b)),
2148 Some(("!=", Some(b), None)) => Expression::Not(Box::new(Expression::Equal(Box::new(a), Box::new(b)))),
2149 Some((">", Some(b), None)) => Expression::Greater(Box::new(a), Box::new(b)),
2150 Some((">=", Some(b), None)) => Expression::GreaterOrEqual(Box::new(a), Box::new(b)),
2151 Some(("<", Some(b), None)) => Expression::Less(Box::new(a), Box::new(b)),
2152 Some(("<=", Some(b), None)) => Expression::LessOrEqual(Box::new(a), Box::new(b)),
2153 Some(("IN", None, Some(l))) => Expression::In(Box::new(a), l),
2154 Some(("NOT IN", None, Some(l))) => Expression::Not(Box::new(Expression::In(Box::new(a), l))),
2155 Some(_) => unreachable!(),
2156 None => a
2157 } }
2158 rule RelationalExpression_inner() -> (&'input str, Option<Expression>, Option<Vec<Expression>>) =
2159 s: $("=" / "!=" / ">=" / ">" / "<=" / "<") _ e:NumericExpression() { (s, Some(e), None) } /
2160 i("IN") _ l:ExpressionList() { ("IN", None, Some(l)) } /
2161 i("NOT") _ i("IN") _ l:ExpressionList() { ("NOT IN", None, Some(l)) }
2162
2163 rule NumericExpression() -> Expression = AdditiveExpression()
2164
2165 rule AdditiveExpression() -> Expression = a:MultiplicativeExpression() _ o:AdditiveExpression_inner()? { match o {
2166 Some(("+", b)) => Expression::Add(Box::new(a), Box::new(b)),
2167 Some(("-", b)) => Expression::Subtract(Box::new(a), Box::new(b)),
2168 Some(_) => unreachable!(),
2169 None => a,
2170 } }
2171 rule AdditiveExpression_inner() -> (&'input str, Expression) = s: $("+" / "-") _ e:AdditiveExpression() {
2172 (s, e)
2173 }
2174
2175 rule MultiplicativeExpression() -> Expression = a:UnaryExpression() _ o: MultiplicativeExpression_inner()? { match o {
2176 Some(("*", b)) => Expression::Multiply(Box::new(a), Box::new(b)),
2177 Some(("/", b)) => Expression::Divide(Box::new(a), Box::new(b)),
2178 Some(_) => unreachable!(),
2179 None => a
2180 } }
2181 rule MultiplicativeExpression_inner() -> (&'input str, Expression) = s: $("*" / "/") _ e:MultiplicativeExpression() {
2182 (s, e)
2183 }
2184
2185 rule UnaryExpression() -> Expression = s: "!" _ e:UnaryExpression() {?
2186 #[cfg(feature = "sparql-12")]{Ok(Expression::Not(Box::new(e)))}
2187 #[cfg(not(feature = "sparql-12"))]{Err("Double negation (!!) is only available in SPARQL 1.2")}
2188 } / s: $("!" / "+" / "-")? _ e:PrimaryExpression() { match s {
2189 Some("!") => Expression::Not(Box::new(e)),
2190 Some("+") => Expression::UnaryPlus(Box::new(e)),
2191 Some("-") => Expression::UnaryMinus(Box::new(e)),
2192 Some(_) => unreachable!(),
2193 None => e,
2194 } }
2195
2196 rule PrimaryExpression() -> Expression =
2197 BrackettedExpression() /
2198 ExprTripleTerm() /
2199 iriOrFunction() /
2200 v:Var() { v.into() } /
2201 l:RDFLiteral() { l.into() } /
2202 l:NumericLiteral() { l.into() } /
2203 l:BooleanLiteral() { l.into() } /
2204 BuiltInCall()
2205
2206 rule ExprTripleTerm() -> Expression = "<<(" _ s:ExprTripleTermSubject() _ p:Verb() _ o:ExprTripleTermObject() _ ")>>" {?
2207 #[cfg(feature = "sparql-12")]{Ok(Expression::FunctionCall(Function::Triple, vec![s, p.into(), o]))}
2208 #[cfg(not(feature = "sparql-12"))]{Err("Triple terms are only available in SPARQL 1.2")}
2209 }
2210
2211 rule ExprTripleTermSubject() -> Expression = ExprTripleTermObject()
2212
2213 rule ExprTripleTermObject() -> Expression =
2214 ExprTripleTerm() /
2215 i:iri() { i.into() } /
2216 l:RDFLiteral() { l.into() } /
2217 l:NumericLiteral() { l.into() } /
2218 l:BooleanLiteral() { l.into() } /
2219 v:Var() { v.into() }
2220
2221 rule BrackettedExpression() -> Expression = "(" _ e:Expression() _ ")" { e }
2222
2223 rule BuiltInCall() -> Expression =
2224 a:Aggregate() {? state.new_aggregation(a).map(Into::into) } /
2225 i("STR") _ "(" _ e:Expression() _ ")" { Expression::FunctionCall(Function::Str, vec![e]) } /
2226 i("LANG") _ "(" _ e:Expression() _ ")" { Expression::FunctionCall(Function::Lang, vec![e]) } /
2227 i("LANGMATCHES") _ "(" _ a:Expression() _ "," _ b:Expression() _ ")" { Expression::FunctionCall(Function::LangMatches, vec![a, b]) } /
2228 i("LANGDIR") _ "(" _ e:Expression() _ ")" {?
2229 #[cfg(feature = "sparql-12")]{Ok(Expression::FunctionCall(Function::LangDir, vec![e]))}
2230 #[cfg(not(feature = "sparql-12"))]{Err("The LANGDIR function is only available in SPARQL 1.2")}
2231 } /
2232 i("DATATYPE") _ "(" _ e:Expression() _ ")" { Expression::FunctionCall(Function::Datatype, vec![e]) } /
2233 i("BOUND") _ "(" _ v:Var() _ ")" { Expression::Bound(v) } /
2234 (i("IRI") / i("URI")) _ "(" _ e:Expression() _ ")" { Expression::FunctionCall(Function::Iri, vec![e]) } /
2235 i("BNODE") _ "(" _ e:Expression() _ ")" { Expression::FunctionCall(Function::BNode, vec![e]) } /
2236 i("BNODE") NIL() { Expression::FunctionCall(Function::BNode, vec![]) } /
2237 i("RAND") _ NIL() { Expression::FunctionCall(Function::Rand, vec![]) } /
2238 i("ABS") _ "(" _ e:Expression() _ ")" { Expression::FunctionCall(Function::Abs, vec![e]) } /
2239 i("CEIL") _ "(" _ e:Expression() _ ")" { Expression::FunctionCall(Function::Ceil, vec![e]) } /
2240 i("FLOOR") _ "(" _ e:Expression() _ ")" { Expression::FunctionCall(Function::Floor, vec![e]) } /
2241 i("ROUND") _ "(" _ e:Expression() _ ")" { Expression::FunctionCall(Function::Round, vec![e]) } /
2242 i("CONCAT") e:ExpressionList() { Expression::FunctionCall(Function::Concat, e) } /
2243 SubstringExpression() /
2244 i("STRLEN") _ "(" _ e: Expression() _ ")" { Expression::FunctionCall(Function::StrLen, vec![e]) } /
2245 StrReplaceExpression() /
2246 i("UCASE") _ "(" _ e:Expression() _ ")" { Expression::FunctionCall(Function::UCase, vec![e]) } /
2247 i("LCASE") _ "(" _ e:Expression() _ ")" { Expression::FunctionCall(Function::LCase, vec![e]) } /
2248 i("ENCODE_FOR_URI") _ "(" _ e: Expression() _ ")" { Expression::FunctionCall(Function::EncodeForUri, vec![e]) } /
2249 i("CONTAINS") _ "(" _ a:Expression() _ "," _ b:Expression() _ ")" { Expression::FunctionCall(Function::Contains, vec![a, b]) } /
2250 i("STRSTARTS") _ "(" _ a:Expression() _ "," _ b:Expression() _ ")" { Expression::FunctionCall(Function::StrStarts, vec![a, b]) } /
2251 i("STRENDS") _ "(" _ a:Expression() _ "," _ b:Expression() _ ")" { Expression::FunctionCall(Function::StrEnds, vec![a, b]) } /
2252 i("STRBEFORE") _ "(" _ a:Expression() _ "," _ b:Expression() _ ")" { Expression::FunctionCall(Function::StrBefore, vec![a, b]) } /
2253 i("STRAFTER") _ "(" _ a:Expression() _ "," _ b:Expression() _ ")" { Expression::FunctionCall(Function::StrAfter, vec![a, b]) } /
2254 i("YEAR") _ "(" _ e:Expression() _ ")" { Expression::FunctionCall(Function::Year, vec![e]) } /
2255 i("MONTH") _ "(" _ e:Expression() _ ")" { Expression::FunctionCall(Function::Month, vec![e]) } /
2256 i("DAY") _ "(" _ e:Expression() _ ")" { Expression::FunctionCall(Function::Day, vec![e]) } /
2257 i("HOURS") _ "(" _ e:Expression() _ ")" { Expression::FunctionCall(Function::Hours, vec![e]) } /
2258 i("MINUTES") _ "(" _ e:Expression() _ ")" { Expression::FunctionCall(Function::Minutes, vec![e]) } /
2259 i("SECONDS") _ "(" _ e:Expression() _ ")" { Expression::FunctionCall(Function::Seconds, vec![e]) } /
2260 i("TIMEZONE") _ "(" _ e:Expression() _ ")" { Expression::FunctionCall(Function::Timezone, vec![e]) } /
2261 i("TZ") _ "(" _ e:Expression() _ ")" { Expression::FunctionCall(Function::Tz, vec![e]) } /
2262 i("NOW") _ NIL() { Expression::FunctionCall(Function::Now, vec![]) } /
2263 i("UUID") _ NIL() { Expression::FunctionCall(Function::Uuid, vec![]) }/
2264 i("STRUUID") _ NIL() { Expression::FunctionCall(Function::StrUuid, vec![]) } /
2265 i("MD5") _ "(" _ e:Expression() _ ")" { Expression::FunctionCall(Function::Md5, vec![e]) } /
2266 i("SHA1") _ "(" _ e:Expression() _ ")" { Expression::FunctionCall(Function::Sha1, vec![e]) } /
2267 i("SHA256") _ "(" _ e:Expression() _ ")" { Expression::FunctionCall(Function::Sha256, vec![e]) } /
2268 i("SHA384") _ "(" _ e:Expression() _ ")" { Expression::FunctionCall(Function::Sha384, vec![e]) } /
2269 i("SHA512") _ "(" _ e:Expression() _ ")" { Expression::FunctionCall(Function::Sha512, vec![e]) } /
2270 i("COALESCE") e:ExpressionList() { Expression::Coalesce(e) } /
2271 i("IF") _ "(" _ a:Expression() _ "," _ b:Expression() _ "," _ c:Expression() _ ")" { Expression::If(Box::new(a), Box::new(b), Box::new(c)) } /
2272 i("STRLANG") _ "(" _ a:Expression() _ "," _ b:Expression() _ ")" { Expression::FunctionCall(Function::StrLang, vec![a, b]) } /
2273 i("STRLANGDIR") _ "(" _ a:Expression() _ "," _ b:Expression() _ "," _ c:Expression() _ ")" {?
2274 #[cfg(feature = "sparql-12")]{Ok(Expression::FunctionCall(Function::StrLangDir, vec![a, b, c]))}
2275 #[cfg(not(feature = "sparql-12"))]{Err("The STRLANGDIR function is only available in SPARQL 1.2")}
2276 } /
2277 i("STRDT") _ "(" _ a:Expression() _ "," _ b:Expression() _ ")" { Expression::FunctionCall(Function::StrDt, vec![a, b]) } /
2278 i("sameTerm") _ "(" _ a:Expression() _ "," _ b:Expression() _ ")" { Expression::SameTerm(Box::new(a), Box::new(b)) } /
2279 (i("isIRI") / i("isURI")) _ "(" _ e:Expression() _ ")" { Expression::FunctionCall(Function::IsIri, vec![e]) } /
2280 i("isBLANK") _ "(" _ e:Expression() _ ")" { Expression::FunctionCall(Function::IsBlank, vec![e]) } /
2281 i("isLITERAL") _ "(" _ e:Expression() _ ")" { Expression::FunctionCall(Function::IsLiteral, vec![e]) } /
2282 i("isNUMERIC") _ "(" _ e:Expression() _ ")" { Expression::FunctionCall(Function::IsNumeric, vec![e]) } /
2283 i("hasLang") _ "(" _ e:Expression() _ ")" {?
2284 #[cfg(feature = "sparql-12")]{Ok(Expression::FunctionCall(Function::HasLang, vec![e]))}
2285 #[cfg(not(feature = "sparql-12"))]{Err("The hasLang function is only available in SPARQL 1.2")}
2286 } /
2287 i("hasLangDir") _ "(" _ e:Expression() _ ")" {?
2288 #[cfg(feature = "sparql-12")]{Ok(Expression::FunctionCall(Function::HasLangDir, vec![e]))}
2289 #[cfg(not(feature = "sparql-12"))]{Err("The hasLangDir function is only available in SPARQL 1.2")}
2290 } /
2291 RegexExpression() /
2292 ExistsFunc() /
2293 NotExistsFunc() /
2294 i("TRIPLE") _ "(" _ s:Expression() _ "," _ p:Expression() "," _ o:Expression() ")" {?
2295 #[cfg(feature = "sparql-12")]{Ok(Expression::FunctionCall(Function::Triple, vec![s, p, o]))}
2296 #[cfg(not(feature = "sparql-12"))]{Err("The TRIPLE function is only available in SPARQL 1.2")}
2297 } /
2298 i("SUBJECT") _ "(" _ e:Expression() _ ")" {?
2299 #[cfg(feature = "sparql-12")]{Ok(Expression::FunctionCall(Function::Subject, vec![e]))}
2300 #[cfg(not(feature = "sparql-12"))]{Err("The SUBJECT function is only available in SPARQL 1.2")}
2301 } /
2302 i("PREDICATE") _ "(" _ e:Expression() _ ")" {?
2303 #[cfg(feature = "sparql-12")]{Ok(Expression::FunctionCall(Function::Predicate, vec![e]))}
2304 #[cfg(not(feature = "sparql-12"))]{Err("The PREDICATE function is only available in SPARQL 1.2")}
2305 } /
2306 i("OBJECT") _ "(" _ e:Expression() _ ")" {?
2307 #[cfg(feature = "sparql-12")]{Ok(Expression::FunctionCall(Function::Object, vec![e]))}
2308 #[cfg(not(feature = "sparql-12"))]{Err("The OBJECT function is only available in SPARQL 1.2")}
2309 } /
2310 i("isTriple") _ "(" _ e:Expression() _ ")" {?
2311 #[cfg(feature = "sparql-12")]{Ok(Expression::FunctionCall(Function::IsTriple, vec![e]))}
2312 #[cfg(not(feature = "sparql-12"))]{Err("The isTriple function is only available in SPARQL 1.2")}
2313 } /
2314 i("ADJUST") _ "(" _ a:Expression() _ "," _ b:Expression() _ ")" {?
2315 #[cfg(feature = "sep-0002")]{Ok(Expression::FunctionCall(Function::Adjust, vec![a, b]))}
2316 #[cfg(not(feature = "sep-0002"))]{Err("The ADJUST function is only available in SPARQL-dev SEP 0002")}
2317 }
2318
2319 rule RegexExpression() -> Expression =
2320 i("REGEX") _ "(" _ a:Expression() _ "," _ b:Expression() _ "," _ c:Expression() _ ")" { Expression::FunctionCall(Function::Regex, vec![a, b, c]) } /
2321 i("REGEX") _ "(" _ a:Expression() _ "," _ b:Expression() _ ")" { Expression::FunctionCall(Function::Regex, vec![a, b]) }
2322
2323
2324 rule SubstringExpression() -> Expression =
2325 i("SUBSTR") _ "(" _ a:Expression() _ "," _ b:Expression() _ "," _ c:Expression() _ ")" { Expression::FunctionCall(Function::SubStr, vec![a, b, c]) } /
2326 i("SUBSTR") _ "(" _ a:Expression() _ "," _ b:Expression() _ ")" { Expression::FunctionCall(Function::SubStr, vec![a, b]) }
2327
2328
2329 rule StrReplaceExpression() -> Expression =
2330 i("REPLACE") _ "(" _ a:Expression() _ "," _ b:Expression() _ "," _ c:Expression() _ "," _ d:Expression() _ ")" { Expression::FunctionCall(Function::Replace, vec![a, b, c, d]) } /
2331 i("REPLACE") _ "(" _ a:Expression() _ "," _ b:Expression() _ "," _ c:Expression() _ ")" { Expression::FunctionCall(Function::Replace, vec![a, b, c]) }
2332
2333 rule ExistsFunc() -> Expression = i("EXISTS") _ p:GroupGraphPattern() { Expression::Exists(Box::new(p)) }
2334
2335 rule NotExistsFunc() -> Expression = i("NOT") _ i("EXISTS") _ p:GroupGraphPattern() { Expression::Not(Box::new(Expression::Exists(Box::new(p)))) }
2336
2337 rule Aggregate() -> AggregateExpression =
2338 i("COUNT") _ "(" _ i("DISTINCT") _ "*" _ ")" { AggregateExpression::CountSolutions { distinct: true } } /
2339 i("COUNT") _ "(" _ i("DISTINCT") _ expr:Expression() _ ")" { AggregateExpression::FunctionCall { name: AggregateFunction::Count, expr, distinct: true } } /
2340 i("COUNT") _ "(" _ "*" _ ")" { AggregateExpression::CountSolutions { distinct: false } } /
2341 i("COUNT") _ "(" _ expr:Expression() _ ")" { AggregateExpression::FunctionCall { name: AggregateFunction::Count, expr, distinct: false } } /
2342 i("SUM") _ "(" _ i("DISTINCT") _ expr:Expression() _ ")" { AggregateExpression::FunctionCall { name: AggregateFunction::Sum, expr, distinct: true } } /
2343 i("SUM") _ "(" _ expr:Expression() _ ")" { AggregateExpression::FunctionCall { name: AggregateFunction::Sum, expr, distinct: false } } /
2344 i("MIN") _ "(" _ i("DISTINCT") _ expr:Expression() _ ")" { AggregateExpression::FunctionCall { name: AggregateFunction::Min, expr, distinct: true } } /
2345 i("MIN") _ "(" _ expr:Expression() _ ")" { AggregateExpression::FunctionCall { name: AggregateFunction::Min, expr, distinct: false } } /
2346 i("MAX") _ "(" _ i("DISTINCT") _ expr:Expression() _ ")" { AggregateExpression::FunctionCall { name: AggregateFunction::Max, expr, distinct: true } } /
2347 i("MAX") _ "(" _ expr:Expression() _ ")" { AggregateExpression::FunctionCall { name: AggregateFunction::Max, expr, distinct: false } } /
2348 i("AVG") _ "(" _ i("DISTINCT") _ expr:Expression() _ ")" { AggregateExpression::FunctionCall { name: AggregateFunction::Avg, expr, distinct: true } } /
2349 i("AVG") _ "(" _ expr:Expression() _ ")" { AggregateExpression::FunctionCall { name: AggregateFunction::Avg, expr, distinct: false } } /
2350 i("SAMPLE") _ "(" _ i("DISTINCT") _ expr:Expression() _ ")" { AggregateExpression::FunctionCall { name: AggregateFunction::Sample, expr, distinct: true } } /
2351 i("SAMPLE") _ "(" _ expr:Expression() _ ")" { AggregateExpression::FunctionCall { name: AggregateFunction::Sample, expr, distinct: false } } /
2352 i("GROUP_CONCAT") _ "(" _ i("DISTINCT") _ expr:Expression() _ ";" _ i("SEPARATOR") _ "=" _ s:String() _ ")" { AggregateExpression::FunctionCall { name: AggregateFunction::GroupConcat { separator: Some(s) }, expr, distinct: true } } /
2353 i("GROUP_CONCAT") _ "(" _ i("DISTINCT") _ expr:Expression() _ ")" { AggregateExpression::FunctionCall { name: AggregateFunction::GroupConcat { separator: None }, expr, distinct: true } } /
2354 i("GROUP_CONCAT") _ "(" _ expr:Expression() _ ";" _ i("SEPARATOR") _ "=" _ s:String() _ ")" { AggregateExpression::FunctionCall { name: AggregateFunction::GroupConcat { separator: Some(s) }, expr, distinct: false } } /
2355 i("GROUP_CONCAT") _ "(" _ expr:Expression() _ ")" { AggregateExpression::FunctionCall { name: AggregateFunction::GroupConcat { separator: None }, expr, distinct: false } } /
2356 name:iri() _ "(" _ i("DISTINCT") _ expr:Expression() _ ")" {?
2357 if state.custom_aggregate_functions.contains(&name) {
2358 Ok(AggregateExpression::FunctionCall { name: AggregateFunction::Custom(name), expr, distinct: true })
2359 } else {
2360 Err("This custom function is a regular function and not an aggregate function")
2361 }
2362 } /
2363 name:iri() _ "(" _ expr:Expression() _ ")" {?
2364 if state.custom_aggregate_functions.contains(&name) {
2365 Ok(AggregateExpression::FunctionCall { name: AggregateFunction::Custom(name), expr, distinct: false })
2366 } else {
2367 Err("This custom function is a regular function and not an aggregate function")
2368 }
2369 }
2370
2371 rule iriOrFunction() -> Expression = i: iri() _ a: ArgList()? {?
2372 if let Some(a) = a {
2373 if state.custom_aggregate_functions.contains(&i) {
2374 Err("This custom function is an aggregate function and not a regular function")
2375 } else {
2376 Ok(Expression::FunctionCall(Function::Custom(i), a))
2377 }
2378 } else {
2379 Ok(i.into())
2380 }
2381 }
2382
2383 rule RDFLiteral() -> Literal =
2384 value:String() _ "^^" _ datatype:iri() { Literal::new_typed_literal(value, datatype) } /
2385 value:String() _ language_and_direction:LANGDIR() {?
2386 let (language, direction) = language_and_direction;
2387 #[cfg(feature = "sparql-12")]
2388 if let Some(is_ltr) = direction {
2389 return Ok(Literal::new_directional_language_tagged_literal_unchecked(value, language.into_inner(), if is_ltr { oxrdf::BaseDirection::Ltr } else { oxrdf::BaseDirection::Rtl }))
2390 }
2391 #[cfg(not(feature = "sparql-12"))]
2392 if direction.is_some() {
2393 return Err("Literal base directions are only supported in SPARQL 1.2")
2394 }
2395 Ok(Literal::new_language_tagged_literal_unchecked(value, language.into_inner()))
2396 } /
2397 value:String() { Literal::new_simple_literal(value) }
2398
2399 rule NumericLiteral() -> Literal = NumericLiteralUnsigned() / NumericLiteralPositive() / NumericLiteralNegative()
2400
2401 rule NumericLiteralUnsigned() -> Literal =
2402 d:$(DOUBLE()) { Literal::new_typed_literal(d, xsd::DOUBLE) } /
2403 d:$(DECIMAL()) { Literal::new_typed_literal(d, xsd::DECIMAL) } /
2404 i:$(INTEGER()) { Literal::new_typed_literal(i, xsd::INTEGER) }
2405
2406 rule NumericLiteralPositive() -> Literal =
2407 d:$(DOUBLE_POSITIVE()) { Literal::new_typed_literal(d, xsd::DOUBLE) } /
2408 d:$(DECIMAL_POSITIVE()) { Literal::new_typed_literal(d, xsd::DECIMAL) } /
2409 i:$(INTEGER_POSITIVE()) { Literal::new_typed_literal(i, xsd::INTEGER) }
2410
2411
2412 rule NumericLiteralNegative() -> Literal =
2413 d:$(DOUBLE_NEGATIVE()) { Literal::new_typed_literal(d, xsd::DOUBLE) } /
2414 d:$(DECIMAL_NEGATIVE()) { Literal::new_typed_literal(d, xsd::DECIMAL) } /
2415 i:$(INTEGER_NEGATIVE()) { Literal::new_typed_literal(i, xsd::INTEGER) }
2416
2417 rule BooleanLiteral() -> Literal =
2418 "true" { Literal::new_typed_literal("true", xsd::BOOLEAN) } /
2419 "false" { Literal::new_typed_literal("false", xsd::BOOLEAN) }
2420
2421 rule String() -> String = STRING_LITERAL_LONG1() / STRING_LITERAL_LONG2() / STRING_LITERAL1() / STRING_LITERAL2()
2422
2423 rule iri() -> NamedNode = i:(IRIREF() / PrefixedName()) {
2424 NamedNode::from(i)
2425 }
2426
2427 rule PrefixedName() -> Iri<String> = PNAME_LN() /
2428 ns:PNAME_NS() {? if let Some(iri) = state.prefixes.get(ns).cloned() {
2429 Iri::parse(iri).map_err(|_| "prefix IRI parsing failed")
2430 } else {
2431 Err("Prefix not found")
2432 } }
2433
2434 rule BlankNode() -> BlankNode = id:BLANK_NODE_LABEL() {?
2435 let node = BlankNode::new_unchecked(id);
2436 if state.used_bnodes.contains(&node) {
2437 Err("Already used blank node id")
2438 } else {
2439 state.currently_used_bnodes.insert(node.clone());
2440 Ok(node)
2441 }
2442 } / ANON() { BlankNode::default() }
2443
2444 rule IRIREF() -> Iri<String> = "<" i:$((!['>'] [_])*) ">" {?
2445 state.parse_iri(unescape_iriref(i)?).map_err(|_| "IRI parsing failed")
2446 }
2447
2448 rule PNAME_NS() -> &'input str = ns:$(PN_PREFIX()?) ":" {
2449 ns
2450 }
2451
2452 rule PNAME_LN() -> Iri<String> = ns:PNAME_NS() local:$(PN_LOCAL()) {?
2453 if let Some(base) = state.prefixes.get(ns) {
2454 let mut iri = String::with_capacity(base.len() + local.len());
2455 iri.push_str(base);
2456 for chunk in local.split('\\') { iri.push_str(chunk);
2458 }
2459 Iri::parse(iri).map_err(|_| "IRI parsing failed")
2460 } else {
2461 Err("Prefix not found")
2462 }
2463 }
2464
2465 rule BLANK_NODE_LABEL() -> &'input str = "_:" b:$((['0'..='9'] / PN_CHARS_U()) PN_CHARS()* ("."+ PN_CHARS()+)*) {
2466 b
2467 }
2468
2469 rule VAR1() -> &'input str = "?" v:$(VARNAME()) { v }
2470
2471 rule VAR2() -> &'input str = "$" v:$(VARNAME()) { v }
2472
2473 rule LANGDIR() -> (LanguageTag<String>, Option<bool>) = "@" l:$(['a' ..= 'z' | 'A' ..= 'Z']+ ("-" ['a' ..= 'z' | 'A' ..= 'Z' | '0' ..= '9']+)*) d:$("--" ['a' ..= 'z' | 'A' ..= 'Z']+)? {?
2474 Ok((
2475 LanguageTag::parse(l.to_ascii_lowercase()).map_err(|_| "language tag parsing failed")?,
2476 d.map(|d| match d {
2477 "--ltr" => Ok(true),
2478 "--rtl" => Ok(false),
2479 _ => Err("the only base directions allowed are 'rtl' and 'ltr'")
2480 }).transpose()?
2481 ))
2482 }
2483
2484 rule INTEGER() = ['0'..='9']+
2485
2486 rule DECIMAL() = ['0'..='9']* "." ['0'..='9']+
2487
2488 rule DOUBLE() = (['0'..='9']+ "." ['0'..='9']* / "." ['0'..='9']+ / ['0'..='9']+) EXPONENT()
2489
2490 rule INTEGER_POSITIVE() = "+" _ INTEGER()
2491
2492 rule DECIMAL_POSITIVE() = "+" _ DECIMAL()
2493
2494 rule DOUBLE_POSITIVE() = "+" _ DOUBLE()
2495
2496 rule INTEGER_NEGATIVE() = "-" _ INTEGER()
2497
2498 rule DECIMAL_NEGATIVE() = "-" _ DECIMAL()
2499
2500 rule DOUBLE_NEGATIVE() = "-" _ DOUBLE()
2501
2502 rule EXPONENT() = ['e' | 'E'] ['+' | '-']? ['0'..='9']+
2503
2504 rule STRING_LITERAL1() -> String = "'" l:$((STRING_LITERAL1_simple_char() / ECHAR() / UCHAR())*) "'" {?
2505 unescape_string(l)
2506 }
2507 rule STRING_LITERAL1_simple_char() = !['\u{27}' | '\u{5C}' | '\u{0A}' | '\u{0D}'] [_]
2508
2509
2510 rule STRING_LITERAL2() -> String = "\"" l:$((STRING_LITERAL2_simple_char() / ECHAR() / UCHAR())*) "\"" {?
2511 unescape_string(l)
2512 }
2513 rule STRING_LITERAL2_simple_char() = !['\u{22}' | '\u{5C}' | '\u{0A}' | '\u{0D}'] [_]
2514
2515 rule STRING_LITERAL_LONG1() -> String = "'''" l:$(STRING_LITERAL_LONG1_inner()*) "'''" {?
2516 unescape_string(l)
2517 }
2518 rule STRING_LITERAL_LONG1_inner() = ("''" / "'")? (STRING_LITERAL_LONG1_simple_char() / ECHAR() / UCHAR())
2519 rule STRING_LITERAL_LONG1_simple_char() = !['\'' | '\\'] [_]
2520
2521 rule STRING_LITERAL_LONG2() -> String = "\"\"\"" l:$(STRING_LITERAL_LONG2_inner()*) "\"\"\"" {?
2522 unescape_string(l)
2523 }
2524 rule STRING_LITERAL_LONG2_inner() = ("\"\"" / "\"")? (STRING_LITERAL_LONG2_simple_char() / ECHAR() / UCHAR())
2525 rule STRING_LITERAL_LONG2_simple_char() = !['"' | '\\'] [_]
2526
2527 rule UCHAR() = "\\u" HEX() HEX() HEX() HEX() / "\\U" HEX() HEX() HEX() HEX() HEX() HEX() HEX() HEX()
2528
2529 rule ECHAR() = "\\" ['t' | 'b' | 'n' | 'r' | 'f' | '"' |'\'' | '\\']
2530
2531 rule NIL() = "(" WS()* ")"
2532
2533 rule WS() = quiet! { ['\u{20}' | '\u{09}' | '\u{0D}' | '\u{0A}'] }
2534
2535 rule ANON() = "[" WS()* "]"
2536
2537 rule PN_CHARS_BASE() = ['A' ..= 'Z' | 'a' ..= 'z' | '\u{00C0}'..='\u{00D6}' | '\u{00D8}'..='\u{00F6}' | '\u{00F8}'..='\u{02FF}' | '\u{0370}'..='\u{037D}' | '\u{037F}'..='\u{1FFF}' | '\u{200C}'..='\u{200D}' | '\u{2070}'..='\u{218F}' | '\u{2C00}'..='\u{2FEF}' | '\u{3001}'..='\u{D7FF}' | '\u{F900}'..='\u{FDCF}' | '\u{FDF0}'..='\u{FFFD}']
2538
2539 rule PN_CHARS_U() = ['_'] / PN_CHARS_BASE()
2540
2541 rule VARNAME() = (['0'..='9'] / PN_CHARS_U()) (['0' ..= '9' | '\u{00B7}' | '\u{0300}'..='\u{036F}' | '\u{203F}'..='\u{2040}'] / PN_CHARS_U())*
2542
2543 rule PN_CHARS() = ['-' | '0' ..= '9' | '\u{00B7}' | '\u{0300}'..='\u{036F}' | '\u{203F}'..='\u{2040}'] / PN_CHARS_U()
2544
2545 rule PN_PREFIX() = PN_CHARS_BASE() PN_CHARS()* ("."+ PN_CHARS()+)*
2546
2547 rule PN_LOCAL() = (PN_CHARS_U() / [':' | '0'..='9'] / PLX()) (PN_CHARS() / [':'] / PLX())* (['.']+ (PN_CHARS() / [':'] / PLX())+)?
2548
2549 rule PLX() = PERCENT() / PN_LOCAL_ESC()
2550
2551 rule PERCENT() = ['%'] HEX() HEX()
2552
2553 rule HEX() = ['0' ..= '9' | 'A' ..= 'F' | 'a' ..= 'f']
2554
2555 rule PN_LOCAL_ESC() = ['\\'] ['_' | '~' | '.' | '-' | '!' | '$' | '&' | '\'' | '(' | ')' | '*' | '+' | ',' | ';' | '=' | '/' | '?' | '#' | '@' | '%']
2556
2557 rule _() = quiet! { ([' ' | '\t' | '\n' | '\r'] / comment())* }
2559
2560 rule comment() = quiet! { ['#'] (!['\r' | '\n'] [_])* }
2562
2563 rule i(literal: &'static str) = input: $([_]*<{literal.len()}>) {?
2564 if input.eq_ignore_ascii_case(literal) {
2565 Ok(())
2566 } else {
2567 Err(literal)
2568 }
2569 }
2570 }
2571}