Packages

An elixir library for parsing and handling SPARQL queries.

Current section

Files

Jump to
sparqlex lib sparql.ex
Raw

lib/sparql.ex

defmodule Sparql do
@moduledoc """
## Overview
This module offers some functionality to parse SPARQL queries. To do this I
have build a parser with the :leex and :yecc erlang libraries.
## :leex and :yecc
You can find the source files as well as the compiled erlang files
for this under ../parser-generator/
Since this uses raw erlang libraries under the hood all queries that get send
are assumed to be single quoted strings
## TODOs
TODO add a function to remove all graph statements
TODO add a function to override all graph statements with a set of graph statements
"""
@doc """
Parses a SPARQL query that gets passed in a single quoted string
(see erlang documentation on the issues with double quoted strings)
## Examples
iex> Sparql.parse('SELECT ?s ?p ?o WHERE { ?s ?p ?o }')
{:ok,
{:sparql,
{:select,
{:"select-clause", {:"var-list", [variable: :s, variable: :p, variable: :o]}},
{:where,
[
{:"same-subject-path", {:subject, {:variable, :s}},
{:"predicate-list",
[
{{:predicate, {:variable, :p}},
{:"object-list", [object: {:variable, :o}]}}
]}}
]}}
}
}
"""
def parse(raw_query) do
raw_query |> tokenize |> do_parse
end
defp tokenize(raw_query) do
:"sparql-tokenizer".string(raw_query)
end
defp do_parse({:ok, tokenized_query, _}) do
:"sparql-parser".parse(tokenized_query)
end
defp do_parse({:error, _, _} = error_message) do
error_message
end
@doc """
Converts all same-subject-paths into simple subject paths
in SPARQL itself this is the equivalent of converting.
```
?s ?p ?o ; ?p2 ?o2 , ?o3 .
```
to
```
?s ?p ?o .
?s ?p2 ?o2 .
?s ?p2 ?o3 .
```
## Examples
iex> Sparql.convert_to_simple_triples({:"same-subject-path", {:subject, {:variable, :s}},
iex> {:"predicate-list",
iex> [
iex> {{:predicate, {:variable, :p}},
iex> {:"object-list", [object: {:variable, :o}]}}
iex> ]}})
[
{{:subject, {:variable, :s}}, {:predicate, {:variable, :p}}, {:object, {:object, {:variable, :o}}}}
]
"""
def convert_to_simple_triples({:"same-subject-path", {:subject, subject}, {:"predicate-list", predicate_list}})do
convert_to_simple_triples(subject, predicate_list)
end
defp convert_to_simple_triples(subject, predicate_list) do
Enum.map(predicate_list, fn({{:predicate, predicate}, {:"object-list", object_list}}) -> convert_to_simple_triples(subject, predicate, object_list) end)
|> Enum.reduce(fn(x,acc) -> Enum.into(x, acc, fn(x) -> x end) end)
end
defp convert_to_simple_triples(subject, predicate, object_list) do
Enum.map(object_list, fn(object) -> {{:subject, subject}, {:predicate, predicate}, {:object, object}} end)
end
end