aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorarie <arie@alleycat.cc>2021-06-14 18:25:26 +0200
committerarie <arie@alleycat.cc>2021-06-28 21:03:35 +0200
commit4e6349d102a99011ff3ee45f168247ae6d16bc5d (patch)
tree7632ddb8e31146f76166469c6088901f02df787b
parent862a3d9eb439452f8903384da421d543064168cc (diff)
Rdf turtle
Add turtle -> graph transformation. Well, statement to graph to be precise, but that's only a list.fold away. Add a function in bin for testing. It does things, but now the great debugging can start, because some of these things are unexpected.
-rw-r--r--bin/dune5
-rw-r--r--bin/main.ml63
-rw-r--r--lib/turtle/ast.ml57
-rw-r--r--lib/turtle/dune1
-rw-r--r--lib/turtle/parser.ml14
-rw-r--r--lib/turtle/rdf_turtle.ml246
-rw-r--r--lib/turtle/rdf_turtle.mli17
-rw-r--r--rdf_turtle.opam0
-rw-r--r--test/turtle/main.ml5
9 files changed, 368 insertions, 40 deletions
diff --git a/bin/dune b/bin/dune
new file mode 100644
index 0000000..46e74f2
--- /dev/null
+++ b/bin/dune
@@ -0,0 +1,5 @@
+(executable
+ (name main)
+ (libraries rdf rdf_turtle))
+
+
diff --git a/bin/main.ml b/bin/main.ml
new file mode 100644
index 0000000..0a4b96d
--- /dev/null
+++ b/bin/main.ml
@@ -0,0 +1,63 @@
+module Parser = Rdf_turtle.Parser
+
+open Rdf
+
+let parse p =
+ Angstrom.parse_string
+ ~consume:Angstrom.Consume.All
+ p
+
+let turtle_list =
+ [
+(* "<http://example.org/#spiderman> <http://www.perceive.net/schemas/relationship/enemyOf> _:a ." *)
+(* ; *)
+ "(_:a _:b)
+ <http://www.perceive.net/schemas/relationship/enemyOf> _:a ."
+ ;
+ ]
+
+let test_sub =
+ "test_sub"
+ |> Rdf.Iri.of_string
+ |> Rdf.Triple.Subject.of_iri
+
+let test_pred =
+ "test_sub"
+ |> Rdf.Iri.of_string
+ |> Rdf.Triple.Predicate.of_iri
+
+let test_iri =
+ "hey-some-iri!"
+ |> Rdf.Iri.of_string
+
+let test_iri_2 =
+ "http://example.org/#spiderman"
+ |> Rdf.Iri.of_string
+
+let test_ctx : Rdf_turtle.Ast.parser_state =
+ {
+ base_uri = "base" |> Iri.of_string;
+ namespaces = Rdf_turtle.Ast.SMap.empty;
+ bnode_labels = Rdf_turtle.Ast.SMap.empty;
+ cur_subject = test_sub;
+ cur_predicate = test_pred;
+ }
+
+let empty_graph = Graph.empty
+
+let () =
+ List.iter (
+ fun statement_str ->
+ statement_str
+ |> parse Parser.statement
+ |> Result.get_ok
+ |> (fun statement ->
+ Rdf_turtle.apply_statement (test_ctx, empty_graph) statement)
+ |> (fun (_ctx, g) -> Graph.to_list @@ g)
+ |> List.iter (fun triple ->
+ Fmt.pr "TRIPLE!! %a@." Triple.pp triple)
+ ) turtle_list ;
+ Fmt.pr "IRI: %a @." Iri.pp test_iri;
+ Fmt.pr "IRI_2: %a @." Iri.pp test_iri_2;
+
+
diff --git a/lib/turtle/ast.ml b/lib/turtle/ast.ml
index b1d9c6c..856a949 100644
--- a/lib/turtle/ast.ml
+++ b/lib/turtle/ast.ml
@@ -23,6 +23,8 @@ end
module SMap = Map.Make (Ordered_string)
+let _empty_map = SMap.empty
+
module Iriref = struct
type t = string
@@ -120,12 +122,12 @@ end
module Literal = struct
type t = {
value: string;
- language: string option;
datatype: Iri.t;
+ language: string option;
}
let make value ?language datatype =
- { value; datatype; language }
+ { value; datatype; language}
let canonical literal =
literal.value
@@ -172,17 +174,19 @@ module Predicate = struct
end
type object' =
- Obj_iri of Iri.t
+ | Obj_iri of Iri.t
| Obj_blank_node of Blank_node.t
| Obj_literal of Literal.t
| Obj_coll of collection
- | Obj_BnodPs of bnodps
+ | Obj_bnodps of bnodps
and collection =
- Collection of object' list
+ | Collection of object' list
and subject =
- Sub_iri of Iri.t
+ | Sub_iri of Iri.t
| Sub_blank_node of Blank_node.t
| Sub_coll of collection
+(* This deviates a little from the w3c specs. *)
+ | Sub_bnodps of bnodps
and bnodps = BnodPs of predobjs
and predobjs = (Predicate.t * object' list) list
@@ -192,7 +196,7 @@ let rec object_equal a b =
| Obj_blank_node ba, Obj_blank_node bb -> Blank_node.equal ba bb
| Obj_literal la, Obj_literal lb -> Literal.equal la lb
| Obj_coll ca, Obj_coll cb -> collection_equal ca cb
- | Obj_BnodPs bas, Obj_BnodPs bbs -> bnodps_equal bas bbs
+ | Obj_bnodps bas, Obj_bnodps bbs -> bnodps_equal bas bbs
| _ -> false
and collection_equal (Collection obsa) (Collection obsb) =
list_equal object_equal obsa obsb
@@ -201,6 +205,7 @@ and subject_equal a b =
| Sub_iri ia, Sub_iri ib -> Iri.equal ia ib
| Sub_blank_node ba, Sub_blank_node bb -> Blank_node.equal ba bb
| Sub_coll ca, Sub_coll cb -> collection_equal ca cb
+ | Sub_bnodps ba, Sub_bnodps bb -> bnodps_equal ba bb
| _ -> false
and bnodps_equal (BnodPs a) (BnodPs b) =
predobjs_equal a b
@@ -214,13 +219,14 @@ let rec object_pp ppf = function
| Obj_blank_node bnode -> Fmt.pf ppf "@[<h 1><obj_blank_node@ %a>@]" Blank_node.pp bnode
| Obj_literal lit -> Fmt.pf ppf "@[<h 1><obj_literal@ %a>@]" Literal.pp lit
| Obj_coll coll -> Fmt.pf ppf "@[<h 1><obj_coll@ %a>@]" collection_pp coll
- | Obj_BnodPs bnodps -> Fmt.pf ppf "@[<h 1><obj_bnodps@ %a>@]" bnodps_pp bnodps
+ | Obj_bnodps bnodps -> Fmt.pf ppf "@[<h 1><obj_bnodps@ %a>@]" bnodps_pp bnodps
and collection_pp ppf (Collection objs) =
Fmt.pf ppf "@[<h 1><collection obj@ %a>@]" (Fmt.list object_pp) objs
and subject_pp ppf = function
- | Sub_iri iri ->Fmt.pf ppf "@[<h 1><obj_iri@ %a>@]" Iri.pp iri
- | Sub_blank_node bnode -> Fmt.pf ppf "@[<h 1><obj_blank_node@ %a>@]" Blank_node.pp bnode
- | Sub_coll collection -> Fmt.pf ppf "@[<h 1><obj_collection@ %a>@]" collection_pp collection
+ | Sub_iri iri ->Fmt.pf ppf "@[<h 1><sub_iri@ %a>@]" Iri.pp iri
+ | Sub_blank_node bnode -> Fmt.pf ppf "@[<h 1><sub_blank_node@ %a>@]" Blank_node.pp bnode
+ | Sub_bnodps bnodps -> Fmt.pf ppf "@[<h 1><sub_bnodps@ %a>@]" bnodps_pp bnodps
+ | Sub_coll collection -> Fmt.pf ppf "@[<h 1><sub_collection@ %a>@]" collection_pp collection
and bnodps_pp ppf (BnodPs predobjs) =
Fmt.pf ppf "@[<h 1><obj_bnodps@ %a>@]" predobjs_pp predobjs
and predobjs_pp ppf l =
@@ -241,27 +247,28 @@ module Triples = struct
type t = SubjPredObjs of subject * predobjs
| BnodPs of bnodps
- let of_subject_and_predobjs s p =
- SubjPredObjs (s, p)
+ let of_subject_and_predobjs subject predobjs =
+ SubjPredObjs (subject, predobjs)
- let of_bnodps b =
- BnodPs b
+ let of_bnodps bnodps =
+ BnodPs bnodps
let equal a b =
match a, b with
| SubjPredObjs (asub, ap), SubjPredObjs (bsub, bp) ->
subject_equal asub bsub && predobjs_equal ap bp
- | BnodPs ab, BnodPs bb ->
- bnodps_equal ab bb
+ | BnodPs abs, BnodPs bbs ->
+ bnodps_equal abs bbs
| _, _ -> false
let pp ppf = function
- | SubjPredObjs (s, p) ->
+ | SubjPredObjs (s, ps) ->
Fmt.pf ppf "@[<h 1><triples@ subject %a@ predicate %a>@]"
subject_pp s
- predobjs_pp p
- | BnodPs b ->
- Fmt.pf ppf "@[<h 1><triples@ bnodps %a>@]" bnodps_pp b
+ predobjs_pp ps
+ | BnodPs bs ->
+ Fmt.pf ppf "@[<h 1><triples@ bnodps %a >@]"
+ bnodps_pp bs
end
@@ -332,9 +339,9 @@ module Turtle = struct
end
type parser_state = {
- base_uri : Iri.t;
- namespaces : Iri.t SMap.t;
+ base_uri : Rdf.Iri.t;
+ namespaces : Rdf.Iri.t SMap.t;
bnode_labels : Blank_node.t SMap.t;
- cur_subject: subject;
- cur_predicate: Predicate.t;
+ cur_subject: Rdf.Triple.Subject.t;
+ cur_predicate: Rdf.Triple.Predicate.t;
}
diff --git a/lib/turtle/dune b/lib/turtle/dune
index 0ef71f5..b0578aa 100644
--- a/lib/turtle/dune
+++ b/lib/turtle/dune
@@ -1,3 +1,4 @@
(library
(name rdf_turtle)
+ (public_name rdf_turtle)
(libraries rdf angstrom))
diff --git a/lib/turtle/parser.ml b/lib/turtle/parser.ml
index c0e2017..2a40664 100644
--- a/lib/turtle/parser.ml
+++ b/lib/turtle/parser.ml
@@ -86,7 +86,7 @@ let object_ collection bnodps =
);
(lift
(fun bnodps ->
- Ast.Obj_BnodPs bnodps)
+ Ast.Obj_bnodps bnodps)
bnodps
);
(lift
@@ -180,11 +180,11 @@ let object' = object_ collection bnodps
let triples =
choice [
(lift2
- (fun subject predobjs -> Ast.Triples.SubjPredObjs (subject, predobjs))
+ Ast.Triples.of_subject_and_predobjs
subject
predobjs);
(lift
- (fun bnodps -> Ast.Triples.BnodPs bnodps)
+ Ast.Triples.of_bnodps
bnodps
)
]
@@ -192,7 +192,7 @@ let triples =
let directive =
choice [
lift2
- (fun str iriref -> Ast.Directive.PrefixID (str, iriref))
+ Ast.Directive.of_string_and_iriref
(string "@prefix"
*> whitespace
*> (take_while (char_is_not_equal_to ([':'] @ whitespace_lst)))
@@ -205,7 +205,7 @@ let directive =
)
;
lift
- (fun iriref -> Ast.Directive.Base iriref)
+ Ast.Directive.of_iriref
(string "@base"
*> whitespace
*> iriref
@@ -217,11 +217,11 @@ let directive =
let statement =
choice [
lift
- (fun directive -> Ast.Statement.Directive directive)
+ Ast.Statement.of_directive
(directive)
;
lift
- (fun triples -> Ast.Statement.Triples triples)
+ Ast.Statement.of_triples
(triples
<* whitespace
<* char '.'
diff --git a/lib/turtle/rdf_turtle.ml b/lib/turtle/rdf_turtle.ml
index 966cdb7..294513e 100644
--- a/lib/turtle/rdf_turtle.ml
+++ b/lib/turtle/rdf_turtle.ml
@@ -2,3 +2,249 @@ module Ast = Ast
module Parser = Parser
+open Rdf
+
+type ctxG = Ast.parser_state * Graph.t
+
+(* TODO use something that creates new blank_nodes (using an i or something?) *)
+let create_blank_node () = Blank_node.of_string "new_blank_node"
+
+(* TODO *)
+let iri_of_iriref : Ast.parser_state -> Ast.Iriref.t -> Iri.t =
+ fun _ctx iriref ->
+ iriref
+ |> Ast.Iriref.to_string
+ |> Iri.of_string
+
+(* TODO *)
+let iri_of_resource : Ast.parser_state -> Ast.Iri.t -> Iri.t = fun
+ _ctx ast_iri ->
+ match ast_iri with
+ | Iriref str ->
+ str |> Iri.of_string
+ | Prefixed_name (a, b) ->
+ Iri.of_string (a ^ b)
+
+(* TODO what should this be? *)
+let base_predicate =
+ "base"
+ |> Iri.of_string
+ |> Triple.Predicate.of_iri
+
+(* TODO should it be like this? *)
+let nil_obj =
+ "http://www.w3.org/1999/02/22-rdf-syntax-ns#nil"
+ |> Iri.of_string
+ |> Triple.Object.of_iri
+
+let nil_sub =
+ "http://www.w3.org/1999/02/22-rdf-syntax-ns#nil"
+ |> Iri.of_string
+ |> Triple.Subject.of_iri
+
+let first_pred =
+ "http://www.w3.org/1999/02/22-rdf-syntax-ns#first"
+ |> Iri.of_string
+ |> Triple.Predicate.of_iri
+
+let rest_pred =
+ "http://www.w3.org/1999/02/22-rdf-syntax-ns#last"
+ |> Iri.of_string
+ |> Triple.Predicate.of_iri
+
+(* We separate the cases where the collection is an object, and where it is a subject. *)
+(* They have in common that, for the list of objects, a list of bnodes is generated. *)
+(* And a list of triples is emitted. This happens in mk_collection. *)
+let rec mk_collection : Blank_node.t -> ctxG -> Ast.object' list -> ctxG * Blank_node.t =
+ fun bnode (ctx, g) objs ->
+ match objs with
+ | [obj] ->
+ let sub_bnode = Triple.Subject.of_blank_node @@ bnode in
+ let (ctx, g) = insert_pred sub_bnode first_pred (ctx, g) obj in
+ let g = Graph.add g (Triple.make sub_bnode rest_pred nil_obj) in
+ let new_bnode = create_blank_node () in
+ (ctx, g), new_bnode
+ | head :: tail ->
+ let sub_bnode = Triple.Subject.of_blank_node @@ bnode in
+ let (ctx, g) = insert_pred sub_bnode first_pred (ctx, g) head in
+ let new_bnode = create_blank_node () in
+ let obj_bnode = Triple.Object.of_blank_node @@ new_bnode in
+ let g = Graph.add g (Triple.make sub_bnode rest_pred obj_bnode) in
+ mk_collection new_bnode (ctx, g) tail
+ | _ -> raise @@ Invalid_argument "This list cannot be empty."
+
+and mk_collection_sub : ctxG -> Ast.object' list -> Triple.Subject.t * ctxG =
+ fun (ctx, g) objs ->
+ match objs with
+ | [] -> nil_sub, (ctx, g)
+ | objs ->
+ let bnode = create_blank_node () in
+ let (ctx, g), _bnode = mk_collection bnode (ctx, g) objs in
+ let sub_bnode = Triple.Subject.of_blank_node @@ bnode in
+ sub_bnode, (ctx, g)
+
+and mk_collection_obj : Triple.Subject.t -> Triple.Predicate.t -> ctxG -> Ast.object' list -> ctxG =
+ fun sub pred (ctx, g) objs ->
+ match objs with
+ | [] ->
+ let g = Graph.add g (Triple.make sub pred nil_obj) in
+ (ctx, g)
+ | objs ->
+ let bnode = create_blank_node () in
+ let (ctx, g), _bnode = mk_collection bnode (ctx, g) objs in
+ let obj_bnode = Triple.Object.of_blank_node @@ bnode in
+ let g = Graph.add g (Triple.make sub pred obj_bnode) in
+ (ctx, g)
+
+ (* We match on objects *)
+ (* If the object is an Iri, check whether it is a prefixed name and apply the namespaces *)
+ (* Add a triple to the graph. *)
+ (* If the object is a blank_node, transform to an rdf_blank_node and add to graph. *)
+ (* If the object is a literal, transform to an rdf_literal and add to graph *)
+ (* If the object is a collection, perform mk_collection with sub, pred, ctxG. *)
+and insert_pred : Triple.Subject.t -> Triple.Predicate.t -> ctxG -> Ast.object' -> ctxG =
+ fun sub pred (ctx, g) obj ->
+ match obj with
+ | Obj_iri i ->
+ let rdf_obj = Triple.Object.of_iri (iri_of_resource ctx i) in
+ let g = Graph.add g (Triple.make sub pred rdf_obj) in
+ (ctx, g)
+ | Obj_blank_node bnode ->
+ let rdf_obj =
+ bnode
+ |> Blank_node.of_string
+ |> Triple.Object.of_blank_node
+ in
+ let g = Graph.add g (Triple.make sub pred rdf_obj) in
+ (ctx, g)
+ | Obj_literal { value; datatype; language } ->
+ let rdf_iri_datatype = iri_of_resource ctx datatype in
+ let rdf_obj =
+ Triple.Object.of_literal
+ (Literal.make
+ value
+ rdf_iri_datatype
+ ?language)
+ in
+ let g = Graph.add g (Triple.make sub pred rdf_obj) in
+ (ctx, g)
+ | Obj_coll (Collection objs) -> mk_collection_obj sub pred (ctx, g) objs
+ | Obj_bnodps (BnodPs obj_predobjs) ->
+ let bnode = create_blank_node () in
+ let obj_bnode = Triple.Object.of_blank_node @@ bnode in
+ let sub_bnode = Triple.Subject.of_blank_node @@ bnode in
+ let g = Graph.add g (Triple.make sub pred obj_bnode) in
+ let (ctx, g) = List.fold_left (insert_sub_predobj sub_bnode) (ctx, g) obj_predobjs in
+ (ctx, g)
+
+and insert_sub_predobj : Triple.Subject.t -> ctxG -> Ast.Predicate.t * (Ast.object' list) -> ctxG =
+ (* We match on predicates. *)
+ (* We transform the Ast Predicate into an Rdf Predicate *)
+ (* Then we fold over the obect' list *)
+ fun sub (ctx, g) (pred, objs) ->
+ let pred =
+ match pred with
+ | Pred_iri i -> Triple.Predicate.of_iri @@ (iri_of_resource ctx i)
+ | Pred_a -> base_predicate
+ in
+ List.fold_left (insert_pred sub pred) (ctx, g) objs
+
+let insert_sub_predobjs : ctxG -> Ast.subject -> Ast.predobjs -> ctxG =
+ (* We match on subject. *)
+ (* There is already a subject (this is also available in the ctx, so maybe we can take it out of the ctx). *)
+ (* If the subject is an Iri, check whether it is a prefixed name and apply the namespaces *)
+ (* If the subject is a blank_node, create a subject with that blank node. *)
+ (* If the subject is a collection, apply the mk_collection_sub function (is there a difference between subject and object?) *)
+(* If the *)
+ (* Then we fold over the list of pred * object list. *)
+ fun (ctx, g) sub predobjs ->
+ let sub, (ctx, g) =
+ match sub with
+ | Sub_iri i -> Triple.Subject.of_iri (iri_of_resource ctx i), (ctx, g)
+ | Sub_blank_node b -> (Triple.Subject.of_blank_node @@ Blank_node.of_string b), (ctx, g)
+ | Sub_coll (Collection objs) -> mk_collection_sub (ctx, g) objs
+ | Sub_bnodps (BnodPs sub_predobjs) ->
+ let bnode = create_blank_node () in
+ let sub_bnode = Triple.Subject.of_blank_node @@ bnode in
+ let (ctx, g) = List.fold_left (insert_sub_predobj sub_bnode) (ctx, g) sub_predobjs in
+ sub_bnode, (ctx, g)
+ in
+ List.fold_left (insert_sub_predobj sub) (ctx, g) predobjs
+
+let apply_statement : ctxG -> Ast.Statement.t -> ctxG =
+ fun (ctx, g) s -> match s with
+ | Directive (PrefixID (s, iriref)) ->
+ let iri = iri_of_iriref ctx iriref in
+ let ctx = { ctx with namespaces = Ast.SMap.add s iri ctx.namespaces } in
+ (ctx, g)
+ | Directive (Base iriref) ->
+ let iri =
+ iriref
+ |> Ast.Iriref.to_string
+ |> Iri.of_string
+ in
+ let ctx = { ctx with base_uri = iri } in
+ (ctx, g)
+ | Triples (SubjPredObjs (sub, predobjs)) ->
+ insert_sub_predobjs (ctx, g) sub predobjs
+(* TODO, double BnodPs is weird *)
+ | Triples (BnodPs (BnodPs predobjs)) ->
+ let bnode = create_blank_node () in
+ let sub_bnode = Triple.Subject.of_blank_node @@ bnode in
+ List.fold_left (insert_sub_predobj sub_bnode) (ctx, g) predobjs
+
+(* SUBJECT COLLECTIONS *)
+(* <http://www.w3.org/1999/02/22-rdf-syntax-ns#nil> <http://a.example/p> <http://a.example/o> . *)
+(* *)
+(* _:genid1 <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> "2"^^<http://www.w3.org/2001/XMLSchema#integer> . *)
+(* _:genid1 <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> <http://www.w3.org/1999/02/22-rdf-syntax-ns#nil> . *)
+(* _:genid1 <http://a.example/p> <http://a.example/o> . *)
+(* *)
+(* _:genid1 <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> "2"^^<http://www.w3.org/2001/XMLSchema#integer> . *)
+(* _:genid1 <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> _:genid2 . *)
+(* _:genid1 <http://a.example/p> <http://a.example/o> . *)
+(* _:genid2 <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> "3"^^<http://www.w3.org/2001/XMLSchema#integer> . *)
+(* _:genid2 <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> <http://www.w3.org/1999/02/22-rdf-syntax-ns#nil> . *)
+(* *)
+(* _:genid1 <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> "2"^^<http://www.w3.org/2001/XMLSchema#integer> . *)
+(* _:genid1 <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> _:genid2 . *)
+(* _:genid1 <http://a.example/p> <http://a.example/o> . *)
+(* _:genid2 <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> "3"^^<http://www.w3.org/2001/XMLSchema#integer> . *)
+(* _:genid2 <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> _:genid3 . *)
+(* _:genid3 <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> "4"^^<http://www.w3.org/2001/XMLSchema#integer> . *)
+(* _:genid3 <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> <http://www.w3.org/1999/02/22-rdf-syntax-ns#nil> . *)
+
+
+(* OBJECT COLLECTIONS *)
+(* <http://a.example/s> <http://a.example/p> <http://www.w3.org/1999/02/22-rdf-syntax-ns#nil> . *)
+(* *)
+(* _:genid1 <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> "1"^^<http://www.w3.org/2001/XMLSchema#integer> . *)
+(* _:genid1 <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> <http://www.w3.org/1999/02/22-rdf-syntax-ns#nil> . *)
+(* <http://a.example/s> <http://a.example/p> _:genid1 . *)
+(* *)
+(* _:genid1 <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> "1"^^<http://www.w3.org/2001/XMLSchema#integer> . *)
+(* _:genid1 <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> _:genid2 . *)
+(* _:genid2 <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> "2"^^<http://www.w3.org/2001/XMLSchema#integer> . *)
+(* _:genid2 <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> <http://www.w3.org/1999/02/22-rdf-syntax-ns#nil> . *)
+(* <http://a.example/s> <http://a.example/p> _:genid1 . *)
+(* *)
+(* _:genid1 <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> "1"^^<http://www.w3.org/2001/XMLSchema#integer> . *)
+(* _:genid1 <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> _:genid2 . *)
+(* _:genid2 <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> "2"^^<http://www.w3.org/2001/XMLSchema#integer> . *)
+(* _:genid2 <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> _:genid3 . *)
+(* _:genid3 <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> "3"^^<http://www.w3.org/2001/XMLSchema#integer> . *)
+(* _:genid3 <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> <http://www.w3.org/1999/02/22-rdf-syntax-ns#nil> . *)
+(* <http://a.example/s> <http://a.example/p> _:genid1 . *)
+(* *)
+
+(* @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . *)
+(* @prefix ns0: <http://a.example/> . *)
+(* *)
+(* [] *)
+(* rdf:first 2 ; *)
+(* rdf:rest ( *)
+(* 3 *)
+(* 4 *)
+(* ) ; *)
+(* ns0:p ns0:o . *)
+
diff --git a/lib/turtle/rdf_turtle.mli b/lib/turtle/rdf_turtle.mli
index c81a983..36d28f8 100644
--- a/lib/turtle/rdf_turtle.mli
+++ b/lib/turtle/rdf_turtle.mli
@@ -133,13 +133,14 @@ module Ast : sig
| Obj_blank_node of Blank_node.t
| Obj_literal of Literal.t
| Obj_coll of collection
- | Obj_BnodPs of bnodps
+ | Obj_bnodps of bnodps
and collection =
Collection of object' list
and subject =
Sub_iri of Iri.t
| Sub_blank_node of Blank_node.t
| Sub_coll of collection
+ | Sub_bnodps of bnodps
and bnodps = BnodPs of predobjs
and predobjs = (Predicate.t * object' list) list
@@ -171,7 +172,7 @@ module Ast : sig
val of_subject_and_predobjs : subject -> predobjs -> t
- val of_bnodps : bnodps -> t
+ val of_bnodps: bnodps -> t
val equal : t -> t -> bool
@@ -224,11 +225,11 @@ module Ast : sig
end
type parser_state = {
- base_uri : Iri.t;
- namespaces : Iri.t SMap.t;
+ base_uri : Rdf.Iri.t;
+ namespaces : Rdf.Iri.t SMap.t;
bnode_labels : Blank_node.t SMap.t;
- cur_subject: subject;
- cur_predicate: Predicate.t;
+ cur_subject : Rdf.Triple.Subject.t;
+ cur_predicate: Rdf.Triple.Predicate.t;
}
end
@@ -270,3 +271,7 @@ module Parser : sig
val turtle : Ast.Turtle.t Angstrom.t
end
+
+type ctxG = Ast.parser_state * Rdf.Graph.t
+
+val apply_statement : ctxG -> Ast.Statement.t -> ctxG
diff --git a/rdf_turtle.opam b/rdf_turtle.opam
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/rdf_turtle.opam
diff --git a/test/turtle/main.ml b/test/turtle/main.ml
index 0973a17..6cd5c32 100644
--- a/test/turtle/main.ml
+++ b/test/turtle/main.ml
@@ -163,7 +163,7 @@ let object_test_case =
) ;
(* BNodePlist *)
"[ foaf:name \"Bob\" ]",
- Obj_BnodPs (BnodPs ([ Predicate.of_iri @@ Iri.of_prefixed_name @@ Prefixed_name.of_strings "foaf" "name",
+ Obj_bnodps (BnodPs ([ Predicate.of_iri @@ Iri.of_prefixed_name @@ Prefixed_name.of_strings "foaf" "name",
[ Obj_literal ( Literal.make
("Bob")
(Iri.of_prefixed_name @@ Prefixed_name.of_strings "xsd" "string"))
@@ -265,7 +265,7 @@ let subject_test_case =
Literal.make
("1")
(Iri.of_prefixed_name @@ Prefixed_name.of_strings "xsd" "string")) ;
- Obj_BnodPs (
+ Obj_bnodps (
BnodPs (
[ Predicate.of_iri @@ Iri.of_prefixed_name @@ Prefixed_name.of_strings "" "p",
[ Obj_iri (Iri.of_prefixed_name @@ Prefixed_name.of_strings "" "q"); ] ; ]
@@ -302,6 +302,7 @@ let triples_test_case =
([ Predicate.of_iri @@ Iri.of_iriref "http://www.perceive.net/schemas/relationship/enemyOf",
[ Obj_iri (Iri.of_iriref "http://example.org/#green-goblin"); ] ; ])
;
+(* TODO write test with proper predobjs *)
"[ foaf:name \"Bob\" ]",
Triples.of_bnodps (
BnodPs ([ Predicate.of_iri @@ Iri.of_prefixed_name @@ Prefixed_name.of_strings "foaf" "name",