Fixes compatibility with latest OxIRI version

pull/836/head
Tpt 8 months ago committed by Thomas Tanon
parent ba396bad10
commit 184b8367dc
  1. 44
      Cargo.lock
  2. 27
      Cargo.toml
  3. 2
      lib/oxrdfio/Cargo.toml
  4. 2
      lib/oxrdfxml/Cargo.toml
  5. 16
      lib/oxrdfxml/src/parser.rs
  6. 2
      lib/oxttl/Cargo.toml
  7. 5
      lib/oxttl/src/lexer.rs
  8. 27
      lib/oxttl/src/n3.rs
  9. 507
      lib/oxttl/src/terse.rs

44
Cargo.lock generated

@ -559,9 +559,9 @@ dependencies = [
[[package]] [[package]]
name = "fastrand" name = "fastrand"
version = "2.0.1" version = "2.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" checksum = "658bd65b1cf4c852a3cc96f18a8ce7b5640f6b703f905c7d74532294c2a63984"
[[package]] [[package]]
name = "flate2" name = "flate2"
@ -810,9 +810,9 @@ dependencies = [
[[package]] [[package]]
name = "json-event-parser" name = "json-event-parser"
version = "0.2.0-alpha.2" version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b5ddd02379e99769e117ab30d21ad42dcec8ad3c12be77f9a34779e62d46346" checksum = "f850fafca79ebacd70eab9d80cb75a33aeda38bde8f3dd784c1837cdf0bde631"
dependencies = [ dependencies = [
"tokio", "tokio",
] ]
@ -1033,9 +1033,9 @@ dependencies = [
[[package]] [[package]]
name = "oxhttp" name = "oxhttp"
version = "0.2.0-alpha.4" version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9bc77c20aeeab248232d09bf748d9cf59548190c128efe4edc271a1e4db2ae95" checksum = "f3cc8fa85d054762930759faa582ba6b6dd0e115156229cdb8cca02b0e0451ae"
dependencies = [ dependencies = [
"flate2", "flate2",
"httparse", "httparse",
@ -1049,7 +1049,7 @@ dependencies = [
[[package]] [[package]]
name = "oxigraph" name = "oxigraph"
version = "0.4.0-alpha.5" version = "0.4.0-alpha.6-dev"
dependencies = [ dependencies = [
"codspeed-criterion-compat", "codspeed-criterion-compat",
"digest", "digest",
@ -1080,7 +1080,7 @@ dependencies = [
[[package]] [[package]]
name = "oxigraph-cli" name = "oxigraph-cli"
version = "0.4.0-alpha.5" version = "0.4.0-alpha.6-dev"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"assert_cmd", "assert_cmd",
@ -1099,7 +1099,7 @@ dependencies = [
[[package]] [[package]]
name = "oxigraph-js" name = "oxigraph-js"
version = "0.4.0-alpha.5" version = "0.4.0-alpha.6-dev"
dependencies = [ dependencies = [
"console_error_panic_hook", "console_error_panic_hook",
"js-sys", "js-sys",
@ -1133,9 +1133,9 @@ dependencies = [
[[package]] [[package]]
name = "oxiri" name = "oxiri"
version = "0.2.3-alpha.1" version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b225dad32cfaa43a960b93f01fa7f87528ac07e794b80f6d9a0153e0222557e2" checksum = "d05417ee46e2eb40dd9d590b4d67fc2408208b3a48a6b7f71d2bc1d7ce12a3e0"
[[package]] [[package]]
name = "oxrdf" name = "oxrdf"
@ -1150,7 +1150,7 @@ dependencies = [
[[package]] [[package]]
name = "oxrdfio" name = "oxrdfio"
version = "0.1.0-alpha.4" version = "0.1.0-alpha.5-dev"
dependencies = [ dependencies = [
"oxrdf", "oxrdf",
"oxrdfxml", "oxrdfxml",
@ -1161,7 +1161,7 @@ dependencies = [
[[package]] [[package]]
name = "oxrdfxml" name = "oxrdfxml"
version = "0.1.0-alpha.4" version = "0.1.0-alpha.5-dev"
dependencies = [ dependencies = [
"oxilangtag", "oxilangtag",
"oxiri", "oxiri",
@ -1173,7 +1173,7 @@ dependencies = [
[[package]] [[package]]
name = "oxrocksdb-sys" name = "oxrocksdb-sys"
version = "0.4.0-alpha.5" version = "0.4.0-alpha.6-dev"
dependencies = [ dependencies = [
"bindgen", "bindgen",
"cc", "cc",
@ -1191,7 +1191,7 @@ dependencies = [
[[package]] [[package]]
name = "oxttl" name = "oxttl"
version = "0.1.0-alpha.4" version = "0.1.0-alpha.5-dev"
dependencies = [ dependencies = [
"memchr", "memchr",
"oxilangtag", "oxilangtag",
@ -1347,9 +1347,9 @@ dependencies = [
[[package]] [[package]]
name = "prettyplease" name = "prettyplease"
version = "0.2.16" version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a41cf62165e97c7f814d2221421dbb9afcbcdb0a88068e5ea206e19951c2cbb5" checksum = "8d3928fb5db768cb86f891ff014f0144589297e3c6a1aba6ed7cecfdace270c7"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"syn", "syn",
@ -1429,7 +1429,7 @@ dependencies = [
[[package]] [[package]]
name = "pyoxigraph" name = "pyoxigraph"
version = "0.4.0-alpha.5" version = "0.4.0-alpha.6-dev"
dependencies = [ dependencies = [
"oxigraph", "oxigraph",
"pyo3", "pyo3",
@ -1486,9 +1486,9 @@ dependencies = [
[[package]] [[package]]
name = "rayon" name = "rayon"
version = "1.9.0" version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e4963ed1bc86e4f3ee217022bd855b297cef07fb9eac5dfa1f788b220b49b3bd" checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa"
dependencies = [ dependencies = [
"either", "either",
"rayon-core", "rayon-core",
@ -1820,9 +1820,9 @@ checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc"
[[package]] [[package]]
name = "syn" name = "syn"
version = "2.0.53" version = "2.0.55"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7383cd0e49fff4b6b90ca5670bfd3e9d6a733b3f90c686605aa7eec8c4996032" checksum = "002a1b3dbf967edfafc32655d0f377ab0bb7b994aa1d32c8cc7e9b8bf3ebb8f0"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",

@ -19,7 +19,7 @@ members = [
resolver = "2" resolver = "2"
[workspace.package] [workspace.package]
version = "0.4.0-alpha.5" version = "0.4.0-alpha.6-dev"
authors = ["Tpt <thomas@pellissier-tanon.fr>"] authors = ["Tpt <thomas@pellissier-tanon.fr>"]
license = "MIT OR Apache-2.0" license = "MIT OR Apache-2.0"
edition = "2021" edition = "2021"
@ -45,9 +45,9 @@ json-event-parser = "0.2.0-alpha.2"
libc = "0.2.147" libc = "0.2.147"
md-5 = "0.10" md-5 = "0.10"
memchr = "2.5" memchr = "2.5"
oxhttp = "0.2.0-alpha.4" oxhttp = "0.2.0"
oxilangtag = "0.1" oxilangtag = "0.1"
oxiri = "0.2.3-alpha.1" oxiri = "0.2.3"
peg = "0.8" peg = "0.8"
pkg-config = "0.3.25" pkg-config = "0.3.25"
predicates = ">=2.0, <4.0" predicates = ">=2.0, <4.0"
@ -68,17 +68,16 @@ wasm-bindgen = "0.2.83"
zstd = ">=0.12, <0.14" zstd = ">=0.12, <0.14"
# Internal dependencies # Internal dependencies
oxigraph = { version = "0.4.0-alpha.4", path = "lib/oxigraph" } oxigraph = { version = "=0.4.0-alpha.6-dev", path = "lib/oxigraph" }
oxrdf = { version = "0.2.0-alpha.4", path = "lib/oxrdf" } oxrdf = { version = "=0.2.0-alpha.4", path = "lib/oxrdf" }
oxrdfio = { version = "0.1.0-alpha.4", path = "lib/oxrdfio" } oxrdfio = { version = "=0.1.0-alpha.5-dev", path = "lib/oxrdfio" }
oxrdfxml = { version = "0.1.0-alpha.4", path = "lib/oxrdfxml" } oxrdfxml = { version = "=0.1.0-alpha.5-dev", path = "lib/oxrdfxml" }
oxrocksdb-sys = { version = "0.4.0-alpha.3", path = "./oxrocksdb-sys" } oxrocksdb-sys = { version = "=0.4.0-alpha.6-dev", path = "./oxrocksdb-sys" }
oxsdatatypes = { version = "0.2.0-alpha.1", path = "lib/oxsdatatypes" } oxsdatatypes = { version = "=0.2.0-alpha.1", path = "lib/oxsdatatypes" }
oxttl = { version = "0.1.0-alpha.4", path = "lib/oxttl" } oxttl = { version = "=0.1.0-alpha.5-dev", path = "lib/oxttl" }
sparesults = { version = "0.2.0-alpha.4", path = "lib/sparesults" } sparesults = { version = "=0.2.0-alpha.4", path = "lib/sparesults" }
spargebra = { version = "0.3.0-alpha.4", path = "lib/spargebra" } spargebra = { version = "=0.3.0-alpha.4", path = "lib/spargebra" }
sparopt = { version = "0.1.0-alpha.4", path = "lib/sparopt" } sparopt = { version = "=0.1.0-alpha.4", path = "lib/sparopt" }
sparql-smith = { version = "0.1.0-alpha.5", path = "lib/sparql-smith" }
[workspace.lints.rust] [workspace.lints.rust]
absolute_paths_not_starting_with_crate = "warn" absolute_paths_not_starting_with_crate = "warn"

@ -1,6 +1,6 @@
[package] [package]
name = "oxrdfio" name = "oxrdfio"
version = "0.1.0-alpha.4" version = "0.1.0-alpha.5-dev"
authors.workspace = true authors.workspace = true
license.workspace = true license.workspace = true
readme = "README.md" readme = "README.md"

@ -1,6 +1,6 @@
[package] [package]
name = "oxrdfxml" name = "oxrdfxml"
version = "0.1.0-alpha.4" version = "0.1.0-alpha.5-dev"
authors.workspace = true authors.workspace = true
license.workspace = true license.workspace = true
readme = "README.md" readme = "README.md"

@ -586,16 +586,13 @@ impl<R> RdfXmlReader<R> {
}); });
} else if attribute.key.as_ref() == b"xml:base" { } else if attribute.key.as_ref() == b"xml:base" {
let iri = self.convert_attribute(&attribute)?; let iri = self.convert_attribute(&attribute)?;
base_iri = Some( base_iri = Some(if self.unchecked {
if self.unchecked {
Iri::parse_unchecked(iri.clone()) Iri::parse_unchecked(iri.clone())
} else { } else {
Iri::parse(iri.clone()) Iri::parse(iri.clone()).map_err(|error| {
}
.map_err(|error| {
RdfXmlSyntaxError(SyntaxErrorKind::InvalidIri { iri, error }) RdfXmlSyntaxError(SyntaxErrorKind::InvalidIri { iri, error })
})?, })?
) })
} else { } else {
// We ignore other xml attributes // We ignore other xml attributes
} }
@ -1175,14 +1172,13 @@ impl<R> RdfXmlReader<R> {
if self.unchecked { if self.unchecked {
base_iri.resolve_unchecked(&relative_iri) base_iri.resolve_unchecked(&relative_iri)
} else { } else {
base_iri.resolve(&relative_iri) base_iri.resolve(&relative_iri).map_err(|error| {
}
.map_err(|error| {
RdfXmlSyntaxError(SyntaxErrorKind::InvalidIri { RdfXmlSyntaxError(SyntaxErrorKind::InvalidIri {
iri: relative_iri, iri: relative_iri,
error, error,
}) })
})? })?
}
.into_inner(), .into_inner(),
)) ))
} else { } else {

@ -1,6 +1,6 @@
[package] [package]
name = "oxttl" name = "oxttl"
version = "0.1.0-alpha.4" version = "0.1.0-alpha.5-dev"
authors.workspace = true authors.workspace = true
license.workspace = true license.workspace = true
readme = "README.md" readme = "README.md"

@ -219,9 +219,10 @@ impl N3Lexer {
if self.unchecked { if self.unchecked {
base_iri.resolve_unchecked(&iri) base_iri.resolve_unchecked(&iri)
} else { } else {
base_iri.resolve(&iri) base_iri
} .resolve(&iri)
.map_err(|e| (position, e.to_string()))? .map_err(|e| (position, e.to_string()))?
}
.into_inner() .into_inner()
} else if self.unchecked { } else if self.unchecked {
iri iri

@ -785,17 +785,11 @@ impl RuleRecognizer for N3Recognizer {
} }
errors.push("A dot is expected at the end of N3 statements".into()); errors.push("A dot is expected at the end of N3 statements".into());
} }
N3State::BaseExpectIri => return match token { N3State::BaseExpectIri => return if let N3Token::IriRef(iri) = token {
N3Token::IriRef(iri) => { context.lexer_options.base_iri = Some(Iri::parse_unchecked(iri));
match Iri::parse_unchecked(iri) {
Ok(iri) => {
context.lexer_options.base_iri = Some(iri);
self self
} } else {
Err(e) => self.error(errors, format!("Invalid base IRI: {e}")) self.error(errors, "The BASE keyword should be followed by an IRI")
}
}
_ => self.error(errors, "The BASE keyword should be followed by an IRI"),
}, },
N3State::PrefixExpectPrefix => return match token { N3State::PrefixExpectPrefix => return match token {
N3Token::PrefixedName { prefix, local, .. } if local.is_empty() => { N3Token::PrefixedName { prefix, local, .. } if local.is_empty() => {
@ -806,17 +800,10 @@ impl RuleRecognizer for N3Recognizer {
self.error(errors, "The PREFIX keyword should be followed by a prefix like 'ex:'") self.error(errors, "The PREFIX keyword should be followed by a prefix like 'ex:'")
} }
}, },
N3State::PrefixExpectIri { name } => return match token { N3State::PrefixExpectIri { name } => return if let N3Token::IriRef(iri) = token {
N3Token::IriRef(iri) => { context.prefixes.insert(name, Iri::parse_unchecked(iri));
match 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"),
}, },
// [9] triples ::= subject predicateObjectList? // [9] triples ::= subject predicateObjectList?
N3State::Triples => { N3State::Triples => {

@ -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);

Loading…
Cancel
Save