|
|
@ -86,88 +86,99 @@ impl RuleRecognizer for TriGRecognizer { |
|
|
|
self.stack.push(TriGState::BaseExpectIri); |
|
|
|
self.stack.push(TriGState::BaseExpectIri); |
|
|
|
self |
|
|
|
self |
|
|
|
} |
|
|
|
} |
|
|
|
N3Token::PlainKeyword(k) if k.eq_ignore_ascii_case("graph") && context.with_graph_name => { |
|
|
|
N3Token::PlainKeyword(k) |
|
|
|
|
|
|
|
if k.eq_ignore_ascii_case("graph") && context.with_graph_name => |
|
|
|
|
|
|
|
{ |
|
|
|
self.stack.push(TriGState::WrappedGraph); |
|
|
|
self.stack.push(TriGState::WrappedGraph); |
|
|
|
self.stack.push(TriGState::GraphName); |
|
|
|
self.stack.push(TriGState::GraphName); |
|
|
|
self |
|
|
|
self |
|
|
|
} |
|
|
|
} |
|
|
|
N3Token::Punctuation("{") if context.with_graph_name => { |
|
|
|
N3Token::Punctuation("{") if context.with_graph_name => { |
|
|
|
self.stack.push(TriGState::WrappedGraph); |
|
|
|
self.stack.push(TriGState::WrappedGraph); |
|
|
|
self.recognize_next(token, context,results, errors) |
|
|
|
self.recognize_next(token, context, results, errors) |
|
|
|
} |
|
|
|
} |
|
|
|
_ => { |
|
|
|
_ => { |
|
|
|
self.stack.push(TriGState::TriplesOrGraph); |
|
|
|
self.stack.push(TriGState::TriplesOrGraph); |
|
|
|
self.recognize_next(token, context,results, errors) |
|
|
|
self.recognize_next(token, context, results, errors) |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
}, |
|
|
|
|
|
|
|
TriGState::ExpectDot => { |
|
|
|
TriGState::ExpectDot => { |
|
|
|
self.cur_subject.pop(); |
|
|
|
self.cur_subject.pop(); |
|
|
|
if token == N3Token::Punctuation(".") { |
|
|
|
if token == N3Token::Punctuation(".") { |
|
|
|
self |
|
|
|
self |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
errors.push("A dot is expected at the end of statements".into()); |
|
|
|
errors.push("A dot is expected at the end of statements".into()); |
|
|
|
self.recognize_next(token, context,results, errors) |
|
|
|
self.recognize_next(token, context, results, errors) |
|
|
|
} |
|
|
|
} |
|
|
|
}, |
|
|
|
|
|
|
|
TriGState::BaseExpectIri => match token { |
|
|
|
|
|
|
|
N3Token::IriRef(iri) => { |
|
|
|
|
|
|
|
match Iri::parse_unchecked(iri) { |
|
|
|
|
|
|
|
Ok(iri) => { |
|
|
|
|
|
|
|
context.lexer_options.base_iri = Some(iri); |
|
|
|
|
|
|
|
self |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
Err(e) => self.error(errors, format!("Invalid base IRI: {e}")) |
|
|
|
TriGState::BaseExpectIri => { |
|
|
|
|
|
|
|
if let N3Token::IriRef(iri) = token { |
|
|
|
|
|
|
|
context.lexer_options.base_iri = Some(Iri::parse_unchecked(iri)); |
|
|
|
|
|
|
|
self |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
self.error(errors, "The BASE keyword should be followed by an IRI") |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
_ => self.error(errors, "The BASE keyword should be followed by an IRI"), |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
TriGState::PrefixExpectPrefix => match token { |
|
|
|
TriGState::PrefixExpectPrefix => match token { |
|
|
|
N3Token::PrefixedName { prefix, local, .. } if local.is_empty() => { |
|
|
|
N3Token::PrefixedName { prefix, local, .. } if local.is_empty() => { |
|
|
|
self.stack.push(TriGState::PrefixExpectIri { name: prefix.to_owned() }); |
|
|
|
self.stack.push(TriGState::PrefixExpectIri { |
|
|
|
|
|
|
|
name: prefix.to_owned(), |
|
|
|
|
|
|
|
}); |
|
|
|
self |
|
|
|
self |
|
|
|
} |
|
|
|
} |
|
|
|
_ => { |
|
|
|
_ => self.error( |
|
|
|
self.error(errors, "The PREFIX keyword should be followed by a prefix like 'ex:'") |
|
|
|
errors, |
|
|
|
} |
|
|
|
"The PREFIX keyword should be followed by a prefix like 'ex:'", |
|
|
|
|
|
|
|
), |
|
|
|
}, |
|
|
|
}, |
|
|
|
TriGState::PrefixExpectIri { name } => match token { |
|
|
|
TriGState::PrefixExpectIri { name } => { |
|
|
|
N3Token::IriRef(iri) => { |
|
|
|
if let N3Token::IriRef(iri) = token { |
|
|
|
match Iri::parse_unchecked(iri) { |
|
|
|
context.prefixes.insert(name, Iri::parse_unchecked(iri)); |
|
|
|
Ok(iri) => { |
|
|
|
|
|
|
|
context.prefixes.insert(name, iri); |
|
|
|
|
|
|
|
self |
|
|
|
self |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
self.error(errors, "The PREFIX declaration should be followed by a prefix and its value as an IRI") |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
Err(e) => self.error(errors, format!("Invalid prefix IRI: {e}")) |
|
|
|
|
|
|
|
} } |
|
|
|
|
|
|
|
_ => self.error(errors, "The PREFIX declaration should be followed by a prefix and its value as an IRI"), |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
// [3g] triplesOrGraph ::= labelOrSubject ( wrappedGraph | predicateObjectList '.' ) | quotedTriple predicateObjectList '.'
|
|
|
|
// [3g] triplesOrGraph ::= labelOrSubject ( wrappedGraph | predicateObjectList '.' ) | quotedTriple predicateObjectList '.'
|
|
|
|
// [4g] triples2 ::= blankNodePropertyList predicateObjectList? '.' | collection predicateObjectList '.'
|
|
|
|
// [4g] triples2 ::= blankNodePropertyList predicateObjectList? '.' | collection predicateObjectList '.'
|
|
|
|
TriGState::TriplesOrGraph => match token { |
|
|
|
TriGState::TriplesOrGraph => match token { |
|
|
|
N3Token::IriRef(iri) => { |
|
|
|
N3Token::IriRef(iri) => { |
|
|
|
self.stack.push(TriGState::WrappedGraphOrPredicateObjectList { |
|
|
|
self.stack |
|
|
|
term: NamedNode::new_unchecked(iri).into() |
|
|
|
.push(TriGState::WrappedGraphOrPredicateObjectList { |
|
|
|
|
|
|
|
term: NamedNode::new_unchecked(iri).into(), |
|
|
|
}); |
|
|
|
}); |
|
|
|
self |
|
|
|
self |
|
|
|
} |
|
|
|
} |
|
|
|
N3Token::PrefixedName { prefix, local, might_be_invalid_iri } => match resolve_local_name(prefix, &local, might_be_invalid_iri, &context.prefixes) { |
|
|
|
N3Token::PrefixedName { |
|
|
|
|
|
|
|
prefix, |
|
|
|
|
|
|
|
local, |
|
|
|
|
|
|
|
might_be_invalid_iri, |
|
|
|
|
|
|
|
} => match resolve_local_name( |
|
|
|
|
|
|
|
prefix, |
|
|
|
|
|
|
|
&local, |
|
|
|
|
|
|
|
might_be_invalid_iri, |
|
|
|
|
|
|
|
&context.prefixes, |
|
|
|
|
|
|
|
) { |
|
|
|
Ok(t) => { |
|
|
|
Ok(t) => { |
|
|
|
self.stack.push(TriGState::WrappedGraphOrPredicateObjectList { |
|
|
|
self.stack |
|
|
|
term: t.into() |
|
|
|
.push(TriGState::WrappedGraphOrPredicateObjectList { |
|
|
|
|
|
|
|
term: t.into(), |
|
|
|
}); |
|
|
|
}); |
|
|
|
self |
|
|
|
self |
|
|
|
}, |
|
|
|
|
|
|
|
Err(e) => self.error(errors, e) |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
Err(e) => self.error(errors, e), |
|
|
|
|
|
|
|
}, |
|
|
|
N3Token::BlankNodeLabel(label) => { |
|
|
|
N3Token::BlankNodeLabel(label) => { |
|
|
|
self.stack.push(TriGState::WrappedGraphOrPredicateObjectList { |
|
|
|
self.stack |
|
|
|
term: BlankNode::new_unchecked(label).into() |
|
|
|
.push(TriGState::WrappedGraphOrPredicateObjectList { |
|
|
|
|
|
|
|
term: BlankNode::new_unchecked(label).into(), |
|
|
|
}); |
|
|
|
}); |
|
|
|
self |
|
|
|
self |
|
|
|
} |
|
|
|
} |
|
|
|
N3Token::Punctuation("[") => { |
|
|
|
N3Token::Punctuation("[") => { |
|
|
|
self.stack.push(TriGState::WrappedGraphBlankNodePropertyListCurrent); |
|
|
|
self.stack |
|
|
|
|
|
|
|
.push(TriGState::WrappedGraphBlankNodePropertyListCurrent); |
|
|
|
self |
|
|
|
self |
|
|
|
} |
|
|
|
} |
|
|
|
N3Token::Punctuation("(") => { |
|
|
|
N3Token::Punctuation("(") => { |
|
|
@ -186,10 +197,8 @@ impl RuleRecognizer for TriGRecognizer { |
|
|
|
self.stack.push(TriGState::QuotedSubject); |
|
|
|
self.stack.push(TriGState::QuotedSubject); |
|
|
|
self |
|
|
|
self |
|
|
|
} |
|
|
|
} |
|
|
|
_ => { |
|
|
|
_ => self.error(errors, "TOKEN is not a valid subject or graph name"), |
|
|
|
self.error(errors, "TOKEN is not a valid subject or graph name") |
|
|
|
}, |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
TriGState::WrappedGraphOrPredicateObjectList { term } => { |
|
|
|
TriGState::WrappedGraphOrPredicateObjectList { term } => { |
|
|
|
if token == N3Token::Punctuation("{") && context.with_graph_name { |
|
|
|
if token == N3Token::Punctuation("{") && context.with_graph_name { |
|
|
|
self.cur_graph = term.into(); |
|
|
|
self.cur_graph = term.into(); |
|
|
@ -199,11 +208,13 @@ impl RuleRecognizer for TriGRecognizer { |
|
|
|
self.stack.push(TriGState::ExpectDot); |
|
|
|
self.stack.push(TriGState::ExpectDot); |
|
|
|
self.stack.push(TriGState::PredicateObjectList); |
|
|
|
self.stack.push(TriGState::PredicateObjectList); |
|
|
|
} |
|
|
|
} |
|
|
|
self.recognize_next(token, context,results, errors) |
|
|
|
self.recognize_next(token, context, results, errors) |
|
|
|
} |
|
|
|
} |
|
|
|
TriGState::WrappedGraphBlankNodePropertyListCurrent => if token == N3Token::Punctuation("]") { |
|
|
|
TriGState::WrappedGraphBlankNodePropertyListCurrent => { |
|
|
|
self.stack.push(TriGState::WrappedGraphOrPredicateObjectList { |
|
|
|
if token == N3Token::Punctuation("]") { |
|
|
|
term: BlankNode::default().into() |
|
|
|
self.stack |
|
|
|
|
|
|
|
.push(TriGState::WrappedGraphOrPredicateObjectList { |
|
|
|
|
|
|
|
term: BlankNode::default().into(), |
|
|
|
}); |
|
|
|
}); |
|
|
|
self |
|
|
|
self |
|
|
|
} else { |
|
|
|
} else { |
|
|
@ -211,21 +222,28 @@ impl RuleRecognizer for TriGRecognizer { |
|
|
|
self.stack.push(TriGState::ExpectDot); |
|
|
|
self.stack.push(TriGState::ExpectDot); |
|
|
|
self.stack.push(TriGState::SubjectBlankNodePropertyListEnd); |
|
|
|
self.stack.push(TriGState::SubjectBlankNodePropertyListEnd); |
|
|
|
self.stack.push(TriGState::PredicateObjectList); |
|
|
|
self.stack.push(TriGState::PredicateObjectList); |
|
|
|
self.recognize_next(token, context,results, errors) |
|
|
|
self.recognize_next(token, context, results, errors) |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
TriGState::SubjectBlankNodePropertyListEnd => if token == N3Token::Punctuation("]") { |
|
|
|
TriGState::SubjectBlankNodePropertyListEnd => { |
|
|
|
self.stack.push(TriGState::SubjectBlankNodePropertyListAfter ); |
|
|
|
if token == N3Token::Punctuation("]") { |
|
|
|
|
|
|
|
self.stack |
|
|
|
|
|
|
|
.push(TriGState::SubjectBlankNodePropertyListAfter); |
|
|
|
self |
|
|
|
self |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
errors.push("blank node property lists should end with a ']'".into()); |
|
|
|
errors.push("blank node property lists should end with a ']'".into()); |
|
|
|
self.stack.push(TriGState::SubjectBlankNodePropertyListAfter ); |
|
|
|
self.stack |
|
|
|
self.recognize_next(token, context,results, errors) |
|
|
|
.push(TriGState::SubjectBlankNodePropertyListAfter); |
|
|
|
|
|
|
|
self.recognize_next(token, context, results, errors) |
|
|
|
} |
|
|
|
} |
|
|
|
TriGState::SubjectBlankNodePropertyListAfter => if matches!(token, N3Token::Punctuation("." | "}")) { |
|
|
|
} |
|
|
|
self.recognize_next(token, context,results, errors) |
|
|
|
TriGState::SubjectBlankNodePropertyListAfter => { |
|
|
|
|
|
|
|
if matches!(token, N3Token::Punctuation("." | "}")) { |
|
|
|
|
|
|
|
self.recognize_next(token, context, results, errors) |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
self.stack.push(TriGState::PredicateObjectList); |
|
|
|
self.stack.push(TriGState::PredicateObjectList); |
|
|
|
self.recognize_next(token, context,results, errors) |
|
|
|
self.recognize_next(token, context, results, errors) |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
TriGState::SubjectCollectionBeginning => { |
|
|
|
TriGState::SubjectCollectionBeginning => { |
|
|
|
if let N3Token::Punctuation(")") = token { |
|
|
|
if let N3Token::Punctuation(")") = token { |
|
|
@ -238,20 +256,15 @@ impl RuleRecognizer for TriGRecognizer { |
|
|
|
self.cur_predicate.push(rdf::FIRST.into()); |
|
|
|
self.cur_predicate.push(rdf::FIRST.into()); |
|
|
|
self.stack.push(TriGState::SubjectCollectionPossibleEnd); |
|
|
|
self.stack.push(TriGState::SubjectCollectionPossibleEnd); |
|
|
|
self.stack.push(TriGState::Object); |
|
|
|
self.stack.push(TriGState::Object); |
|
|
|
self.recognize_next(token, context,results, errors) |
|
|
|
self.recognize_next(token, context, results, errors) |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
}, |
|
|
|
|
|
|
|
TriGState::SubjectCollectionPossibleEnd => { |
|
|
|
TriGState::SubjectCollectionPossibleEnd => { |
|
|
|
let old = self.cur_subject.pop().unwrap(); |
|
|
|
let old = self.cur_subject.pop().unwrap(); |
|
|
|
self.cur_object.pop(); |
|
|
|
self.cur_object.pop(); |
|
|
|
if let N3Token::Punctuation(")") = token { |
|
|
|
if let N3Token::Punctuation(")") = token { |
|
|
|
self.cur_predicate.pop(); |
|
|
|
self.cur_predicate.pop(); |
|
|
|
results.push(Quad::new( |
|
|
|
results.push(Quad::new(old, rdf::REST, rdf::NIL, self.cur_graph.clone())); |
|
|
|
old, |
|
|
|
|
|
|
|
rdf::REST, |
|
|
|
|
|
|
|
rdf::NIL, |
|
|
|
|
|
|
|
self.cur_graph.clone() |
|
|
|
|
|
|
|
)); |
|
|
|
|
|
|
|
self |
|
|
|
self |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
let new = BlankNode::default(); |
|
|
|
let new = BlankNode::default(); |
|
|
@ -259,37 +272,39 @@ impl RuleRecognizer for TriGRecognizer { |
|
|
|
old, |
|
|
|
old, |
|
|
|
rdf::REST, |
|
|
|
rdf::REST, |
|
|
|
new.clone(), |
|
|
|
new.clone(), |
|
|
|
self.cur_graph.clone() |
|
|
|
self.cur_graph.clone(), |
|
|
|
)); |
|
|
|
)); |
|
|
|
self.cur_subject.push(new.into()); |
|
|
|
self.cur_subject.push(new.into()); |
|
|
|
self.stack.push(TriGState::ObjectCollectionPossibleEnd); |
|
|
|
self.stack.push(TriGState::ObjectCollectionPossibleEnd); |
|
|
|
self.stack.push(TriGState::Object); |
|
|
|
self.stack.push(TriGState::Object); |
|
|
|
self.recognize_next(token, context,results, errors) |
|
|
|
self.recognize_next(token, context, results, errors) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
// [5g] wrappedGraph ::= '{' triplesBlock? '}'
|
|
|
|
// [5g] wrappedGraph ::= '{' triplesBlock? '}'
|
|
|
|
// [6g] triplesBlock ::= triples ('.' triplesBlock?)?
|
|
|
|
// [6g] triplesBlock ::= triples ('.' triplesBlock?)?
|
|
|
|
TriGState::WrappedGraph => if token == N3Token::Punctuation("{") { |
|
|
|
TriGState::WrappedGraph => { |
|
|
|
|
|
|
|
if token == N3Token::Punctuation("{") { |
|
|
|
self.stack.push(TriGState::WrappedGraphPossibleEnd); |
|
|
|
self.stack.push(TriGState::WrappedGraphPossibleEnd); |
|
|
|
self.stack.push(TriGState::Triples); |
|
|
|
self.stack.push(TriGState::Triples); |
|
|
|
self |
|
|
|
self |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
self.error(errors, "The GRAPH keyword should be followed by a graph name and a value in '{'") |
|
|
|
self.error(errors, "The GRAPH keyword should be followed by a graph name and a value in '{'") |
|
|
|
}, |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
TriGState::WrappedGraphPossibleEnd => { |
|
|
|
TriGState::WrappedGraphPossibleEnd => { |
|
|
|
self.cur_subject.pop(); |
|
|
|
self.cur_subject.pop(); |
|
|
|
match token { |
|
|
|
match token { |
|
|
|
N3Token::Punctuation("}") => { |
|
|
|
N3Token::Punctuation("}") => self, |
|
|
|
self |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
N3Token::Punctuation(".") => { |
|
|
|
N3Token::Punctuation(".") => { |
|
|
|
self.stack.push(TriGState::WrappedGraphPossibleEnd); |
|
|
|
self.stack.push(TriGState::WrappedGraphPossibleEnd); |
|
|
|
self.stack.push(TriGState::Triples); |
|
|
|
self.stack.push(TriGState::Triples); |
|
|
|
self |
|
|
|
self |
|
|
|
} |
|
|
|
} |
|
|
|
_ => { |
|
|
|
_ => { |
|
|
|
errors.push("A '}' or a '.' is expected at the end of a graph block".into()); |
|
|
|
errors.push( |
|
|
|
self.recognize_next(token, context,results, errors) |
|
|
|
"A '}' or a '.' is expected at the end of a graph block".into(), |
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
self.recognize_next(token, context, results, errors) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -297,11 +312,12 @@ impl RuleRecognizer for TriGRecognizer { |
|
|
|
// [10] subject ::= iri | BlankNode | collection | quotedTriple
|
|
|
|
// [10] subject ::= iri | BlankNode | collection | quotedTriple
|
|
|
|
TriGState::Triples => match token { |
|
|
|
TriGState::Triples => match token { |
|
|
|
N3Token::Punctuation("}") => { |
|
|
|
N3Token::Punctuation("}") => { |
|
|
|
self.recognize_next(token, context,results, errors) // Early end
|
|
|
|
self.recognize_next(token, context, results, errors) // Early end
|
|
|
|
}, |
|
|
|
} |
|
|
|
N3Token::Punctuation("[") => { |
|
|
|
N3Token::Punctuation("[") => { |
|
|
|
self.cur_subject.push(BlankNode::default().into()); |
|
|
|
self.cur_subject.push(BlankNode::default().into()); |
|
|
|
self.stack.push(TriGState::TriplesBlankNodePropertyListCurrent); |
|
|
|
self.stack |
|
|
|
|
|
|
|
.push(TriGState::TriplesBlankNodePropertyListCurrent); |
|
|
|
self |
|
|
|
self |
|
|
|
} |
|
|
|
} |
|
|
|
N3Token::IriRef(iri) => { |
|
|
|
N3Token::IriRef(iri) => { |
|
|
@ -309,16 +325,26 @@ impl RuleRecognizer for TriGRecognizer { |
|
|
|
self.stack.push(TriGState::PredicateObjectList); |
|
|
|
self.stack.push(TriGState::PredicateObjectList); |
|
|
|
self |
|
|
|
self |
|
|
|
} |
|
|
|
} |
|
|
|
N3Token::PrefixedName { prefix, local, might_be_invalid_iri } => match resolve_local_name(prefix, &local, might_be_invalid_iri, &context.prefixes) { |
|
|
|
N3Token::PrefixedName { |
|
|
|
|
|
|
|
prefix, |
|
|
|
|
|
|
|
local, |
|
|
|
|
|
|
|
might_be_invalid_iri, |
|
|
|
|
|
|
|
} => match resolve_local_name( |
|
|
|
|
|
|
|
prefix, |
|
|
|
|
|
|
|
&local, |
|
|
|
|
|
|
|
might_be_invalid_iri, |
|
|
|
|
|
|
|
&context.prefixes, |
|
|
|
|
|
|
|
) { |
|
|
|
Ok(t) => { |
|
|
|
Ok(t) => { |
|
|
|
self.cur_subject.push(t.into()); |
|
|
|
self.cur_subject.push(t.into()); |
|
|
|
self.stack.push(TriGState::PredicateObjectList); |
|
|
|
self.stack.push(TriGState::PredicateObjectList); |
|
|
|
self |
|
|
|
self |
|
|
|
}, |
|
|
|
|
|
|
|
Err(e) => self.error(errors, e) |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
Err(e) => self.error(errors, e), |
|
|
|
|
|
|
|
}, |
|
|
|
N3Token::BlankNodeLabel(label) => { |
|
|
|
N3Token::BlankNodeLabel(label) => { |
|
|
|
self.cur_subject.push(BlankNode::new_unchecked(label).into()); |
|
|
|
self.cur_subject |
|
|
|
|
|
|
|
.push(BlankNode::new_unchecked(label).into()); |
|
|
|
self.stack.push(TriGState::PredicateObjectList); |
|
|
|
self.stack.push(TriGState::PredicateObjectList); |
|
|
|
self |
|
|
|
self |
|
|
|
} |
|
|
|
} |
|
|
@ -336,17 +362,17 @@ impl RuleRecognizer for TriGRecognizer { |
|
|
|
self.stack.push(TriGState::QuotedSubject); |
|
|
|
self.stack.push(TriGState::QuotedSubject); |
|
|
|
self |
|
|
|
self |
|
|
|
} |
|
|
|
} |
|
|
|
_ => { |
|
|
|
_ => self.error(errors, "TOKEN is not a valid RDF subject"), |
|
|
|
self.error(errors, "TOKEN is not a valid RDF subject") |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}, |
|
|
|
}, |
|
|
|
TriGState::TriplesBlankNodePropertyListCurrent => if token == N3Token::Punctuation("]") { |
|
|
|
TriGState::TriplesBlankNodePropertyListCurrent => { |
|
|
|
|
|
|
|
if token == N3Token::Punctuation("]") { |
|
|
|
self.stack.push(TriGState::PredicateObjectList); |
|
|
|
self.stack.push(TriGState::PredicateObjectList); |
|
|
|
self |
|
|
|
self |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
self.stack.push(TriGState::SubjectBlankNodePropertyListEnd); |
|
|
|
self.stack.push(TriGState::SubjectBlankNodePropertyListEnd); |
|
|
|
self.stack.push(TriGState::PredicateObjectList); |
|
|
|
self.stack.push(TriGState::PredicateObjectList); |
|
|
|
self.recognize_next(token, context,results, errors) |
|
|
|
self.recognize_next(token, context, results, errors) |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
// [7g] labelOrSubject ::= iri | BlankNode
|
|
|
|
// [7g] labelOrSubject ::= iri | BlankNode
|
|
|
|
TriGState::GraphName => match token { |
|
|
|
TriGState::GraphName => match token { |
|
|
@ -354,13 +380,22 @@ impl RuleRecognizer for TriGRecognizer { |
|
|
|
self.cur_graph = NamedNode::new_unchecked(iri).into(); |
|
|
|
self.cur_graph = NamedNode::new_unchecked(iri).into(); |
|
|
|
self |
|
|
|
self |
|
|
|
} |
|
|
|
} |
|
|
|
N3Token::PrefixedName { prefix, local, might_be_invalid_iri } => match resolve_local_name(prefix, &local, might_be_invalid_iri, &context.prefixes) { |
|
|
|
N3Token::PrefixedName { |
|
|
|
|
|
|
|
prefix, |
|
|
|
|
|
|
|
local, |
|
|
|
|
|
|
|
might_be_invalid_iri, |
|
|
|
|
|
|
|
} => match resolve_local_name( |
|
|
|
|
|
|
|
prefix, |
|
|
|
|
|
|
|
&local, |
|
|
|
|
|
|
|
might_be_invalid_iri, |
|
|
|
|
|
|
|
&context.prefixes, |
|
|
|
|
|
|
|
) { |
|
|
|
Ok(t) => { |
|
|
|
Ok(t) => { |
|
|
|
self.cur_graph = t.into(); |
|
|
|
self.cur_graph = t.into(); |
|
|
|
self |
|
|
|
self |
|
|
|
}, |
|
|
|
|
|
|
|
Err(e) => self.error(errors, e) |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
Err(e) => self.error(errors, e), |
|
|
|
|
|
|
|
}, |
|
|
|
N3Token::BlankNodeLabel(label) => { |
|
|
|
N3Token::BlankNodeLabel(label) => { |
|
|
|
self.cur_graph = BlankNode::new_unchecked(label).into(); |
|
|
|
self.cur_graph = BlankNode::new_unchecked(label).into(); |
|
|
|
self |
|
|
|
self |
|
|
@ -369,64 +404,67 @@ impl RuleRecognizer for TriGRecognizer { |
|
|
|
self.stack.push(TriGState::GraphNameAnonEnd); |
|
|
|
self.stack.push(TriGState::GraphNameAnonEnd); |
|
|
|
self |
|
|
|
self |
|
|
|
} |
|
|
|
} |
|
|
|
_ => { |
|
|
|
_ => self.error(errors, "TOKEN is not a valid graph name"), |
|
|
|
self.error(errors, "TOKEN is not a valid graph name") |
|
|
|
}, |
|
|
|
} |
|
|
|
TriGState::GraphNameAnonEnd => { |
|
|
|
} |
|
|
|
if token == N3Token::Punctuation("]") { |
|
|
|
TriGState::GraphNameAnonEnd => if token == N3Token::Punctuation("]") { |
|
|
|
|
|
|
|
self.cur_graph = BlankNode::default().into(); |
|
|
|
self.cur_graph = BlankNode::default().into(); |
|
|
|
self |
|
|
|
self |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
self.error(errors, "Anonymous blank node with a property list are not allowed as graph name") |
|
|
|
self.error(errors, "Anonymous blank node with a property list are not allowed as graph name") |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
// [7] predicateObjectList ::= verb objectList (';' (verb objectList)?)*
|
|
|
|
// [7] predicateObjectList ::= verb objectList (';' (verb objectList)?)*
|
|
|
|
TriGState::PredicateObjectList => { |
|
|
|
TriGState::PredicateObjectList => { |
|
|
|
self.stack.push(TriGState::PredicateObjectListEnd); |
|
|
|
self.stack.push(TriGState::PredicateObjectListEnd); |
|
|
|
self.stack.push(TriGState::ObjectsList); |
|
|
|
self.stack.push(TriGState::ObjectsList); |
|
|
|
self.stack.push(TriGState::Verb); |
|
|
|
self.stack.push(TriGState::Verb); |
|
|
|
self.recognize_next(token, context,results, errors) |
|
|
|
self.recognize_next(token, context, results, errors) |
|
|
|
}, |
|
|
|
} |
|
|
|
TriGState::PredicateObjectListEnd => { |
|
|
|
TriGState::PredicateObjectListEnd => { |
|
|
|
self.cur_predicate.pop(); |
|
|
|
self.cur_predicate.pop(); |
|
|
|
if token == N3Token::Punctuation(";") { |
|
|
|
if token == N3Token::Punctuation(";") { |
|
|
|
self.stack.push(TriGState::PredicateObjectListPossibleContinuation); |
|
|
|
self.stack |
|
|
|
|
|
|
|
.push(TriGState::PredicateObjectListPossibleContinuation); |
|
|
|
self |
|
|
|
self |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
self.recognize_next(token, context,results, errors) |
|
|
|
self.recognize_next(token, context, results, errors) |
|
|
|
} |
|
|
|
} |
|
|
|
}, |
|
|
|
} |
|
|
|
TriGState::PredicateObjectListPossibleContinuation => if token == N3Token::Punctuation(";") { |
|
|
|
TriGState::PredicateObjectListPossibleContinuation => { |
|
|
|
self.stack.push(TriGState::PredicateObjectListPossibleContinuation); |
|
|
|
if token == N3Token::Punctuation(";") { |
|
|
|
|
|
|
|
self.stack |
|
|
|
|
|
|
|
.push(TriGState::PredicateObjectListPossibleContinuation); |
|
|
|
self |
|
|
|
self |
|
|
|
} else if matches!(token, N3Token::Punctuation("." | "}" | "]")) { |
|
|
|
} else if matches!(token, N3Token::Punctuation("." | "}" | "]")) { |
|
|
|
self.recognize_next(token, context,results, errors) |
|
|
|
self.recognize_next(token, context, results, errors) |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
self.stack.push(TriGState::PredicateObjectListEnd); |
|
|
|
self.stack.push(TriGState::PredicateObjectListEnd); |
|
|
|
self.stack.push(TriGState::ObjectsList); |
|
|
|
self.stack.push(TriGState::ObjectsList); |
|
|
|
self.stack.push(TriGState::Verb); |
|
|
|
self.stack.push(TriGState::Verb); |
|
|
|
self.recognize_next(token, context,results, errors) |
|
|
|
self.recognize_next(token, context, results, errors) |
|
|
|
}, |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
// [8] objectList ::= object annotation? ( ',' object annotation? )*
|
|
|
|
// [8] objectList ::= object annotation? ( ',' object annotation? )*
|
|
|
|
// [30t] annotation ::= '{|' predicateObjectList '|}'
|
|
|
|
// [30t] annotation ::= '{|' predicateObjectList '|}'
|
|
|
|
TriGState::ObjectsList => { |
|
|
|
TriGState::ObjectsList => { |
|
|
|
self.stack.push(TriGState::ObjectsListEnd); |
|
|
|
self.stack.push(TriGState::ObjectsListEnd); |
|
|
|
self.stack.push(TriGState::Object); |
|
|
|
self.stack.push(TriGState::Object); |
|
|
|
self.recognize_next(token, context,results, errors) |
|
|
|
self.recognize_next(token, context, results, errors) |
|
|
|
} |
|
|
|
} |
|
|
|
TriGState::ObjectsListEnd => { |
|
|
|
TriGState::ObjectsListEnd => match token { |
|
|
|
match token { |
|
|
|
|
|
|
|
N3Token::Punctuation(",") => { |
|
|
|
N3Token::Punctuation(",") => { |
|
|
|
self.cur_object.pop(); |
|
|
|
self.cur_object.pop(); |
|
|
|
self.stack.push(TriGState::ObjectsListEnd); |
|
|
|
self.stack.push(TriGState::ObjectsListEnd); |
|
|
|
self.stack.push(TriGState::Object); |
|
|
|
self.stack.push(TriGState::Object); |
|
|
|
self |
|
|
|
self |
|
|
|
}, |
|
|
|
} |
|
|
|
#[cfg(feature = "rdf-star")] |
|
|
|
#[cfg(feature = "rdf-star")] |
|
|
|
N3Token::Punctuation("{|") => { |
|
|
|
N3Token::Punctuation("{|") => { |
|
|
|
let triple = Triple::new( |
|
|
|
let triple = Triple::new( |
|
|
|
self.cur_subject.last().unwrap().clone(), |
|
|
|
self.cur_subject.last().unwrap().clone(), |
|
|
|
self.cur_predicate.last().unwrap().clone(), |
|
|
|
self.cur_predicate.last().unwrap().clone(), |
|
|
|
self.cur_object.pop().unwrap() |
|
|
|
self.cur_object.pop().unwrap(), |
|
|
|
); |
|
|
|
); |
|
|
|
self.cur_subject.push(triple.into()); |
|
|
|
self.cur_subject.push(triple.into()); |
|
|
|
self.stack.push(TriGState::AnnotationEnd); |
|
|
|
self.stack.push(TriGState::AnnotationEnd); |
|
|
@ -435,8 +473,7 @@ impl RuleRecognizer for TriGRecognizer { |
|
|
|
} |
|
|
|
} |
|
|
|
_ => { |
|
|
|
_ => { |
|
|
|
self.cur_object.pop(); |
|
|
|
self.cur_object.pop(); |
|
|
|
self.recognize_next(token, context,results, errors) |
|
|
|
self.recognize_next(token, context, results, errors) |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
}, |
|
|
|
}, |
|
|
|
#[cfg(feature = "rdf-star")] |
|
|
|
#[cfg(feature = "rdf-star")] |
|
|
@ -448,15 +485,17 @@ impl RuleRecognizer for TriGRecognizer { |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
self.error(errors, "Annotations should end with '|}'") |
|
|
|
self.error(errors, "Annotations should end with '|}'") |
|
|
|
} |
|
|
|
} |
|
|
|
}, |
|
|
|
} |
|
|
|
#[cfg(feature = "rdf-star")] |
|
|
|
#[cfg(feature = "rdf-star")] |
|
|
|
TriGState::ObjectsListAfterAnnotation => if token == N3Token::Punctuation(",") { |
|
|
|
TriGState::ObjectsListAfterAnnotation => { |
|
|
|
|
|
|
|
if token == N3Token::Punctuation(",") { |
|
|
|
self.stack.push(TriGState::ObjectsListEnd); |
|
|
|
self.stack.push(TriGState::ObjectsListEnd); |
|
|
|
self.stack.push(TriGState::Object); |
|
|
|
self.stack.push(TriGState::Object); |
|
|
|
self |
|
|
|
self |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
self.recognize_next(token, context,results, errors) |
|
|
|
self.recognize_next(token, context, results, errors) |
|
|
|
}, |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
// [9] verb ::= predicate | 'a'
|
|
|
|
// [9] verb ::= predicate | 'a'
|
|
|
|
// [11] predicate ::= iri
|
|
|
|
// [11] predicate ::= iri
|
|
|
|
TriGState::Verb => match token { |
|
|
|
TriGState::Verb => match token { |
|
|
@ -468,17 +507,24 @@ impl RuleRecognizer for TriGRecognizer { |
|
|
|
self.cur_predicate.push(NamedNode::new_unchecked(iri)); |
|
|
|
self.cur_predicate.push(NamedNode::new_unchecked(iri)); |
|
|
|
self |
|
|
|
self |
|
|
|
} |
|
|
|
} |
|
|
|
N3Token::PrefixedName { prefix, local, might_be_invalid_iri } => match resolve_local_name(prefix, &local, might_be_invalid_iri, &context.prefixes) { |
|
|
|
N3Token::PrefixedName { |
|
|
|
|
|
|
|
prefix, |
|
|
|
|
|
|
|
local, |
|
|
|
|
|
|
|
might_be_invalid_iri, |
|
|
|
|
|
|
|
} => match resolve_local_name( |
|
|
|
|
|
|
|
prefix, |
|
|
|
|
|
|
|
&local, |
|
|
|
|
|
|
|
might_be_invalid_iri, |
|
|
|
|
|
|
|
&context.prefixes, |
|
|
|
|
|
|
|
) { |
|
|
|
Ok(t) => { |
|
|
|
Ok(t) => { |
|
|
|
self.cur_predicate.push(t); |
|
|
|
self.cur_predicate.push(t); |
|
|
|
self |
|
|
|
self |
|
|
|
}, |
|
|
|
|
|
|
|
Err(e) => self.error(errors, e) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
_ => { |
|
|
|
|
|
|
|
self.error(errors, "TOKEN is not a valid predicate") |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
Err(e) => self.error(errors, e), |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
_ => self.error(errors, "TOKEN is not a valid predicate"), |
|
|
|
|
|
|
|
}, |
|
|
|
// [12] object ::= iri | BlankNode | collection | blankNodePropertyList | literal | quotedTriple
|
|
|
|
// [12] object ::= iri | BlankNode | collection | blankNodePropertyList | literal | quotedTriple
|
|
|
|
// [13] literal ::= RDFLiteral | NumericLiteral | BooleanLiteral
|
|
|
|
// [13] literal ::= RDFLiteral | NumericLiteral | BooleanLiteral
|
|
|
|
// [14] blank ::= BlankNode | collection
|
|
|
|
// [14] blank ::= BlankNode | collection
|
|
|
@ -497,21 +543,31 @@ impl RuleRecognizer for TriGRecognizer { |
|
|
|
self.emit_quad(results); |
|
|
|
self.emit_quad(results); |
|
|
|
self |
|
|
|
self |
|
|
|
} |
|
|
|
} |
|
|
|
N3Token::PrefixedName { prefix, local, might_be_invalid_iri } => match resolve_local_name(prefix, &local, might_be_invalid_iri, &context.prefixes) { |
|
|
|
N3Token::PrefixedName { |
|
|
|
|
|
|
|
prefix, |
|
|
|
|
|
|
|
local, |
|
|
|
|
|
|
|
might_be_invalid_iri, |
|
|
|
|
|
|
|
} => match resolve_local_name( |
|
|
|
|
|
|
|
prefix, |
|
|
|
|
|
|
|
&local, |
|
|
|
|
|
|
|
might_be_invalid_iri, |
|
|
|
|
|
|
|
&context.prefixes, |
|
|
|
|
|
|
|
) { |
|
|
|
Ok(t) => { |
|
|
|
Ok(t) => { |
|
|
|
self.cur_object.push(t.into()); |
|
|
|
self.cur_object.push(t.into()); |
|
|
|
self.emit_quad(results); |
|
|
|
self.emit_quad(results); |
|
|
|
self |
|
|
|
self |
|
|
|
}, |
|
|
|
|
|
|
|
Err(e) => self.error(errors, e) |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
Err(e) => self.error(errors, e), |
|
|
|
|
|
|
|
}, |
|
|
|
N3Token::BlankNodeLabel(label) => { |
|
|
|
N3Token::BlankNodeLabel(label) => { |
|
|
|
self.cur_object.push(BlankNode::new_unchecked(label).into()); |
|
|
|
self.cur_object.push(BlankNode::new_unchecked(label).into()); |
|
|
|
self.emit_quad(results); |
|
|
|
self.emit_quad(results); |
|
|
|
self |
|
|
|
self |
|
|
|
} |
|
|
|
} |
|
|
|
N3Token::Punctuation("[") => { |
|
|
|
N3Token::Punctuation("[") => { |
|
|
|
self.stack.push(TriGState::ObjectBlankNodePropertyListCurrent); |
|
|
|
self.stack |
|
|
|
|
|
|
|
.push(TriGState::ObjectBlankNodePropertyListCurrent); |
|
|
|
self |
|
|
|
self |
|
|
|
} |
|
|
|
} |
|
|
|
N3Token::Punctuation("(") => { |
|
|
|
N3Token::Punctuation("(") => { |
|
|
@ -519,48 +575,53 @@ impl RuleRecognizer for TriGRecognizer { |
|
|
|
self |
|
|
|
self |
|
|
|
} |
|
|
|
} |
|
|
|
N3Token::String(value) => { |
|
|
|
N3Token::String(value) => { |
|
|
|
self.stack.push(TriGState::LiteralPossibleSuffix { value, emit: true }); |
|
|
|
self.stack |
|
|
|
|
|
|
|
.push(TriGState::LiteralPossibleSuffix { value, emit: true }); |
|
|
|
self |
|
|
|
self |
|
|
|
} |
|
|
|
} |
|
|
|
N3Token::Integer(v) => { |
|
|
|
N3Token::Integer(v) => { |
|
|
|
self.cur_object.push(Literal::new_typed_literal(v, xsd::INTEGER).into()); |
|
|
|
self.cur_object |
|
|
|
|
|
|
|
.push(Literal::new_typed_literal(v, xsd::INTEGER).into()); |
|
|
|
self.emit_quad(results); |
|
|
|
self.emit_quad(results); |
|
|
|
self |
|
|
|
self |
|
|
|
} |
|
|
|
} |
|
|
|
N3Token::Decimal(v) => { |
|
|
|
N3Token::Decimal(v) => { |
|
|
|
self.cur_object.push(Literal::new_typed_literal(v, xsd::DECIMAL).into()); |
|
|
|
self.cur_object |
|
|
|
|
|
|
|
.push(Literal::new_typed_literal(v, xsd::DECIMAL).into()); |
|
|
|
self.emit_quad(results); |
|
|
|
self.emit_quad(results); |
|
|
|
self |
|
|
|
self |
|
|
|
} |
|
|
|
} |
|
|
|
N3Token::Double(v) => { |
|
|
|
N3Token::Double(v) => { |
|
|
|
self.cur_object.push(Literal::new_typed_literal(v, xsd::DOUBLE).into()); |
|
|
|
self.cur_object |
|
|
|
|
|
|
|
.push(Literal::new_typed_literal(v, xsd::DOUBLE).into()); |
|
|
|
self.emit_quad(results); |
|
|
|
self.emit_quad(results); |
|
|
|
self |
|
|
|
self |
|
|
|
} |
|
|
|
} |
|
|
|
N3Token::PlainKeyword("true") => { |
|
|
|
N3Token::PlainKeyword("true") => { |
|
|
|
self.cur_object.push(Literal::new_typed_literal("true", xsd::BOOLEAN).into()); |
|
|
|
self.cur_object |
|
|
|
|
|
|
|
.push(Literal::new_typed_literal("true", xsd::BOOLEAN).into()); |
|
|
|
self.emit_quad(results); |
|
|
|
self.emit_quad(results); |
|
|
|
self |
|
|
|
self |
|
|
|
} |
|
|
|
} |
|
|
|
N3Token::PlainKeyword("false") => { |
|
|
|
N3Token::PlainKeyword("false") => { |
|
|
|
self.cur_object.push(Literal::new_typed_literal("false", xsd::BOOLEAN).into()); |
|
|
|
self.cur_object |
|
|
|
|
|
|
|
.push(Literal::new_typed_literal("false", xsd::BOOLEAN).into()); |
|
|
|
self.emit_quad(results); |
|
|
|
self.emit_quad(results); |
|
|
|
self |
|
|
|
self |
|
|
|
} |
|
|
|
} |
|
|
|
#[cfg(feature = "rdf-star")] |
|
|
|
#[cfg(feature = "rdf-star")] |
|
|
|
N3Token::Punctuation("<<") if context.with_quoted_triples => { |
|
|
|
N3Token::Punctuation("<<") if context.with_quoted_triples => { |
|
|
|
self.stack.push(TriGState::ObjectQuotedTripleEnd { emit: true }); |
|
|
|
self.stack |
|
|
|
|
|
|
|
.push(TriGState::ObjectQuotedTripleEnd { emit: true }); |
|
|
|
self.stack.push(TriGState::QuotedObject); |
|
|
|
self.stack.push(TriGState::QuotedObject); |
|
|
|
self.stack.push(TriGState::Verb); |
|
|
|
self.stack.push(TriGState::Verb); |
|
|
|
self.stack.push(TriGState::QuotedSubject); |
|
|
|
self.stack.push(TriGState::QuotedSubject); |
|
|
|
self |
|
|
|
self |
|
|
|
} |
|
|
|
} |
|
|
|
_ => { |
|
|
|
_ => self.error(errors, "TOKEN is not a valid RDF object"), |
|
|
|
self.error(errors, "TOKEN is not a valid RDF object") |
|
|
|
}, |
|
|
|
} |
|
|
|
TriGState::ObjectBlankNodePropertyListCurrent => { |
|
|
|
|
|
|
|
if token == N3Token::Punctuation("]") { |
|
|
|
} |
|
|
|
|
|
|
|
TriGState::ObjectBlankNodePropertyListCurrent => if token == N3Token::Punctuation("]") { |
|
|
|
|
|
|
|
self.cur_object.push(BlankNode::default().into()); |
|
|
|
self.cur_object.push(BlankNode::default().into()); |
|
|
|
self.emit_quad(results); |
|
|
|
self.emit_quad(results); |
|
|
|
self |
|
|
|
self |
|
|
@ -568,16 +629,20 @@ impl RuleRecognizer for TriGRecognizer { |
|
|
|
self.cur_subject.push(BlankNode::default().into()); |
|
|
|
self.cur_subject.push(BlankNode::default().into()); |
|
|
|
self.stack.push(TriGState::ObjectBlankNodePropertyListEnd); |
|
|
|
self.stack.push(TriGState::ObjectBlankNodePropertyListEnd); |
|
|
|
self.stack.push(TriGState::PredicateObjectList); |
|
|
|
self.stack.push(TriGState::PredicateObjectList); |
|
|
|
self.recognize_next(token, context,results, errors) |
|
|
|
self.recognize_next(token, context, results, errors) |
|
|
|
} |
|
|
|
} |
|
|
|
TriGState::ObjectBlankNodePropertyListEnd => if token == N3Token::Punctuation("]") { |
|
|
|
} |
|
|
|
|
|
|
|
TriGState::ObjectBlankNodePropertyListEnd => { |
|
|
|
|
|
|
|
if token == N3Token::Punctuation("]") { |
|
|
|
self.cur_object.push(self.cur_subject.pop().unwrap().into()); |
|
|
|
self.cur_object.push(self.cur_subject.pop().unwrap().into()); |
|
|
|
self.emit_quad(results); |
|
|
|
self.emit_quad(results); |
|
|
|
self |
|
|
|
self |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
self.error(errors, "blank node property lists should end with a ']'") |
|
|
|
self.error(errors, "blank node property lists should end with a ']'") |
|
|
|
} |
|
|
|
} |
|
|
|
TriGState::ObjectCollectionBeginning => if let N3Token::Punctuation(")") = token { |
|
|
|
} |
|
|
|
|
|
|
|
TriGState::ObjectCollectionBeginning => { |
|
|
|
|
|
|
|
if let N3Token::Punctuation(")") = token { |
|
|
|
self.cur_object.push(rdf::NIL.into()); |
|
|
|
self.cur_object.push(rdf::NIL.into()); |
|
|
|
self.emit_quad(results); |
|
|
|
self.emit_quad(results); |
|
|
|
self |
|
|
|
self |
|
|
@ -589,91 +654,109 @@ impl RuleRecognizer for TriGRecognizer { |
|
|
|
self.cur_predicate.push(rdf::FIRST.into()); |
|
|
|
self.cur_predicate.push(rdf::FIRST.into()); |
|
|
|
self.stack.push(TriGState::ObjectCollectionPossibleEnd); |
|
|
|
self.stack.push(TriGState::ObjectCollectionPossibleEnd); |
|
|
|
self.stack.push(TriGState::Object); |
|
|
|
self.stack.push(TriGState::Object); |
|
|
|
self.recognize_next(token, context,results, errors) |
|
|
|
self.recognize_next(token, context, results, errors) |
|
|
|
}, |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
TriGState::ObjectCollectionPossibleEnd => { |
|
|
|
TriGState::ObjectCollectionPossibleEnd => { |
|
|
|
let old = self.cur_subject.pop().unwrap(); |
|
|
|
let old = self.cur_subject.pop().unwrap(); |
|
|
|
self.cur_object.pop(); |
|
|
|
self.cur_object.pop(); |
|
|
|
if let N3Token::Punctuation(")") = token { |
|
|
|
if let N3Token::Punctuation(")") = token { |
|
|
|
self.cur_predicate.pop(); |
|
|
|
self.cur_predicate.pop(); |
|
|
|
results.push(Quad::new(old, |
|
|
|
results.push(Quad::new(old, rdf::REST, rdf::NIL, self.cur_graph.clone())); |
|
|
|
rdf::REST, |
|
|
|
|
|
|
|
rdf::NIL, |
|
|
|
|
|
|
|
self.cur_graph.clone() |
|
|
|
|
|
|
|
)); |
|
|
|
|
|
|
|
self |
|
|
|
self |
|
|
|
}else { |
|
|
|
} else { |
|
|
|
let new = BlankNode::default(); |
|
|
|
let new = BlankNode::default(); |
|
|
|
results.push(Quad::new(old, |
|
|
|
results.push(Quad::new( |
|
|
|
|
|
|
|
old, |
|
|
|
rdf::REST, |
|
|
|
rdf::REST, |
|
|
|
new.clone(), |
|
|
|
new.clone(), |
|
|
|
self.cur_graph.clone() |
|
|
|
self.cur_graph.clone(), |
|
|
|
)); |
|
|
|
)); |
|
|
|
self.cur_subject.push(new.into()); |
|
|
|
self.cur_subject.push(new.into()); |
|
|
|
self.stack.push(TriGState::ObjectCollectionPossibleEnd); |
|
|
|
self.stack.push(TriGState::ObjectCollectionPossibleEnd); |
|
|
|
self.stack.push(TriGState::Object); |
|
|
|
self.stack.push(TriGState::Object); |
|
|
|
self.recognize_next(token, context,results, errors) |
|
|
|
self.recognize_next(token, context, results, errors) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
TriGState::LiteralPossibleSuffix { value, emit } => { |
|
|
|
TriGState::LiteralPossibleSuffix { value, emit } => match token { |
|
|
|
match token { |
|
|
|
|
|
|
|
N3Token::LangTag(lang) => { |
|
|
|
N3Token::LangTag(lang) => { |
|
|
|
self.cur_object.push(Literal::new_language_tagged_literal_unchecked(value, lang.to_ascii_lowercase()).into()); |
|
|
|
self.cur_object.push( |
|
|
|
|
|
|
|
Literal::new_language_tagged_literal_unchecked( |
|
|
|
|
|
|
|
value, |
|
|
|
|
|
|
|
lang.to_ascii_lowercase(), |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
.into(), |
|
|
|
|
|
|
|
); |
|
|
|
if emit { |
|
|
|
if emit { |
|
|
|
self.emit_quad(results); |
|
|
|
self.emit_quad(results); |
|
|
|
} |
|
|
|
} |
|
|
|
self |
|
|
|
self |
|
|
|
}, |
|
|
|
} |
|
|
|
N3Token::Punctuation("^^") => { |
|
|
|
N3Token::Punctuation("^^") => { |
|
|
|
self.stack.push(TriGState::LiteralExpectDatatype { value, emit }); |
|
|
|
self.stack |
|
|
|
|
|
|
|
.push(TriGState::LiteralExpectDatatype { value, emit }); |
|
|
|
self |
|
|
|
self |
|
|
|
} |
|
|
|
} |
|
|
|
_ => { |
|
|
|
_ => { |
|
|
|
self.cur_object.push(Literal::new_simple_literal(value).into()); |
|
|
|
self.cur_object |
|
|
|
|
|
|
|
.push(Literal::new_simple_literal(value).into()); |
|
|
|
if emit { |
|
|
|
if emit { |
|
|
|
self.emit_quad(results); |
|
|
|
self.emit_quad(results); |
|
|
|
} |
|
|
|
} |
|
|
|
self.recognize_next(token, context,results, errors) |
|
|
|
self.recognize_next(token, context, results, errors) |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
TriGState::LiteralExpectDatatype { value, emit } => { |
|
|
|
}, |
|
|
|
match token { |
|
|
|
TriGState::LiteralExpectDatatype { value, emit } => match token { |
|
|
|
N3Token::IriRef(datatype) => { |
|
|
|
N3Token::IriRef(datatype) => { |
|
|
|
self.cur_object.push(Literal::new_typed_literal(value, NamedNode::new_unchecked(datatype)).into()); |
|
|
|
self.cur_object.push( |
|
|
|
|
|
|
|
Literal::new_typed_literal(value, NamedNode::new_unchecked(datatype)) |
|
|
|
|
|
|
|
.into(), |
|
|
|
|
|
|
|
); |
|
|
|
if emit { |
|
|
|
if emit { |
|
|
|
self.emit_quad(results); |
|
|
|
self.emit_quad(results); |
|
|
|
} |
|
|
|
} |
|
|
|
self |
|
|
|
self |
|
|
|
}, |
|
|
|
} |
|
|
|
N3Token::PrefixedName { prefix, local, might_be_invalid_iri } => match resolve_local_name(prefix, &local, might_be_invalid_iri, &context.prefixes) { |
|
|
|
N3Token::PrefixedName { |
|
|
|
|
|
|
|
prefix, |
|
|
|
|
|
|
|
local, |
|
|
|
|
|
|
|
might_be_invalid_iri, |
|
|
|
|
|
|
|
} => match resolve_local_name( |
|
|
|
|
|
|
|
prefix, |
|
|
|
|
|
|
|
&local, |
|
|
|
|
|
|
|
might_be_invalid_iri, |
|
|
|
|
|
|
|
&context.prefixes, |
|
|
|
|
|
|
|
) { |
|
|
|
Ok(t) => { |
|
|
|
Ok(t) => { |
|
|
|
self.cur_object.push(Literal::new_typed_literal(value, t).into()); |
|
|
|
self.cur_object |
|
|
|
|
|
|
|
.push(Literal::new_typed_literal(value, t).into()); |
|
|
|
if emit { |
|
|
|
if emit { |
|
|
|
self.emit_quad(results); |
|
|
|
self.emit_quad(results); |
|
|
|
} |
|
|
|
} |
|
|
|
self |
|
|
|
self |
|
|
|
}, |
|
|
|
|
|
|
|
Err(e) => self.error(errors, e) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
_ => { |
|
|
|
|
|
|
|
self.error(errors, "Expecting a datatype IRI after ^^, found TOKEN").recognize_next(token, context, results, errors) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
Err(e) => self.error(errors, e), |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
_ => self |
|
|
|
|
|
|
|
.error(errors, "Expecting a datatype IRI after ^^, found TOKEN") |
|
|
|
|
|
|
|
.recognize_next(token, context, results, errors), |
|
|
|
|
|
|
|
}, |
|
|
|
// [27t] quotedTriple ::= '<<' qtSubject verb qtObject '>>'
|
|
|
|
// [27t] quotedTriple ::= '<<' qtSubject verb qtObject '>>'
|
|
|
|
#[cfg(feature = "rdf-star")] |
|
|
|
#[cfg(feature = "rdf-star")] |
|
|
|
TriGState::SubjectQuotedTripleEnd => { |
|
|
|
TriGState::SubjectQuotedTripleEnd => { |
|
|
|
let triple = Triple::new( |
|
|
|
let triple = Triple::new( |
|
|
|
self.cur_subject.pop().unwrap(), |
|
|
|
self.cur_subject.pop().unwrap(), |
|
|
|
self.cur_predicate.pop().unwrap(), |
|
|
|
self.cur_predicate.pop().unwrap(), |
|
|
|
self.cur_object.pop().unwrap() |
|
|
|
self.cur_object.pop().unwrap(), |
|
|
|
); |
|
|
|
); |
|
|
|
self.cur_subject.push(triple.into()); |
|
|
|
self.cur_subject.push(triple.into()); |
|
|
|
if token == N3Token::Punctuation(">>") { |
|
|
|
if token == N3Token::Punctuation(">>") { |
|
|
|
self |
|
|
|
self |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
self.error(errors, "Expecting '>>' to close a quoted triple, found TOKEN") |
|
|
|
self.error( |
|
|
|
|
|
|
|
errors, |
|
|
|
|
|
|
|
"Expecting '>>' to close a quoted triple, found TOKEN", |
|
|
|
|
|
|
|
) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
#[cfg(feature = "rdf-star")] |
|
|
|
#[cfg(feature = "rdf-star")] |
|
|
@ -681,7 +764,7 @@ impl RuleRecognizer for TriGRecognizer { |
|
|
|
let triple = Triple::new( |
|
|
|
let triple = Triple::new( |
|
|
|
self.cur_subject.pop().unwrap(), |
|
|
|
self.cur_subject.pop().unwrap(), |
|
|
|
self.cur_predicate.pop().unwrap(), |
|
|
|
self.cur_predicate.pop().unwrap(), |
|
|
|
self.cur_object.pop().unwrap() |
|
|
|
self.cur_object.pop().unwrap(), |
|
|
|
); |
|
|
|
); |
|
|
|
self.cur_object.push(triple.into()); |
|
|
|
self.cur_object.push(triple.into()); |
|
|
|
if emit { |
|
|
|
if emit { |
|
|
@ -690,7 +773,10 @@ impl RuleRecognizer for TriGRecognizer { |
|
|
|
if token == N3Token::Punctuation(">>") { |
|
|
|
if token == N3Token::Punctuation(">>") { |
|
|
|
self |
|
|
|
self |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
self.error(errors, "Expecting '>>' to close a quoted triple, found TOKEN") |
|
|
|
self.error( |
|
|
|
|
|
|
|
errors, |
|
|
|
|
|
|
|
"Expecting '>>' to close a quoted triple, found TOKEN", |
|
|
|
|
|
|
|
) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
// [28t] qtSubject ::= iri | BlankNode | quotedTriple
|
|
|
|
// [28t] qtSubject ::= iri | BlankNode | quotedTriple
|
|
|
@ -705,15 +791,25 @@ impl RuleRecognizer for TriGRecognizer { |
|
|
|
self.cur_subject.push(NamedNode::new_unchecked(iri).into()); |
|
|
|
self.cur_subject.push(NamedNode::new_unchecked(iri).into()); |
|
|
|
self |
|
|
|
self |
|
|
|
} |
|
|
|
} |
|
|
|
N3Token::PrefixedName { prefix, local, might_be_invalid_iri } => match resolve_local_name(prefix, &local, might_be_invalid_iri, &context.prefixes) { |
|
|
|
N3Token::PrefixedName { |
|
|
|
|
|
|
|
prefix, |
|
|
|
|
|
|
|
local, |
|
|
|
|
|
|
|
might_be_invalid_iri, |
|
|
|
|
|
|
|
} => match resolve_local_name( |
|
|
|
|
|
|
|
prefix, |
|
|
|
|
|
|
|
&local, |
|
|
|
|
|
|
|
might_be_invalid_iri, |
|
|
|
|
|
|
|
&context.prefixes, |
|
|
|
|
|
|
|
) { |
|
|
|
Ok(t) => { |
|
|
|
Ok(t) => { |
|
|
|
self.cur_subject.push(t.into()); |
|
|
|
self.cur_subject.push(t.into()); |
|
|
|
self |
|
|
|
self |
|
|
|
}, |
|
|
|
|
|
|
|
Err(e) => self.error(errors, e) |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
Err(e) => self.error(errors, e), |
|
|
|
|
|
|
|
}, |
|
|
|
N3Token::BlankNodeLabel(label) => { |
|
|
|
N3Token::BlankNodeLabel(label) => { |
|
|
|
self.cur_subject.push(BlankNode::new_unchecked(label).into()); |
|
|
|
self.cur_subject |
|
|
|
|
|
|
|
.push(BlankNode::new_unchecked(label).into()); |
|
|
|
self |
|
|
|
self |
|
|
|
} |
|
|
|
} |
|
|
|
N3Token::Punctuation("<<") => { |
|
|
|
N3Token::Punctuation("<<") => { |
|
|
@ -723,8 +819,11 @@ impl RuleRecognizer for TriGRecognizer { |
|
|
|
self.stack.push(TriGState::QuotedSubject); |
|
|
|
self.stack.push(TriGState::QuotedSubject); |
|
|
|
self |
|
|
|
self |
|
|
|
} |
|
|
|
} |
|
|
|
_ => self.error(errors, "TOKEN is not a valid RDF quoted triple subject: TOKEN") |
|
|
|
_ => self.error( |
|
|
|
} |
|
|
|
errors, |
|
|
|
|
|
|
|
"TOKEN is not a valid RDF quoted triple subject: TOKEN", |
|
|
|
|
|
|
|
), |
|
|
|
|
|
|
|
}, |
|
|
|
// [29t] qtObject ::= iri | BlankNode | literal | quotedTriple
|
|
|
|
// [29t] qtObject ::= iri | BlankNode | literal | quotedTriple
|
|
|
|
#[cfg(feature = "rdf-star")] |
|
|
|
#[cfg(feature = "rdf-star")] |
|
|
|
TriGState::QuotedObject => match token { |
|
|
|
TriGState::QuotedObject => match token { |
|
|
@ -737,57 +836,75 @@ impl RuleRecognizer for TriGRecognizer { |
|
|
|
self.cur_object.push(NamedNode::new_unchecked(iri).into()); |
|
|
|
self.cur_object.push(NamedNode::new_unchecked(iri).into()); |
|
|
|
self |
|
|
|
self |
|
|
|
} |
|
|
|
} |
|
|
|
N3Token::PrefixedName { prefix, local, might_be_invalid_iri } => match resolve_local_name(prefix, &local, might_be_invalid_iri, &context.prefixes) { |
|
|
|
N3Token::PrefixedName { |
|
|
|
|
|
|
|
prefix, |
|
|
|
|
|
|
|
local, |
|
|
|
|
|
|
|
might_be_invalid_iri, |
|
|
|
|
|
|
|
} => match resolve_local_name( |
|
|
|
|
|
|
|
prefix, |
|
|
|
|
|
|
|
&local, |
|
|
|
|
|
|
|
might_be_invalid_iri, |
|
|
|
|
|
|
|
&context.prefixes, |
|
|
|
|
|
|
|
) { |
|
|
|
Ok(t) => { |
|
|
|
Ok(t) => { |
|
|
|
self.cur_object.push(t.into()); |
|
|
|
self.cur_object.push(t.into()); |
|
|
|
self |
|
|
|
self |
|
|
|
}, |
|
|
|
|
|
|
|
Err(e) => self.error(errors, e) |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
Err(e) => self.error(errors, e), |
|
|
|
|
|
|
|
}, |
|
|
|
N3Token::BlankNodeLabel(label) => { |
|
|
|
N3Token::BlankNodeLabel(label) => { |
|
|
|
self.cur_object.push(BlankNode::new_unchecked(label).into()); |
|
|
|
self.cur_object.push(BlankNode::new_unchecked(label).into()); |
|
|
|
self |
|
|
|
self |
|
|
|
} |
|
|
|
} |
|
|
|
N3Token::String(value) => { |
|
|
|
N3Token::String(value) => { |
|
|
|
self.stack.push(TriGState::LiteralPossibleSuffix { value, emit: false }); |
|
|
|
self.stack |
|
|
|
|
|
|
|
.push(TriGState::LiteralPossibleSuffix { value, emit: false }); |
|
|
|
self |
|
|
|
self |
|
|
|
} |
|
|
|
} |
|
|
|
N3Token::Integer(v) => { |
|
|
|
N3Token::Integer(v) => { |
|
|
|
self.cur_object.push(Literal::new_typed_literal(v, xsd::INTEGER).into()); |
|
|
|
self.cur_object |
|
|
|
|
|
|
|
.push(Literal::new_typed_literal(v, xsd::INTEGER).into()); |
|
|
|
self |
|
|
|
self |
|
|
|
} |
|
|
|
} |
|
|
|
N3Token::Decimal(v) => { |
|
|
|
N3Token::Decimal(v) => { |
|
|
|
self.cur_object.push(Literal::new_typed_literal(v, xsd::DECIMAL).into()); |
|
|
|
self.cur_object |
|
|
|
|
|
|
|
.push(Literal::new_typed_literal(v, xsd::DECIMAL).into()); |
|
|
|
self |
|
|
|
self |
|
|
|
} |
|
|
|
} |
|
|
|
N3Token::Double(v) => { |
|
|
|
N3Token::Double(v) => { |
|
|
|
self.cur_object.push(Literal::new_typed_literal(v, xsd::DOUBLE).into()); |
|
|
|
self.cur_object |
|
|
|
|
|
|
|
.push(Literal::new_typed_literal(v, xsd::DOUBLE).into()); |
|
|
|
self |
|
|
|
self |
|
|
|
} |
|
|
|
} |
|
|
|
N3Token::PlainKeyword("true") => { |
|
|
|
N3Token::PlainKeyword("true") => { |
|
|
|
self.cur_object.push(Literal::new_typed_literal("true", xsd::BOOLEAN).into()); |
|
|
|
self.cur_object |
|
|
|
|
|
|
|
.push(Literal::new_typed_literal("true", xsd::BOOLEAN).into()); |
|
|
|
self |
|
|
|
self |
|
|
|
} |
|
|
|
} |
|
|
|
N3Token::PlainKeyword("false") => { |
|
|
|
N3Token::PlainKeyword("false") => { |
|
|
|
self.cur_object.push(Literal::new_typed_literal("false", xsd::BOOLEAN).into()); |
|
|
|
self.cur_object |
|
|
|
|
|
|
|
.push(Literal::new_typed_literal("false", xsd::BOOLEAN).into()); |
|
|
|
self |
|
|
|
self |
|
|
|
} |
|
|
|
} |
|
|
|
N3Token::Punctuation("<<") => { |
|
|
|
N3Token::Punctuation("<<") => { |
|
|
|
self.stack.push(TriGState::ObjectQuotedTripleEnd { emit: false }); |
|
|
|
self.stack |
|
|
|
|
|
|
|
.push(TriGState::ObjectQuotedTripleEnd { emit: false }); |
|
|
|
self.stack.push(TriGState::QuotedObject); |
|
|
|
self.stack.push(TriGState::QuotedObject); |
|
|
|
self.stack.push(TriGState::Verb); |
|
|
|
self.stack.push(TriGState::Verb); |
|
|
|
self.stack.push(TriGState::QuotedSubject); |
|
|
|
self.stack.push(TriGState::QuotedSubject); |
|
|
|
self |
|
|
|
self |
|
|
|
} |
|
|
|
} |
|
|
|
_ => self.error(errors, "TOKEN is not a valid RDF quoted triple object") |
|
|
|
_ => self.error(errors, "TOKEN is not a valid RDF quoted triple object"), |
|
|
|
} |
|
|
|
}, |
|
|
|
#[cfg(feature = "rdf-star")] |
|
|
|
#[cfg(feature = "rdf-star")] |
|
|
|
TriGState::QuotedAnonEnd => if token == N3Token::Punctuation("]") { |
|
|
|
TriGState::QuotedAnonEnd => { |
|
|
|
|
|
|
|
if token == N3Token::Punctuation("]") { |
|
|
|
self |
|
|
|
self |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
self.error(errors, "Anonymous blank node with a property list are not allowed in quoted triples") |
|
|
|
self.error(errors, "Anonymous blank node with a property list are not allowed in quoted triples") |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} else if token == N3Token::Punctuation(".") || token == N3Token::Punctuation("}") { |
|
|
|
} else if token == N3Token::Punctuation(".") || token == N3Token::Punctuation("}") { |
|
|
|
// TODO: be smarter depending if we are in '{' or not
|
|
|
|
// TODO: be smarter depending if we are in '{' or not
|
|
|
|
self.stack.push(TriGState::TriGDoc); |
|
|
|
self.stack.push(TriGState::TriGDoc); |
|
|
|