From 0f65012f1b8221dbced9cba013d373810b067aae Mon Sep 17 00:00:00 2001 From: Colin Okay Date: Sat, 25 Apr 2020 17:55:14 -0500 Subject: added tutorial, added < (let ((string " ")) + (parse string + +PZ-JSON> (let ((string " + ")) + (parse string + +PZ-JSON> + +#+END_SRC + +So what is going on? The combinators =< (parse "hey dude" (< +#+END_SRC + +The parser =(< (parse "hey dude" (< +#+END_SRC + +The parse resulted in failure (indicated by a second return value of +=NIL=) because, though ="dude"= appeared in the input, it was not at +the beginning of the stream. + +At this point it seems clear tha you will will want to define parsers +that look something like this: + +#+BEGIN_SRC lisp +(< (parse "hey dude" (< +PZ-JSON> +#+END_SRC + +Ah! Much easier to understand. You just apply =#'string-upcase= to +the result of =(< +; #'(LAMBDA (NULL) :NULL) +; +; caught STYLE-WARNING: +; The variable NULL is defined but never used. +; +; compilation unit finished +; caught 1 STYLE-WARNING condition +PZ-JSON> (parse "null" + +#+END_SRC + +Hmm everything works, but the compiler isn't happy. It is reporting a +warning that a variable is being defined but not used. You could get +rid of this by doing something like, for example =(declare (ignore +null))=, for each of the above parser definitions, but it isnt +necessary: =parzival= supplies a mapping variant called =< (parse "abcd" (< +PZ-JSON> (parse "abcd" (< +PZ-JSON> + + #+END_SRC + + Both parses succeed, but the second one would have failed if it + were not made optional using =< (< +PZ-JSON> (parse "?a 7" +PZ-JSON> (parse "?z 7" +PZ-JSON> + +#+END_SRC + + What is going on here? The above example, while illustrative, is + perhaps a bit hard to look at. Stay strong - relief will soon be + found when =< (parse "-234.443e-4" +PZ-JSON> (parse "-234.443e4" +PZ-JSON> (parse "4.443E+3" +PZ-JSON> (parse "0.443E+3" +PZ-JSON> (parse "00001.443E+3" +PZ-JSON> + +#+END_SRC + +In the very last REPL example, you see that = (parse "aaba" (< +PZ-JSON> (parse "aaba" (< +#+END_SRC + +And the =< (parse "\"ab\\u6211cd moo \\n\"" +PZ-JSON> (parse "\"ab\\u0123Fcd\"" +PZ-JSON> (parse "\"they call me Colin \\\"Parse Master\\\" Okay\"" +PZ-JSON> +#+END_SRC + + +** Recrusive Parsers + +You're in the home stretch. You've defined parsers for all fo the +primtive value types, and now only the complex types remain. And +here's where you encounter a new and intersting challenge. + +Looking at the JSON document, you notice two things. + +1) There is a definition for a =value=, and value can be, among other + things, an =object= and an =array=. +2) The definitions for =object= and =array= are both in terms of =value=. + +That's right! It's time for recursive parser definitions. + +So, without having defined = (parse "{\"a\" : 10 , \"b\" : 3 }" +PZ-JSON> (parse "{ \"name\" : \"colin\", +\"hobbies\" : [\"lisp\" , \"parsing\" ] , +\"features\" : { \"head\" : \"round\", \"eyes\" : 2} }" +PZ-JSON> + +#+END_SRC + + +** Conclusion + +I hope you have had a good time learning about how this parser +combinator library works. It is a convenient define parsers to +consume streams of text, spitting out values and calling functions +during the parse. + +signing off. +cbeo. + +*** code listing + + For your convenience, the complete code listing follow + +#+BEGIN_SRC lisp +(defpackage :parzival-json + (:use :cl :parzival) + (:nicknames :pz-json)) + +(in-package :parzival-json) + +(<