aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorarie <arie@alleycat.cc>2021-05-20 18:35:56 +0200
committerarie <arie@alleycat.cc>2021-06-28 21:01:35 +0200
commit105a7eff0ccffa9b0df07d0615b7b75314934e3a (patch)
tree4364e4c96a1a99d887d54b6966e3550df6300a38
parenta93fc2c982764720b5c12538730e7fde6f1d6757 (diff)
Rdf-turtle:
add some more parsers. Add some helper functions (these are optional, maybe it's more clear not to use them. If there's a way to use lift functions with functions that use optional values that would be great (at least a better way than this one).
-rw-r--r--lib/turtle/rdf_turtle.ml57
-rw-r--r--lib/turtle/rdf_turtle.mli19
2 files changed, 69 insertions, 7 deletions
diff --git a/lib/turtle/rdf_turtle.ml b/lib/turtle/rdf_turtle.ml
index 3fdfa3c..83c7aea 100644
--- a/lib/turtle/rdf_turtle.ml
+++ b/lib/turtle/rdf_turtle.ml
@@ -40,7 +40,23 @@ module Iri = struct
end
module Literal = struct
- type t = String of string * Language.t option * Iri.t option
+ type t = {
+ value: string;
+ language: string option;
+ datatype: Iri.t;
+ }
+
+ let make value ?language datatype =
+ { value; datatype; language }
+
+ let canonical literal =
+ literal.value
+
+ let datatype literal =
+ literal.datatype
+
+ let language literal =
+ literal.language
end
module Predicate = struct
@@ -91,20 +107,33 @@ module Parser = struct
let is_not_whitespace c = c |> is_whitespace |> not
+ let char_is_not_equal_to c d =
+ c != d
+
let whitespace =
many @@ choice [string " "; string "\n"; string "\t"]
>>| ignore
+ let delimiters c1 c2 =
+ char c1
+ *> take_while (fun d -> not @@ Char.equal c2 d)
+ <* char c2
+
+(* let iriref = *)
+(* char '<' *)
+(* *> take_while (fun c -> not @@ Char.equal '>' c) *)
+(* <* char '>' *)
+(* >>| (fun s -> Iriref.of_string s) *)
+
let iriref =
- char '<'
- *> take_while (fun c -> not @@ Char.equal '>' c)
- <* char '>'
- >>| (fun s -> Iriref.of_string s)
+ lift
+ Iriref.of_string
+ (delimiters '<' '>')
let prefixed_name =
lift2
Prefixed_name.of_strings
- (take_while (fun c -> not @@ Char.equal ':' c)
+ (take_while (char_is_not_equal_to ':')
<* char ':')
(take_while is_not_whitespace)
@@ -121,5 +150,21 @@ module Parser = struct
*> char ':'
*> take_while is_not_whitespace)
+ let iri =
+ (lift Iri.of_iriref iriref)
+ <|>
+ (lift Iri.of_prefixed_name prefixed_name)
+
+ let literal =
+ lift3
+ (fun value lang_opt iri -> match lang_opt with
+ | "" -> Literal.make value iri
+ | lang -> Literal.make value ~language:lang iri)
+ (delimiters '"' '"')
+ (char '@'
+ *> (take_while (char_is_not_equal_to ':'))
+ )
+ (string "^^" *> iri)
+
end
diff --git a/lib/turtle/rdf_turtle.mli b/lib/turtle/rdf_turtle.mli
index 15e847a..4c4ccff 100644
--- a/lib/turtle/rdf_turtle.mli
+++ b/lib/turtle/rdf_turtle.mli
@@ -39,7 +39,20 @@ end
(* The language option indicates a language, the iri option inidicates the data type *)
module Literal : sig
- type t = String of string * Language.t option * Iri.t option
+ type t
+ (** A literal. *)
+
+ val make : string -> ?language:string -> Iri.t -> t
+ (** Create a new literal. *)
+
+ val canonical : t -> string
+ (** [canonical literal] returns the canonical representation of the literal. *)
+
+ val datatype : t -> Iri.t
+ (** [datatype literal] returns the datatype of the literal. *)
+
+ val language : t -> string option
+ (** [language literal] returns the language tag of the literal. *)
end
(* We omit the 'verb' type, since this predicate type encompasses the same space *)
@@ -94,4 +107,8 @@ module Parser : sig
val blank_node : Blank_node.t Angstrom.t
+ val iri : Iri.t Angstrom.t
+
+ val literal : Literal.t Angstrom.t
+
end