grammar;
use crate::turtle_stream::ParsedLine;
use crate::data::Pre;
use crate::data::RdfName;
// Entry rule for each line
pub Line: ParsedLine = {
<prefix:Prefix> => ParsedLine::Prefix(prefix.0, prefix.1),
<subject:RDFName> => ParsedLine::Subject(subject.0, RdfName::new(subject.1)),
<isa:IsaStmt> => ParsedLine::SubjectPredObj( isa.0.0,
RdfName::new(isa.0.1), Some(Pre::new("rdf".to_string())),
RdfName::new("type".to_string()), isa.1.0, isa.1.1, isa.2),
<triple:Triple> => ParsedLine::SubjectPredObj( triple.0.0,
RdfName::new(triple.0.1), triple.1.0,
RdfName::new(triple.1.1), triple.2.0, triple.2.1, triple.3),
<object:RDFName> End => ParsedLine::ContinueObj(object.0, RdfName::new(object.1), false),
<object:RDFName> Sep => ParsedLine::ContinueObj(object.0, RdfName::new(object.1), true),
<object:RDFName> ObjSep => ParsedLine::ContinueObj(object.0, RdfName::new(object.1), true),
<pair:PredicateObjectPair> Sep End => ParsedLine::PredObjTerm(pair.0.0,
RdfName::new(pair.0.1), pair.1.0, pair.1.1),
<pair:PredicateObjectPair> End => ParsedLine::PredObjTerm(pair.0.0,
RdfName::new(pair.0.1), pair.1.0, pair.1.1),
<pair:PredicateObjectPair> ObjSep => ParsedLine::PredObj(pair.0.0,
RdfName::new(pair.0.1), pair.1.0, pair.1.1, true),
<pair:PredicateObjectPair> Sep => ParsedLine::PredObj(pair.0.0,
RdfName::new(pair.0.1), pair.1.0, pair.1.1, true),
};
IsaStmt: ((Option<Pre>, String), (Option<Pre>, String), bool) = {
<subject:RDFName> IsA <object:Object> End => (subject, object, false),
<subject:RDFName> IsA <object:Object> ObjSep => (subject, object, true)
};
Triple: ((Option<Pre>, String), (Option<Pre>, String), (Option<Pre>, String), bool) = {
<subject:RDFName> <predicate:RDFName> <object:Object> End => (subject, predicate, object, false),
<subject:RDFName> <predicate:RDFName> <object:Object> ObjSep => (subject, predicate, object, true),
};
PredicateObjectPair: ((Option<Pre>, String), (Option<Pre>, String), bool) = {
<predicate:RDFName> <object:Object> => (predicate, object, false)
};
pub Prefix: (Pre, RdfName) = {
"@prefix" <ns:Namespace> PrefixSep <uri:Uri> End => (Pre::new ( ns.to_string() ), RdfName::new(uri.to_string()))
};
// Captures the namespace (like "myns:")
Namespace: &'input str = {
<n:Ident> => n
};
// Captures the URI enclosed in angle brackets (like "<http://example.com/myns#>")
Uri: &'input str = {
"<" <u:UriContent> ">" => u.trim_end_matches('/')
};
UriContent: &'input str = r"https?://[^>]+";
pub Object: (Option<Pre>, String) = {
<quoted:EscapedString> => {
(None, quoted.trim_matches('"').to_string())
},
<name:RDFName> => {
(name.0, name.1)
}
};
// RDF Name (like res:... or prop:...)
pub RDFName: (Option<Pre>, String) = {
<ns:Ident> PrefixSep <name:Ident> => (Some(Pre::new(ns.to_string())), name.to_string()),
<name:Ident> => (None, name.to_string()),
<uri:Uri> => (None, uri.to_string()),
};
// Definition of an identifier
Ident: &'input str = {
r"[a-zA-Z0-9_][a-zA-Z0-9_-]*" => <>
};
EscapedString: &'input str = {
r#""([^"\\]|\\.)*""# => <>
};
End: () = {
r"\." => (),
};
Sep: () = {
r";" => (),
};
//NsSep: () = {
// r"#" => (),
//};
ObjSep: () = {
r"," => (),
};
IsA: () = {
r" a" => (),
};
PrefixSep: () = {
r":" => (),
};