@prefix log: <http://www.w3.org/2000/10/swap/log#>.
@prefix : <http://example.org#>.

[] log:dcg
    "sentence(triple(NP, '<http://example.org#sentence>', VP)) --> noun_phrase(NP), verb_phrase(VP)",
    "noun_phrase(triple(D, '<http://example.org#nounPhrase>', N)) --> determiner(D), noun(N)",
    "verb_phrase(triple(V, '<http://example.org#verbPhrase>', NP)) --> verb(V), noun_phrase(NP)",
    "determiner(triple('<http://example.org#the>', '<http://www.w3.org/1999/02/22-rdf-syntax-ns#type>', '<http://example.org#Determiner>')) --> [the]",
    "determiner(triple('<http://example.org#a>', '<http://www.w3.org/1999/02/22-rdf-syntax-ns#type>', '<http://example.org#Determiner>')) --> [a]",
    "noun(triple('<http://example.org#cat>', '<http://www.w3.org/1999/02/22-rdf-syntax-ns#type>', '<http://example.org#Noun>')) --> [cat]",
    "noun(triple('<http://example.org#bat>', '<http://www.w3.org/1999/02/22-rdf-syntax-ns#type>', '<http://example.org#Noun>')) --> [bat]",
    "verb(triple('<http://example.org#eats>', '<http://www.w3.org/1999/02/22-rdf-syntax-ns#type>', '<http://example.org#Verb>')) --> [eats]".

{("sentence(S)" ?S) log:phrase ("the" "cat" "eats" "a" "bat")} => {:parseTree :is ?S}.

{:parseTree :is <<( ?S ?P ?O )>>} => {[] a :ParseTree; :node ?P; :left ?S; :right ?O}.
{?A :left <<( ?S ?P ?O )>>} => {[] :parent ?A; :node ?P; :left ?S; :right ?O}.
{?A :right <<( ?S ?P ?O )>>} => {[] :parent ?A; :node ?P; :left ?S; :right ?O}.
