Forbids variables in property path

Allows BGP to contain TriplePattern
pull/10/head
Tpt 7 years ago
parent 028910b77c
commit 257cd08846
  1. 218
      src/sparql/algebra.rs
  2. 31
      src/sparql/parser.rs
  3. 67
      src/sparql/sparql_grammar.rustpeg

@ -7,7 +7,7 @@ use utils::Escaper;
#[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Hash)] #[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Hash)]
pub enum PropertyPath { pub enum PropertyPath {
PredicatePath(NamedNodeOrVariable), //TODO: restrict to NamedNode PredicatePath(NamedNode),
InversePath(Box<PropertyPath>), InversePath(Box<PropertyPath>),
SequencePath(Box<PropertyPath>, Box<PropertyPath>), SequencePath(Box<PropertyPath>, Box<PropertyPath>),
AlternativePath(Box<PropertyPath>, Box<PropertyPath>), AlternativePath(Box<PropertyPath>, Box<PropertyPath>),
@ -20,7 +20,7 @@ pub enum PropertyPath {
impl fmt::Display for PropertyPath { impl fmt::Display for PropertyPath {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self { match self {
PropertyPath::PredicatePath(p) => write!(f, "{}", p), PropertyPath::PredicatePath(p) => write!(f, "link({})", p),
PropertyPath::InversePath(p) => write!(f, "inv({})", p), PropertyPath::InversePath(p) => write!(f, "inv({})", p),
PropertyPath::AlternativePath(a, b) => write!(f, "alt({}, {})", a, b), PropertyPath::AlternativePath(a, b) => write!(f, "alt({}, {})", a, b),
PropertyPath::SequencePath(a, b) => write!(f, "seq({}, {})", a, b), PropertyPath::SequencePath(a, b) => write!(f, "seq({}, {})", a, b),
@ -73,38 +73,26 @@ impl<'a> fmt::Display for SparqlPropertyPath<'a> {
} }
} }
impl From<NamedNodeOrVariable> for PropertyPath {
fn from(p: NamedNodeOrVariable) -> Self {
PropertyPath::PredicatePath(p)
}
}
impl From<NamedNode> for PropertyPath { impl From<NamedNode> for PropertyPath {
fn from(p: NamedNode) -> Self { fn from(p: NamedNode) -> Self {
PropertyPath::PredicatePath(p.into()) PropertyPath::PredicatePath(p.into())
} }
} }
impl From<Variable> for PropertyPath {
fn from(p: Variable) -> Self {
PropertyPath::PredicatePath(p.into())
}
}
#[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Hash)] #[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Hash)]
pub struct PropertyPathPattern { pub struct PathPattern {
pub subject: TermOrVariable, pub subject: TermOrVariable,
pub path: PropertyPath, pub path: PropertyPath,
pub object: TermOrVariable, pub object: TermOrVariable,
} }
impl fmt::Display for PropertyPathPattern { impl fmt::Display for PathPattern {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{} {} {}", self.subject, self.path, self.object) write!(f, "Path({} {} {})", self.subject, self.path, self.object)
} }
} }
impl PropertyPathPattern { impl PathPattern {
pub fn new( pub fn new(
subject: impl Into<TermOrVariable>, subject: impl Into<TermOrVariable>,
path: impl Into<PropertyPath>, path: impl Into<PropertyPath>,
@ -118,19 +106,9 @@ impl PropertyPathPattern {
} }
} }
impl From<TriplePattern> for PropertyPathPattern { struct SparqlPathPattern<'a>(&'a PathPattern);
fn from(p: TriplePattern) -> Self {
Self {
subject: p.subject,
path: p.predicate.into(),
object: p.object,
}
}
}
struct SparqlPropertyPathPattern<'a>(&'a PropertyPathPattern);
impl<'a> fmt::Display for SparqlPropertyPathPattern<'a> { impl<'a> fmt::Display for SparqlPathPattern<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!( write!(
f, f,
@ -142,6 +120,44 @@ impl<'a> fmt::Display for SparqlPropertyPathPattern<'a> {
} }
} }
#[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Hash)]
pub enum TripleOrPathPattern {
Triple(TriplePattern),
Path(PathPattern),
}
impl<'a> fmt::Display for TripleOrPathPattern {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
TripleOrPathPattern::Triple(tp) => write!(f, "{}", tp),
TripleOrPathPattern::Path(ppp) => write!(f, "{}", ppp),
}
}
}
impl From<TriplePattern> for TripleOrPathPattern {
fn from(tp: TriplePattern) -> Self {
TripleOrPathPattern::Triple(tp)
}
}
impl From<PathPattern> for TripleOrPathPattern {
fn from(ppp: PathPattern) -> Self {
TripleOrPathPattern::Path(ppp)
}
}
struct SparqlTripleOrPathPattern<'a>(&'a TripleOrPathPattern);
impl<'a> fmt::Display for SparqlTripleOrPathPattern<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self.0 {
TripleOrPathPattern::Triple(tp) => write!(f, "{}", tp),
TripleOrPathPattern::Path(ppp) => write!(f, "{}", SparqlPathPattern(&ppp)),
}
}
}
#[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Hash)] #[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Hash)]
pub enum Expression { pub enum Expression {
ConstantExpression(TermOrVariable), ConstantExpression(TermOrVariable),
@ -750,7 +766,7 @@ impl<'a> fmt::Display for SparqlExpression<'a> {
#[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Hash)] #[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Hash)]
pub enum MultiSetPattern { pub enum MultiSetPattern {
BGP(Vec<PropertyPathPattern>), BGP(Vec<TripleOrPathPattern>),
Join(Box<MultiSetPattern>, Box<MultiSetPattern>), Join(Box<MultiSetPattern>, Box<MultiSetPattern>),
LeftJoin(Box<MultiSetPattern>, Box<MultiSetPattern>, Expression), LeftJoin(Box<MultiSetPattern>, Box<MultiSetPattern>, Expression),
Filter(Expression, Box<MultiSetPattern>), Filter(Expression, Box<MultiSetPattern>),
@ -792,8 +808,8 @@ impl Default for MultiSetPattern {
} }
} }
impl From<PropertyPathPattern> for MultiSetPattern { impl From<TripleOrPathPattern> for MultiSetPattern {
fn from(p: PropertyPathPattern) -> Self { fn from(p: TripleOrPathPattern) -> Self {
MultiSetPattern::BGP(vec![p]) MultiSetPattern::BGP(vec![p])
} }
} }
@ -818,12 +834,26 @@ impl MultiSetPattern {
match self { match self {
MultiSetPattern::BGP(p) => { MultiSetPattern::BGP(p) => {
for pattern in p { for pattern in p {
if let TermOrVariable::Variable(ref s) = pattern.subject { match pattern {
vars.insert(s); TripleOrPathPattern::Triple(tp) => {
} if let TermOrVariable::Variable(ref s) = tp.subject {
//TODO: pred vars.insert(s);
if let TermOrVariable::Variable(ref o) = pattern.object { }
vars.insert(o); if let NamedNodeOrVariable::Variable(ref p) = tp.predicate {
vars.insert(p);
}
if let TermOrVariable::Variable(ref o) = tp.object {
vars.insert(o);
}
}
TripleOrPathPattern::Path(ppp) => {
if let TermOrVariable::Variable(ref s) = ppp.subject {
vars.insert(s);
}
if let TermOrVariable::Variable(ref o) = ppp.object {
vars.insert(o);
}
}
} }
} }
} }
@ -865,7 +895,7 @@ impl<'a> fmt::Display for SparqlMultiSetPattern<'a> {
f, f,
"{}", "{}",
p.iter() p.iter()
.map(|v| SparqlPropertyPathPattern(v).to_string()) .map(|v| SparqlTripleOrPathPattern(v).to_string())
.collect::<Vec<String>>() .collect::<Vec<String>>()
.join(" . ") .join(" . ")
) )
@ -1318,12 +1348,12 @@ impl fmt::Display for Query {
#[test] #[test]
fn test_sparql_algebra_examples() { fn test_sparql_algebra_examples() {
assert_eq!( assert_eq!(
ast::GraphPattern::PropertyPathPattern(ast::PropertyPathPattern::new( ast::GraphPattern::PathPattern(ast::PathPattern::new(
Variable::new("s"), Variable::new("s"),
Variable::new("p"), Variable::new("p"),
Variable::new("o") Variable::new("o")
)).try_into(), )).try_into(),
Ok(GraphPattern::BGP(vec![PropertyPathPattern::new( Ok(GraphPattern::BGP(vec![PathPattern::new(
Variable::new("s"), Variable::new("s"),
Variable::new("p"), Variable::new("p"),
Variable::new("o"), Variable::new("o"),
@ -1332,43 +1362,43 @@ fn test_sparql_algebra_examples() {
assert_eq!( assert_eq!(
ast::GraphPattern::GroupPattern(vec![ ast::GraphPattern::GroupPattern(vec![
ast::GraphPattern::PropertyPathPattern(ast::PropertyPathPattern::new( ast::GraphPattern::PathPattern(ast::PathPattern::new(
Variable::new("s"), Variable::new("s"),
Variable::new("p1"), Variable::new("p1"),
Variable::new("v1"), Variable::new("v1"),
)), )),
ast::GraphPattern::PropertyPathPattern(ast::PropertyPathPattern::new( ast::GraphPattern::PathPattern(ast::PathPattern::new(
Variable::new("s"), Variable::new("s"),
Variable::new("p2"), Variable::new("p2"),
Variable::new("v2"), Variable::new("v2"),
)), )),
]).try_into(), ]).try_into(),
Ok(GraphPattern::BGP(vec![ Ok(GraphPattern::BGP(vec![
PropertyPathPattern::new(Variable::new("s"), Variable::new("p1"), Variable::new("v1")), PathPattern::new(Variable::new("s"), Variable::new("p1"), Variable::new("v1")),
PropertyPathPattern::new(Variable::new("s"), Variable::new("p2"), Variable::new("v2")), PathPattern::new(Variable::new("s"), Variable::new("p2"), Variable::new("v2")),
])) ]))
); );
assert_eq!( assert_eq!(
ast::GraphPattern::UnionPattern(vec![ ast::GraphPattern::UnionPattern(vec![
ast::GraphPattern::PropertyPathPattern(ast::PropertyPathPattern::new( ast::GraphPattern::PathPattern(ast::PathPattern::new(
Variable::new("s"), Variable::new("s"),
Variable::new("p1"), Variable::new("p1"),
Variable::new("v1"), Variable::new("v1"),
)), )),
ast::GraphPattern::PropertyPathPattern(ast::PropertyPathPattern::new( ast::GraphPattern::PathPattern(ast::PathPattern::new(
Variable::new("s"), Variable::new("s"),
Variable::new("p2"), Variable::new("p2"),
Variable::new("v2"), Variable::new("v2"),
)), )),
]).try_into(), ]).try_into(),
Ok(GraphPattern::Union( Ok(GraphPattern::Union(
Box::new(GraphPattern::BGP(vec![PropertyPathPattern::new( Box::new(GraphPattern::BGP(vec![PathPattern::new(
Variable::new("s"), Variable::new("s"),
Variable::new("p1"), Variable::new("p1"),
Variable::new("v1"), Variable::new("v1"),
)])), )])),
Box::new(GraphPattern::BGP(vec![PropertyPathPattern::new( Box::new(GraphPattern::BGP(vec![PathPattern::new(
Variable::new("s"), Variable::new("s"),
Variable::new("p2"), Variable::new("p2"),
Variable::new("v2"), Variable::new("v2"),
@ -1378,17 +1408,17 @@ fn test_sparql_algebra_examples() {
assert_eq!( assert_eq!(
ast::GraphPattern::UnionPattern(vec![ ast::GraphPattern::UnionPattern(vec![
ast::GraphPattern::PropertyPathPattern(ast::PropertyPathPattern::new( ast::GraphPattern::PathPattern(ast::PathPattern::new(
Variable::new("s"), Variable::new("s"),
Variable::new("p1"), Variable::new("p1"),
Variable::new("v1"), Variable::new("v1"),
)), )),
ast::GraphPattern::PropertyPathPattern(ast::PropertyPathPattern::new( ast::GraphPattern::PathPattern(ast::PathPattern::new(
Variable::new("s"), Variable::new("s"),
Variable::new("p2"), Variable::new("p2"),
Variable::new("v2"), Variable::new("v2"),
)), )),
ast::GraphPattern::PropertyPathPattern(ast::PropertyPathPattern::new( ast::GraphPattern::PathPattern(ast::PathPattern::new(
Variable::new("s"), Variable::new("s"),
Variable::new("p3"), Variable::new("p3"),
Variable::new("v3"), Variable::new("v3"),
@ -1396,18 +1426,18 @@ fn test_sparql_algebra_examples() {
]).try_into(), ]).try_into(),
Ok(GraphPattern::Union( Ok(GraphPattern::Union(
Box::new(GraphPattern::Union( Box::new(GraphPattern::Union(
Box::new(GraphPattern::BGP(vec![PropertyPathPattern::new( Box::new(GraphPattern::BGP(vec![PathPattern::new(
Variable::new("s"), Variable::new("s"),
Variable::new("p1"), Variable::new("p1"),
Variable::new("v1"), Variable::new("v1"),
)])), )])),
Box::new(GraphPattern::BGP(vec![PropertyPathPattern::new( Box::new(GraphPattern::BGP(vec![PathPattern::new(
Variable::new("s"), Variable::new("s"),
Variable::new("p2"), Variable::new("p2"),
Variable::new("v2"), Variable::new("v2"),
)])), )])),
)), )),
Box::new(GraphPattern::BGP(vec![PropertyPathPattern::new( Box::new(GraphPattern::BGP(vec![PathPattern::new(
Variable::new("s"), Variable::new("s"),
Variable::new("p3"), Variable::new("p3"),
Variable::new("v3"), Variable::new("v3"),
@ -1417,13 +1447,13 @@ fn test_sparql_algebra_examples() {
assert_eq!( assert_eq!(
ast::GraphPattern::GroupPattern(vec![ ast::GraphPattern::GroupPattern(vec![
ast::GraphPattern::PropertyPathPattern(ast::PropertyPathPattern::new( ast::GraphPattern::PathPattern(ast::PathPattern::new(
Variable::new("s"), Variable::new("s"),
Variable::new("p1"), Variable::new("p1"),
Variable::new("v1"), Variable::new("v1"),
)), )),
ast::GraphPattern::OptionalPattern(Box::new(ast::GraphPattern::PropertyPathPattern( ast::GraphPattern::OptionalPattern(Box::new(ast::GraphPattern::PathPattern(
ast::PropertyPathPattern::new( ast::PathPattern::new(
Variable::new("s"), Variable::new("s"),
Variable::new("p2"), Variable::new("p2"),
Variable::new("v2"), Variable::new("v2"),
@ -1431,12 +1461,12 @@ fn test_sparql_algebra_examples() {
))), ))),
]).try_into(), ]).try_into(),
Ok(GraphPattern::LeftJoin( Ok(GraphPattern::LeftJoin(
Box::new(GraphPattern::BGP(vec![PropertyPathPattern::new( Box::new(GraphPattern::BGP(vec![PathPattern::new(
Variable::new("s"), Variable::new("s"),
Variable::new("p1"), Variable::new("p1"),
Variable::new("v1"), Variable::new("v1"),
)])), )])),
Box::new(GraphPattern::BGP(vec![PropertyPathPattern::new( Box::new(GraphPattern::BGP(vec![PathPattern::new(
Variable::new("s"), Variable::new("s"),
Variable::new("p2"), Variable::new("p2"),
Variable::new("v2"), Variable::new("v2"),
@ -1447,20 +1477,20 @@ fn test_sparql_algebra_examples() {
assert_eq!( assert_eq!(
ast::GraphPattern::GroupPattern(vec![ ast::GraphPattern::GroupPattern(vec![
ast::GraphPattern::PropertyPathPattern(ast::PropertyPathPattern::new( ast::GraphPattern::PathPattern(ast::PathPattern::new(
Variable::new("s"), Variable::new("s"),
Variable::new("p1"), Variable::new("p1"),
Variable::new("v1"), Variable::new("v1"),
)), )),
ast::GraphPattern::OptionalPattern(Box::new(ast::GraphPattern::PropertyPathPattern( ast::GraphPattern::OptionalPattern(Box::new(ast::GraphPattern::PathPattern(
ast::PropertyPathPattern::new( ast::PathPattern::new(
Variable::new("s"), Variable::new("s"),
Variable::new("p2"), Variable::new("p2"),
Variable::new("v2"), Variable::new("v2"),
), ),
))), ))),
ast::GraphPattern::OptionalPattern(Box::new(ast::GraphPattern::PropertyPathPattern( ast::GraphPattern::OptionalPattern(Box::new(ast::GraphPattern::PathPattern(
ast::PropertyPathPattern::new( ast::PathPattern::new(
Variable::new("s"), Variable::new("s"),
Variable::new("p3"), Variable::new("p3"),
Variable::new("v3"), Variable::new("v3"),
@ -1469,19 +1499,19 @@ fn test_sparql_algebra_examples() {
]).try_into(), ]).try_into(),
Ok(GraphPattern::LeftJoin( Ok(GraphPattern::LeftJoin(
Box::new(GraphPattern::LeftJoin( Box::new(GraphPattern::LeftJoin(
Box::new(GraphPattern::BGP(vec![PropertyPathPattern::new( Box::new(GraphPattern::BGP(vec![PathPattern::new(
Variable::new("s"), Variable::new("s"),
Variable::new("p1"), Variable::new("p1"),
Variable::new("v1"), Variable::new("v1"),
)])), )])),
Box::new(GraphPattern::BGP(vec![PropertyPathPattern::new( Box::new(GraphPattern::BGP(vec![PathPattern::new(
Variable::new("s"), Variable::new("s"),
Variable::new("p2"), Variable::new("p2"),
Variable::new("v2"), Variable::new("v2"),
)])), )])),
ast::Expression::ConstantExpression(Literal::from(true).into()), ast::Expression::ConstantExpression(Literal::from(true).into()),
)), )),
Box::new(GraphPattern::BGP(vec![PropertyPathPattern::new( Box::new(GraphPattern::BGP(vec![PathPattern::new(
Variable::new("s"), Variable::new("s"),
Variable::new("p3"), Variable::new("p3"),
Variable::new("v3"), Variable::new("v3"),
@ -1492,13 +1522,13 @@ fn test_sparql_algebra_examples() {
assert_eq!( assert_eq!(
ast::GraphPattern::GroupPattern(vec![ ast::GraphPattern::GroupPattern(vec![
ast::GraphPattern::PropertyPathPattern(ast::PropertyPathPattern::new( ast::GraphPattern::PathPattern(ast::PathPattern::new(
Variable::new("s"), Variable::new("s"),
Variable::new("p1"), Variable::new("p1"),
Variable::new("v1"), Variable::new("v1"),
)), )),
ast::GraphPattern::OptionalPattern(Box::new(ast::GraphPattern::GroupPattern(vec![ ast::GraphPattern::OptionalPattern(Box::new(ast::GraphPattern::GroupPattern(vec![
ast::GraphPattern::PropertyPathPattern(ast::PropertyPathPattern::new( ast::GraphPattern::PathPattern(ast::PathPattern::new(
Variable::new("s"), Variable::new("s"),
Variable::new("p2"), Variable::new("p2"),
Variable::new("v2"), Variable::new("v2"),
@ -1512,12 +1542,12 @@ fn test_sparql_algebra_examples() {
]))), ]))),
]).try_into(), ]).try_into(),
Ok(GraphPattern::LeftJoin( Ok(GraphPattern::LeftJoin(
Box::new(GraphPattern::BGP(vec![PropertyPathPattern::new( Box::new(GraphPattern::BGP(vec![PathPattern::new(
Variable::new("s"), Variable::new("s"),
Variable::new("p1"), Variable::new("p1"),
Variable::new("v1"), Variable::new("v1"),
)])), )])),
Box::new(GraphPattern::BGP(vec![PropertyPathPattern::new( Box::new(GraphPattern::BGP(vec![PathPattern::new(
Variable::new("s"), Variable::new("s"),
Variable::new("p2"), Variable::new("p2"),
Variable::new("v2"), Variable::new("v2"),
@ -1534,19 +1564,19 @@ fn test_sparql_algebra_examples() {
assert_eq!( assert_eq!(
ast::GraphPattern::GroupPattern(vec![ ast::GraphPattern::GroupPattern(vec![
ast::GraphPattern::UnionPattern(vec![ ast::GraphPattern::UnionPattern(vec![
ast::GraphPattern::PropertyPathPattern(ast::PropertyPathPattern::new( ast::GraphPattern::PathPattern(ast::PathPattern::new(
Variable::new("s"), Variable::new("s"),
Variable::new("p1"), Variable::new("p1"),
Variable::new("v1"), Variable::new("v1"),
)), )),
ast::GraphPattern::PropertyPathPattern(ast::PropertyPathPattern::new( ast::GraphPattern::PathPattern(ast::PathPattern::new(
Variable::new("s"), Variable::new("s"),
Variable::new("p2"), Variable::new("p2"),
Variable::new("v2"), Variable::new("v2"),
)), )),
]), ]),
ast::GraphPattern::OptionalPattern(Box::new(ast::GraphPattern::PropertyPathPattern( ast::GraphPattern::OptionalPattern(Box::new(ast::GraphPattern::PathPattern(
ast::PropertyPathPattern::new( ast::PathPattern::new(
Variable::new("s"), Variable::new("s"),
Variable::new("p3"), Variable::new("p3"),
Variable::new("v3"), Variable::new("v3"),
@ -1555,18 +1585,18 @@ fn test_sparql_algebra_examples() {
]).try_into(), ]).try_into(),
Ok(GraphPattern::LeftJoin( Ok(GraphPattern::LeftJoin(
Box::new(GraphPattern::Union( Box::new(GraphPattern::Union(
Box::new(GraphPattern::BGP(vec![PropertyPathPattern::new( Box::new(GraphPattern::BGP(vec![PathPattern::new(
Variable::new("s"), Variable::new("s"),
Variable::new("p1"), Variable::new("p1"),
Variable::new("v1"), Variable::new("v1"),
)])), )])),
Box::new(GraphPattern::BGP(vec![PropertyPathPattern::new( Box::new(GraphPattern::BGP(vec![PathPattern::new(
Variable::new("s"), Variable::new("s"),
Variable::new("p2"), Variable::new("p2"),
Variable::new("v2"), Variable::new("v2"),
)])), )])),
)), )),
Box::new(GraphPattern::BGP(vec![PropertyPathPattern::new( Box::new(GraphPattern::BGP(vec![PathPattern::new(
Variable::new("s"), Variable::new("s"),
Variable::new("p3"), Variable::new("p3"),
Variable::new("v3"), Variable::new("v3"),
@ -1577,7 +1607,7 @@ fn test_sparql_algebra_examples() {
assert_eq!( assert_eq!(
ast::GraphPattern::GroupPattern(vec![ ast::GraphPattern::GroupPattern(vec![
ast::GraphPattern::PropertyPathPattern(ast::PropertyPathPattern::new( ast::GraphPattern::PathPattern(ast::PathPattern::new(
Variable::new("s"), Variable::new("s"),
Variable::new("p1"), Variable::new("p1"),
Variable::new("v1"), Variable::new("v1"),
@ -1588,8 +1618,8 @@ fn test_sparql_algebra_examples() {
)), )),
Box::new(ast::Expression::ConstantExpression(Literal::from(3).into())), Box::new(ast::Expression::ConstantExpression(Literal::from(3).into())),
)), )),
ast::GraphPattern::OptionalPattern(Box::new(ast::GraphPattern::PropertyPathPattern( ast::GraphPattern::OptionalPattern(Box::new(ast::GraphPattern::PathPattern(
ast::PropertyPathPattern::new( ast::PathPattern::new(
Variable::new("s"), Variable::new("s"),
Variable::new("p2"), Variable::new("p2"),
Variable::new("v2"), Variable::new("v2"),
@ -1604,12 +1634,12 @@ fn test_sparql_algebra_examples() {
Box::new(ast::Expression::ConstantExpression(Literal::from(3).into())), Box::new(ast::Expression::ConstantExpression(Literal::from(3).into())),
), ),
Box::new(GraphPattern::LeftJoin( Box::new(GraphPattern::LeftJoin(
Box::new(GraphPattern::BGP(vec![PropertyPathPattern::new( Box::new(GraphPattern::BGP(vec![PathPattern::new(
Variable::new("s"), Variable::new("s"),
Variable::new("p1"), Variable::new("p1"),
Variable::new("v1"), Variable::new("v1"),
)])), )])),
Box::new(GraphPattern::BGP(vec![PropertyPathPattern::new( Box::new(GraphPattern::BGP(vec![PathPattern::new(
Variable::new("s"), Variable::new("s"),
Variable::new("p2"), Variable::new("p2"),
Variable::new("v2"), Variable::new("v2"),
@ -1621,7 +1651,7 @@ fn test_sparql_algebra_examples() {
assert_eq!( assert_eq!(
ast::GraphPattern::GroupPattern(vec![ ast::GraphPattern::GroupPattern(vec![
ast::GraphPattern::PropertyPathPattern(ast::PropertyPathPattern::new( ast::GraphPattern::PathPattern(ast::PathPattern::new(
Variable::new("s"), Variable::new("s"),
Variable::new("p"), Variable::new("p"),
Variable::new("v"), Variable::new("v"),
@ -1635,7 +1665,7 @@ fn test_sparql_algebra_examples() {
), ),
Variable::new("v2"), Variable::new("v2"),
), ),
ast::GraphPattern::PropertyPathPattern(ast::PropertyPathPattern::new( ast::GraphPattern::PathPattern(ast::PathPattern::new(
Variable::new("s"), Variable::new("s"),
Variable::new("p1"), Variable::new("p1"),
Variable::new("v2"), Variable::new("v2"),
@ -1643,7 +1673,7 @@ fn test_sparql_algebra_examples() {
]).try_into(), ]).try_into(),
Ok(GraphPattern::Join( Ok(GraphPattern::Join(
Box::new(GraphPattern::Extend( Box::new(GraphPattern::Extend(
Box::new(GraphPattern::BGP(vec![PropertyPathPattern::new( Box::new(GraphPattern::BGP(vec![PathPattern::new(
Variable::new("s"), Variable::new("s"),
Variable::new("p"), Variable::new("p"),
Variable::new("v"), Variable::new("v"),
@ -1656,7 +1686,7 @@ fn test_sparql_algebra_examples() {
)), )),
), ),
)), )),
Box::new(GraphPattern::BGP(vec![PropertyPathPattern::new( Box::new(GraphPattern::BGP(vec![PathPattern::new(
Variable::new("s"), Variable::new("s"),
Variable::new("p1"), Variable::new("p1"),
Variable::new("v2"), Variable::new("v2"),
@ -1668,13 +1698,13 @@ fn test_sparql_algebra_examples() {
assert_eq!( assert_eq!(
ast::GraphPattern::GroupPattern(vec![ ast::GraphPattern::GroupPattern(vec![
ast::GraphPattern::PropertyPathPattern(ast::PropertyPathPattern::new( ast::GraphPattern::PathPattern(ast::PathPattern::new(
Variable::new("s"), Variable::new("s"),
Variable::new("p"), Variable::new("p"),
Variable::new("v"), Variable::new("v"),
)), )),
ast::GraphPattern::MinusPattern(Box::new(ast::GraphPattern::PropertyPathPattern( ast::GraphPattern::MinusPattern(Box::new(ast::GraphPattern::PathPattern(
ast::PropertyPathPattern::new( ast::PathPattern::new(
Variable::new("s"), Variable::new("s"),
Variable::new("p1"), Variable::new("p1"),
Variable::new("v2"), Variable::new("v2"),
@ -1682,12 +1712,12 @@ fn test_sparql_algebra_examples() {
))), ))),
]).try_into(), ]).try_into(),
Ok(GraphPattern::Minus( Ok(GraphPattern::Minus(
Box::new(GraphPattern::BGP(vec![PropertyPathPattern::new( Box::new(GraphPattern::BGP(vec![PathPattern::new(
Variable::new("s"), Variable::new("s"),
Variable::new("p"), Variable::new("p"),
Variable::new("v"), Variable::new("v"),
)])), )])),
Box::new(GraphPattern::BGP(vec![PropertyPathPattern::new( Box::new(GraphPattern::BGP(vec![PathPattern::new(
Variable::new("s"), Variable::new("s"),
Variable::new("p1"), Variable::new("p1"),
Variable::new("v2"), Variable::new("v2"),

@ -49,12 +49,29 @@ mod grammar {
} }
} }
struct FocusedPropertyPathPattern<F> { #[derive(Clone)]
enum VariableOrPropertyPath {
Variable(Variable),
PropertyPath(PropertyPath),
}
fn to_triple_or_path_pattern(
s: TermOrVariable,
p: VariableOrPropertyPath,
o: TermOrVariable,
) -> TripleOrPathPattern {
match p {
VariableOrPropertyPath::Variable(p) => TriplePattern::new(s, p, o).into(),
VariableOrPropertyPath::PropertyPath(p) => PathPattern::new(s, p, o).into(),
}
}
struct FocusedTripleOrPathPattern<F> {
focus: F, focus: F,
patterns: Vec<PropertyPathPattern>, patterns: Vec<TripleOrPathPattern>,
} }
impl<F> FocusedPropertyPathPattern<F> { impl<F> FocusedTripleOrPathPattern<F> {
fn new(focus: F) -> Self { fn new(focus: F) -> Self {
Self { Self {
focus, focus,
@ -63,7 +80,7 @@ mod grammar {
} }
} }
impl<F: Default> Default for FocusedPropertyPathPattern<F> { impl<F: Default> Default for FocusedTripleOrPathPattern<F> {
fn default() -> Self { fn default() -> Self {
Self { Self {
focus: F::default(), focus: F::default(),
@ -72,8 +89,8 @@ mod grammar {
} }
} }
impl<F> From<FocusedPropertyPathPattern<F>> for FocusedPropertyPathPattern<Vec<F>> { impl<F> From<FocusedTripleOrPathPattern<F>> for FocusedTripleOrPathPattern<Vec<F>> {
fn from(input: FocusedPropertyPathPattern<F>) -> Self { fn from(input: FocusedTripleOrPathPattern<F>) -> Self {
Self { Self {
focus: vec![input.focus], focus: vec![input.focus],
patterns: input.patterns, patterns: input.patterns,
@ -81,7 +98,7 @@ mod grammar {
} }
} }
impl<F, T: From<F>> From<FocusedTriplePattern<F>> for FocusedPropertyPathPattern<T> { impl<F, T: From<F>> From<FocusedTriplePattern<F>> for FocusedTripleOrPathPattern<T> {
fn from(input: FocusedTriplePattern<F>) -> Self { fn from(input: FocusedTriplePattern<F>) -> Self {
Self { Self {
focus: input.focus.into(), focus: input.focus.into(),

@ -87,7 +87,7 @@ ConstructQuery -> Query =
algebra: build_select(Selection { algebra: build_select(Selection {
option: SelectionOption::Reduced, option: SelectionOption::Reduced,
variables: None variables: None
}, MultiSetPattern::BGP(c.into_iter().map(|p| PropertyPathPattern::from(p)).collect()).into(), }, MultiSetPattern::BGP(c.into_iter().map(|p| TripleOrPathPattern::from(p)).collect()).into(),
h, o, l, v) h, o, l, v)
} }
} }
@ -253,14 +253,14 @@ GroupGraphPatternSub_item -> Vec<PartialGraphPattern> = a:GraphPatternNotTriples
} }
//[55] //[55]
TriplesBlock -> Vec<PropertyPathPattern> = h:TriplesSameSubjectPath _ t:TriplesBlock_tail? { TriplesBlock -> Vec<TripleOrPathPattern> = h:TriplesSameSubjectPath _ t:TriplesBlock_tail? {
let mut triples = h; let mut triples = h;
if let Some(l) = t { if let Some(l) = t {
triples.extend_from_slice(&l) triples.extend_from_slice(&l)
} }
triples triples
} }
TriplesBlock_tail -> Vec<PropertyPathPattern> = '.' _ t:TriplesBlock? _ { TriplesBlock_tail -> Vec<TripleOrPathPattern> = '.' _ t:TriplesBlock? _ {
t.unwrap_or_else(|| Vec::default()) t.unwrap_or_else(|| Vec::default())
} }
@ -433,12 +433,12 @@ ObjectList_item -> FocusedTriplePattern<TermOrVariable> = o:Object _ { o }
Object -> FocusedTriplePattern<TermOrVariable> = GraphNode Object -> FocusedTriplePattern<TermOrVariable> = GraphNode
//[81] //[81]
TriplesSameSubjectPath -> Vec<PropertyPathPattern> = TriplesSameSubjectPath -> Vec<TripleOrPathPattern> =
s:VarOrTerm _ po:PropertyListPathNotEmpty { s:VarOrTerm _ po:PropertyListPathNotEmpty {
let mut patterns = po.patterns; let mut patterns = po.patterns;
for (p, os) in po.focus { for (p, os) in po.focus {
for o in os { for o in os {
patterns.push(PropertyPathPattern::new(s.clone(), p.clone(), o)) patterns.push(to_triple_or_path_pattern(s.clone(), p.clone(), o))
} }
} }
patterns patterns
@ -448,20 +448,20 @@ TriplesSameSubjectPath -> Vec<PropertyPathPattern> =
patterns.extend_from_slice(&po.patterns); patterns.extend_from_slice(&po.patterns);
for (p, os) in po.focus { for (p, os) in po.focus {
for o in os { for o in os {
patterns.push(PropertyPathPattern::new(s.focus.clone(), p.clone(), o)) patterns.push(to_triple_or_path_pattern(s.focus.clone(), p.clone(), o))
} }
} }
patterns patterns
} }
//[82] //[82]
PropertyListPath -> FocusedPropertyPathPattern<Vec<(PropertyPath,Vec<TermOrVariable>)>> = PropertyListPath -> FocusedTripleOrPathPattern<Vec<(VariableOrPropertyPath,Vec<TermOrVariable>)>> =
PropertyListPathNotEmpty / PropertyListPathNotEmpty /
{ FocusedPropertyPathPattern::default() } { FocusedTripleOrPathPattern::default() }
//[83] //[83]
PropertyListPathNotEmpty -> FocusedPropertyPathPattern<Vec<(PropertyPath,Vec<TermOrVariable>)>> = hp:(VerbPath / VerbSimple) _ ho:ObjectListPath _ t:PropertyListPathNotEmpty_item* { PropertyListPathNotEmpty -> FocusedTripleOrPathPattern<Vec<(VariableOrPropertyPath,Vec<TermOrVariable>)>> = hp:(VerbPath / VerbSimple) _ ho:ObjectListPath _ t:PropertyListPathNotEmpty_item* {
t.into_iter().fold(FocusedPropertyPathPattern { t.into_iter().fold(FocusedTripleOrPathPattern {
focus: vec![(hp, ho.focus)], focus: vec![(hp, ho.focus)],
patterns: ho.patterns patterns: ho.patterns
}, |mut a, b| { }, |mut a, b| {
@ -470,7 +470,7 @@ PropertyListPathNotEmpty -> FocusedPropertyPathPattern<Vec<(PropertyPath,Vec<Ter
a a
}) })
} }
PropertyListPathNotEmpty_item -> FocusedTriplePattern<(PropertyPath,Vec<TermOrVariable>)> = ';' _ p:(VerbPath / VerbSimple) _ o:ObjectList _ { //TODO: make values after ';' optional PropertyListPathNotEmpty_item -> FocusedTriplePattern<(VariableOrPropertyPath,Vec<TermOrVariable>)> = ';' _ p:(VerbPath / VerbSimple) _ o:ObjectList _ { //TODO: make values after ';' optional
FocusedTriplePattern { FocusedTriplePattern {
focus: (p, o.focus), focus: (p, o.focus),
patterns: o.patterns patterns: o.patterns
@ -478,25 +478,27 @@ PropertyListPathNotEmpty_item -> FocusedTriplePattern<(PropertyPath,Vec<TermOrVa
} }
//[84] //[84]
VerbPath -> PropertyPath = Path VerbPath -> VariableOrPropertyPath = p:Path {
VariableOrPropertyPath::PropertyPath(p)
}
//[85] //[85]
VerbSimple -> PropertyPath = v:Var { VerbSimple -> VariableOrPropertyPath = v:Var {
v.into() VariableOrPropertyPath::Variable(v)
} }
//[86] //[86]
ObjectListPath -> FocusedPropertyPathPattern<Vec<TermOrVariable>> = o:ObjectPath_item **<1,> (',' _) { ObjectListPath -> FocusedTripleOrPathPattern<Vec<TermOrVariable>> = o:ObjectPath_item **<1,> (',' _) {
o.into_iter().fold(FocusedPropertyPathPattern::<Vec<TermOrVariable>>::default(), |mut a, b| { o.into_iter().fold(FocusedTripleOrPathPattern::<Vec<TermOrVariable>>::default(), |mut a, b| {
a.focus.push(b.focus); a.focus.push(b.focus);
a.patterns.extend_from_slice(&b.patterns); a.patterns.extend_from_slice(&b.patterns);
a a
}) })
} }
ObjectPath_item -> FocusedPropertyPathPattern<TermOrVariable> = o:ObjectPath _ { o } ObjectPath_item -> FocusedTripleOrPathPattern<TermOrVariable> = o:ObjectPath _ { o }
//[87] //[87]
ObjectPath -> FocusedPropertyPathPattern<TermOrVariable> = GraphNodePath ObjectPath -> FocusedTripleOrPathPattern<TermOrVariable> = GraphNodePath
//[88] //[88]
Path -> PropertyPath = PathAlternative Path -> PropertyPath = PathAlternative
@ -531,7 +533,8 @@ PathEltOrInverse -> PropertyPath =
//[94] //[94]
PathPrimary -> PropertyPath = PathPrimary -> PropertyPath =
v:Verb { v.into() } / 'a' { rdf::TYPE.clone().into() } /
v:iri { v.into() } /
'!' _ p:PathNegatedPropertySet { p } / '!' _ p:PathNegatedPropertySet { p } /
'(' _ p:Path _ ')' { p } '(' _ p:Path _ ')' { p }
@ -591,18 +594,18 @@ BlankNodePropertyList -> FocusedTriplePattern<TermOrVariable> = '[' _ po:Propert
} }
//[100] //[100]
TriplesNodePath -> FocusedPropertyPathPattern<TermOrVariable> = CollectionPath / BlankNodePropertyListPath TriplesNodePath -> FocusedTripleOrPathPattern<TermOrVariable> = CollectionPath / BlankNodePropertyListPath
//[101] //[101]
BlankNodePropertyListPath -> FocusedPropertyPathPattern<TermOrVariable> = '[' _ po:PropertyListPathNotEmpty _ ']' { BlankNodePropertyListPath -> FocusedTripleOrPathPattern<TermOrVariable> = '[' _ po:PropertyListPathNotEmpty _ ']' {
let mut patterns: Vec<PropertyPathPattern> = Vec::default(); let mut patterns: Vec<TripleOrPathPattern> = Vec::default();
let mut bnode = TermOrVariable::from(BlankNode::default()); let mut bnode = TermOrVariable::from(BlankNode::default());
for (p, os) in po.focus { for (p, os) in po.focus {
for o in os { for o in os {
patterns.push(PropertyPathPattern::new(bnode.clone(), p.clone(), o)); patterns.push(to_triple_or_path_pattern(bnode.clone(), p.clone(), o));
} }
} }
FocusedPropertyPathPattern { FocusedTripleOrPathPattern {
focus: bnode, focus: bnode,
patterns patterns
} }
@ -627,22 +630,22 @@ Collection -> FocusedTriplePattern<TermOrVariable> = '(' _ o:Collection_item+ ')
Collection_item -> FocusedTriplePattern<TermOrVariable> = o:GraphNode _ { o } Collection_item -> FocusedTriplePattern<TermOrVariable> = o:GraphNode _ { o }
//[103] //[103]
CollectionPath -> FocusedPropertyPathPattern<TermOrVariable> = '(' _ o:CollectionPath_item+ _ ')' { CollectionPath -> FocusedTripleOrPathPattern<TermOrVariable> = '(' _ o:CollectionPath_item+ _ ')' {
let mut patterns: Vec<PropertyPathPattern> = Vec::default(); let mut patterns: Vec<TripleOrPathPattern> = Vec::default();
let mut current_list_node = TermOrVariable::from(rdf::NIL.clone()); let mut current_list_node = TermOrVariable::from(rdf::NIL.clone());
for objWithPatterns in o.into_iter().rev() { for objWithPatterns in o.into_iter().rev() {
let new_blank_node = TermOrVariable::from(BlankNode::default()); let new_blank_node = TermOrVariable::from(BlankNode::default());
patterns.push(PropertyPathPattern::new(new_blank_node.clone(), rdf::FIRST.clone(), objWithPatterns.focus.clone())); patterns.push(TriplePattern::new(new_blank_node.clone(), rdf::FIRST.clone(), objWithPatterns.focus.clone()).into());
patterns.push(PropertyPathPattern::new(new_blank_node.clone(), rdf::REST.clone(), current_list_node)); patterns.push(TriplePattern::new(new_blank_node.clone(), rdf::REST.clone(), current_list_node).into());
current_list_node = new_blank_node; current_list_node = new_blank_node;
patterns.extend_from_slice(&objWithPatterns.patterns); patterns.extend_from_slice(&objWithPatterns.patterns);
} }
FocusedPropertyPathPattern { FocusedTripleOrPathPattern {
focus: current_list_node, focus: current_list_node,
patterns patterns
} }
} }
CollectionPath_item -> FocusedPropertyPathPattern<TermOrVariable> = p:GraphNodePath _ { p } CollectionPath_item -> FocusedTripleOrPathPattern<TermOrVariable> = p:GraphNodePath _ { p }
//[104] //[104]
GraphNode -> FocusedTriplePattern<TermOrVariable> = GraphNode -> FocusedTriplePattern<TermOrVariable> =
@ -650,8 +653,8 @@ GraphNode -> FocusedTriplePattern<TermOrVariable> =
TriplesNode TriplesNode
//[105] //[105]
GraphNodePath -> FocusedPropertyPathPattern<TermOrVariable> = GraphNodePath -> FocusedTripleOrPathPattern<TermOrVariable> =
t:VarOrTerm { FocusedPropertyPathPattern::new(t.into()) } / t:VarOrTerm { FocusedTripleOrPathPattern::new(t.into()) } /
TriplesNodePath TriplesNodePath
//[106] //[106]

Loading…
Cancel
Save