Author: lgiessmann Date: Sun Nov 21 14:57:58 2010 New Revision: 345
Log: TM-SPARQL: fixed a bug by calling the next function from a group-pattern
Modified: trunk/src/TM-SPARQL/sparql_parser.lisp trunk/src/unit_tests/sparql_test.lisp
Modified: trunk/src/TM-SPARQL/sparql_parser.lisp ============================================================================== --- trunk/src/TM-SPARQL/sparql_parser.lisp (original) +++ trunk/src/TM-SPARQL/sparql_parser.lisp Sun Nov 21 14:57:58 2010 @@ -23,6 +23,27 @@ (make-condition 'sparql-parser-error :message message)))
+(defun parse-closed-value(query-string query-object &key (open "<") (close ">")) + "A helper function that checks the value of a statement within + two brackets, i.e. <prefix-value>. A list of the + form (:next-query string :value string) is returned." + (declare (String query-string open close) + (SPARQL-Query query-object)) + (let ((trimmed-string (cut-comment query-string))) + (if (string-starts-with trimmed-string open) + (let* ((pref-url (string-until (string-after trimmed-string open) close)) + (next-query-str (string-after trimmed-string close))) + (unless next-query-str + (error (make-sparql-parser-condition + trimmed-string (original-query query-object) + close))) + (list :next-query next-query-str + :value pref-url)) + (error (make-sparql-parser-condition + trimmed-string (original-query query-object) + close))))) + + (defun cut-comment (query-string) "Returns the given string back. If the query starts with a # or space # the characters until the nextline are removed." @@ -70,8 +91,8 @@ (unless (string-starts-with next-query "WHERE") (error (make-sparql-parser-condition next-query (original-query construct) "WHERE"))) - (let* ((tripples (string-after next-query "WHERE")) - (query-tail (parse-where construct tripples))) + (let* ((triples (string-after next-query "WHERE")) + (query-tail (parse-where construct triples))) (or query-tail) ;TODO: process tail-of query, e.g. order by, ... construct))))
@@ -83,12 +104,15 @@ (unless (string-starts-with trimmed-str "{") (error (make-sparql-parser-condition trimmed-str (original-query construct) "{"))) - (parse-group construct (subseq trimmed-str 1) nil)))) + (let ((query-tail (parse-group construct (subseq trimmed-str 1) nil nil))) + ;TODO: process query-tail + query-tail))))
-(defgeneric parse-group (construct query-string values) +(defgeneric parse-group (construct query-string values filters) (:documentation "The entry-point for the parsing of a {} statement.") - (:method ((construct SPARQL-Query) (query-string String) (values List)) + (:method ((construct SPARQL-Query) (query-string String) + (values List) (filters List)) (let ((trimmed-str (cut-comment query-string))) (cond ((string-starts-with trimmed-str "BASE") (parse-base construct (string-after trimmed-str "BASE") @@ -96,26 +120,29 @@ ((string-starts-with trimmed-str "{") (error (make-sparql-parser-condition trimmed-str (original-query construct) - "FILTER, BASE, or tripple. Grouping is currently no implemented."))) + "FILTER, BASE, or triple. Grouping is currently no implemented."))) ((string-starts-with trimmed-str "FILTER") - nil) ;TODO: implement => save the filters and call - ;it after invoking parse-tripples + nil) ;TODO: call parse-group with added filter ((string-starts-with trimmed-str "OPTIONAL") (error (make-sparql-parser-condition trimmed-str (original-query construct) - "FILTER, BASE, or tripple. Grouping is currently no implemented."))) + "FILTER, BASE, or triple. Grouping is currently no implemented."))) ((string-starts-with trimmed-str "UNION") (error (make-sparql-parser-condition trimmed-str (original-query construct) - "FILTER, BASE, or tripple. Grouping is currently no implemented."))) + "FILTER, BASE, or triple. Grouping is currently no implemented."))) ((string-starts-with trimmed-str "}") ;ending of this group + ;TODO: invoke filters with all results (subseq trimmed-str 1)) (t - (parse-tripple construct trimmed-str values)))))) + (let ((result (parse-triple construct trimmed-str values))) + (parse-group construct (getf result :next-query) + (getf result :values) filters))))))) +
-(defun parse-tripple-elem (query-string query-object &key (literal-allowed nil)) - "A helper function to parse a subject or predicate of an RDF tripple. +(defun parse-triple-elem (query-string query-object &key (literal-allowed nil)) + "A helper function to parse a subject or predicate of an RDF triple. Returns an entry of the form (:value (:value string :type <'VAR|'IRI|'LITERAL>) :next-query string)." (declare (String query-string) @@ -188,7 +215,7 @@ *xml-string*)) (next-query (getf result-2 :next-query))) (list :next-query next-query :lang l-lang :type l-lang - :value (cast-literal l-value l-type query-object)))) + :value (cast-literal l-value l-type))))
(defun cast-literal (literal-value literal-type) @@ -232,10 +259,10 @@ after the closing literal bounding." (declare (String query-string) (SPARQL-Query query-object)) - (let ((delimiters (list " ." ". " ";" "}" " " (string #\tab) + (let ((delimiters (list "." ";" "}" " " (string #\tab) (string #\newline)))) (cond ((string-starts-with query-string "@") - (let ((end-pos (search-first (append delimiters (list ".")) + (let ((end-pos (search-first delimiters (subseq query-string 1)))) (unless end-pos (error (make-sparql-parser-condition @@ -303,19 +330,19 @@ (defun parse-literal-number-value (query-string query-object) "A helper function that parses any number that is a literal. The return value is of the form - (list :value nil :type string :pos int)." + (list :value nil :type string :next-query string." (declare (String query-string) (SPARQL-Query query-object)) (let* ((trimmed-str (cut-comment query-string)) (triple-delimiters - (list ". " ". " ";" " " (string #\tab) + (list ". " ";" " " (string #\tab) (string #\newline) "}")) (end-pos (search-first triple-delimiters trimmed-str))) (unless end-pos (error (make-sparql-parser-condition trimmed-str (original-query query-object) - "'. ', ' .', ';' ' ', '\t', '\n' or '}'"))) + "'. ', , ';' ' ', '\t', '\n' or '}'"))) (let* ((literal-number (read-from-string (subseq trimmed-str 0 end-pos))) (number-type @@ -374,53 +401,39 @@ :type 'IRI))))
-(defgeneric parse-tripple (construct query-string values) - (:documentation "Parses a tripple within a trippel group and returns a +(defgeneric parse-triple (construct query-string values &key last-subject) + (:documentation "Parses a triple within a trippel group and returns a a list of the form (:next-query :subject (:type <'VAR|'IRI> :value string) :predicate (:type <'VAR|'IRI> :value string) :object (:type <'VAR|'IRI|'LITERAL> :value string)).") - (:method ((construct SPARQL-Query) (query-string String) (values List)) + (:method ((construct SPARQL-Query) (query-string String) (values List) + &key (last-subject nil)) + (declare (List last-subject)) (let* ((trimmed-str (cut-comment query-string)) - (subject - (let ((result (parse-tripple-elem trimmed-str construct))) - (setf trimmed-str (getf result :next-query)) - (getf result :value))) - (predicate - (let ((result (parse-tripple-elem trimmed-str construct))) - (setf trimmed-str (getf result :next-query)) - (getf result :value))) - (object - (let ((result (parse-tripple-elem trimmed-str construct - :literal-allowed t))) - (setf trimmed-str (getf result :next-query)) - (getf result :value)))) - (or subject object predicate);;TODO: implement - ;; 0) ; => use last subject - ;; 1) search for <url> => if full-url use it otherwise set bse - ;; 2) search for label:suffix - ;; 3) varname => ?|$ - ;; 4) literal => only the object - - ;; => BASE is also allowed - ;; => ;-shortcut - - ;; <full-url> - ;; <base-suffix> - ;; label:pref-suffix - ;; ?var - ;; $var - ;; "literal" - ;; 'literal' - ;; "literal"@language - ;; "literal"^^type - ;; '''"literal"''' - ;; 1, which is the same as "1"^^xsd:integer - ;; 1.3, which is the same as "1.3"^^xsd:decimal - ;; 1.300, which is the same as "1.300"^^xsd:decimal - ;; 1.0e6, which is the same as "1.0e6"^^xsd:double - ;; true, which is the same as "true"^^xsd:boolean - ;; false, which is the same as "false"^^xsd:boolean - ))) + (subject-result (if last-subject ;;is used after a ";" + last-subject + (parse-triple-elem trimmed-str construct))) + (predicate-result (parse-triple-elem + (if last-subject + trimmed-str + (getf subject-result :next-query)) + construct)) + (object-result (parse-triple-elem (getf predicate-result :next-query) + construct :literal-allowed t)) + (all-values (append values + (list :subject (getf subject-result :value) + :predicate (getf predicate-result :value) + :object (getf object-result :value))))) + (let ((tr-str (cut-comment (getf object-result :next-query)))) + (cond ((string-starts-with tr-str ";") + (parse-triple construct (subseq tr-str 1) all-values + :last-subject (list :value + (getf subject-result :value)))) + ((string-starts-with tr-str ".") + (parse-triple construct (subseq tr-str 1) all-values)) + ((string-starts-with tr-str "}") ;no other triples follows + (list :next-query tr-str + :values all-values)))))))
(defgeneric parse-variables (construct query-string) @@ -498,25 +511,4 @@ (error (make-sparql-parser-condition trimmed-string (original-query construct) ":"))) (add-prefix construct label-name (getf results :value)) - (parser-start construct (getf results :next-query))))))) - - -(defun parse-closed-value(query-string query-object &key (open "<") (close ">")) - "A helper function that checks the value of a statement within - two brackets, i.e. <prefix-value>. A list of the - form (:next-query string :value string) is returned." - (declare (String query-string open close) - (SPARQL-Query query-object)) - (let ((trimmed-string (cut-comment query-string))) - (if (string-starts-with trimmed-string open) - (let* ((pref-url (string-until (string-after trimmed-string open) close)) - (next-query-str (string-after trimmed-string close))) - (unless next-query-str - (error (make-sparql-parser-condition - trimmed-string (original-query query-object) - close))) - (list :next-query next-query-str - :value pref-url)) - (error (make-sparql-parser-condition - trimmed-string (original-query query-object) - close))))) \ No newline at end of file + (parser-start construct (getf results :next-query))))))) \ No newline at end of file
Modified: trunk/src/unit_tests/sparql_test.lisp ============================================================================== --- trunk/src/unit_tests/sparql_test.lisp (original) +++ trunk/src/unit_tests/sparql_test.lisp Sun Nov 21 14:57:58 2010 @@ -11,7 +11,8 @@ (:use :cl :it.bese.FiveAM :TM-SPARQL - :exceptions) + :exceptions + :constants) (:export :run-sparql-tests :sparql-tests :test-prefix-and-base)) @@ -151,5 +152,19 @@ (TM-SPARQL::variables query-object-3)))))
+;(test test-parse-literal-string-value +; "Tests the helper function parse-literal-string-value." +; (let ((query-1 " "literal-value"@de.") +; (query-2 "true.") +; (query-3 "false}") +; (query-4 "1234.43e10") +; (query-4 (concatenate 'string "'''true'''"^^" *xml-boolean* " ;")) + + + ;TODO: delimiter " ;" or " ." + ;TODO: handle: subject predicate object; predicate object +; ) + + (defun run-sparql-tests () (it.bese.fiveam:run! 'sparql-test:sparql-tests)) \ No newline at end of file