From e0b792f5bef886e13544a57494bdfca175008c1f Mon Sep 17 00:00:00 2001 From: Utz-Uwe Haus Date: Sat, 4 Oct 2008 22:31:35 +0200 Subject: [PATCH] Add docstrings. Still needs more work, but basic documentation web page can be generated now. Signed-off-by: Utz-Uwe Haus --- package.lisp | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- pegutils.lisp | 35 ++++++++++++++++++++++------------- 2 files changed, 80 insertions(+), 14 deletions(-) diff --git a/package.lisp b/package.lisp index 243fc25..13b870f 100644 --- a/package.lisp +++ b/package.lisp @@ -45,7 +45,64 @@ ;; high-level user interface (:export #:make-string-parser #:make-file-parser - #:make-stream-parser)) + #:make-stream-parser) + (:documentation + "This package provides a parser generator for Parsing Expression Grammars (PEGs) for Common Lisp. + + The canonical project home page is @a[http://primaldual.de/cl-opossum/]{here}, the + @a[http://git.or.cz/]{GIT repository} is hosted on @a[http://repo.or.cz/]{repo.or.cz} under the + project @a[http://repo.or.cz/w/cl-opossum.git]{cl-opossum.git}. You can download a + snapshot of the current master branch head @a[http://repo.or.cz/w/cl-opossum.git?a=snapshot]{here}. + + @begin[Installation]{section} + To make use of this package you will need + @begin{itemize} + @item{A Common Lisp Environment. @a[http://sbcl.sourceforge.net/]{SBCL} is a good free candidate. See + the @a[http://wiki.alu.org/Implementation]{ALU Wiki} for a list of choices.} + @item{(Optionally) @a[http://www.gnu.org/emacs]{Emacs} with @a[http://common-lisp.net/project/slime/]{SLIME} installed.} + @item{The @a[http://www.cliki.net/asdf]{ASDF} System definition package. If you chose SBCL above then you already have it.} + @item{This package, either as a @a[http://repo.or.cz/w/cl-opossum.git?a=snapshot]{snapshot} or through + git by @a[git://repo.or.cz/cl-opossum.git]{git protocol} or @a[http://repo.or.cz/r/cl-opossum.git]{http}.} + @end{itemize} + + If you are using @a[http://www.debian.org]{Debian GNU/Linux} you can fetch the prerequistites by + @pre{apt-get install emacs slime sbcl} + A one-step solution may be @a[http://www.gigamonkeys.com/lispbox/]{Lispbox}. + + If any of the above does not make sense to you, you may want to + start learning more about Common Lisp by reading Peter Seibel's + @em{Practical Common Lisp}, a great Lisp book suitable as + online Common Lisp tutorial + but also available in printed form with ISBN 978-1590592397. + @end{section} + + @begin[Quick start]{section} + If you want to get a quick start, load the package into your lisp and evaluate + @begin{pre} +CL-USER> (asdf:operate 'asdf:load-op :opossum) +; registering # as OPOSSUM +NIL +CL-USER> (setq *p* (opossum:make-string-parser \"example.peg\")) +\[lots of output scrolling by\] +CL-USER> (setq *t* (funcall *p* \"14+7*(1+1)*2\")) +... +CL-USER>(eval *t*) + @end{pre} + @end{section} + + @begin[Literature]{section} + PEG parsers are a family of recursive descent parsers suitable to parsing context free grammars, + in linear time if memoization is used. OPOSSUM currently does not implement memoization, but this will + be fixed soon. See @a[http://pdos.csail.mit.edu/~baford/packrat/]{Bryan Ford}'s home page for details. + @end{section} + @begin[Authors]{section} + This code is released under the GNU Lesser Public License with Lisp clarifications and + copyrighted by + @a[http://www.math.uni-magdeburg.de/~haus/]{Utz-Uwe Haus} + Please see the file @code{LICENSE} in the distribution for details. + @end{section} + + ")) diff --git a/pegutils.lisp b/pegutils.lisp index e9a9382..b1be478 100644 --- a/pegutils.lisp +++ b/pegutils.lisp @@ -53,15 +53,20 @@ :type '(cons (integer 0) null) :documentation "The counter of actions.") ;; these slots are what make a context unique - (parent :accessor parent :initarg :parent :initform nil) - (rule :accessor rule :initarg :rule :initform nil) + (parent :accessor parent :initarg :parent :initform nil + :documentation "Parent context of this context.") + (rule :accessor rule :initarg :rule :initform nil + :documentation "Rule name in this context.") (children :accessor children :initform nil) - (value :accessor value :initarg :value :initform nil) - (start-index :accessor start-index :initarg :start-index :initform nil) - (end-index :accessor end-index :initarg :end-index :initform nil) + (value :accessor value :initarg :value :initform nil + :documentation "Accumulated value after successful matching of rule in this context.") + (start-index :accessor start-index :initarg :start-index :initform nil + :documentation "Position in INPUT where this context starts.") + (end-index :accessor end-index :initarg :end-index :initform nil + :documentation "Position in INPUT where this context's match ends.") (depth :accessor depth :initarg :depth :initform 0 :documentation "How deep in the tree is this context?")) - (:documentation "The parser context.")) + (:documentation "A parser context object.")) (defmethod print-object ((obj context) stream) (print-unreadable-object (obj stream :type T :identity NIL) @@ -69,6 +74,7 @@ (rule obj) (children obj) (value obj) (start-index obj) (end-index obj)))) (defmethod store-action ((ctx context) action) + "Store ACTION in context CTX." (let ((a (actions ctx))) (rplacd a (cons (car a) (cdr a))) (rplaca a action))) @@ -88,12 +94,11 @@ :depth (1+ (depth ctx)))) (defun ctx-failed-p (ctx) - (unless ctx - (break "Botched context")) + "Check whether CTX failed to match." (null (end-index ctx))) (defun succeed (ctx value start-index end-index) - "Mark CTX as successful: set VALUE and matched region." + "Mark CTX as successful: set VALUE and matched region START-INDEX:END-INDEX." (setf (value ctx) value) (setf (start-index ctx) start-index) (setf (end-index ctx) end-index) @@ -103,7 +108,7 @@ ctx) (defun fail () - "Return a failure context." + "Return a failure context generate from *CONTEXT*." (let ((ctx (make-instance 'context :input (input *context*) :rule ':fail @@ -122,12 +127,13 @@ ;; -(defun make-name (string) - (intern (concatenate 'string "parse-" string) +(defun make-name (rule-string) + "Create a symbol suitable for naming the parser function for rule RULE-STRING." + (intern (concatenate 'string "parse-" rule-string) (dst-package *context*))) (defun make-action-name (&key ctx) - "Return a symbol suitable to name the next action." + "Return a symbol suitable to name the next action in the current *CONTEXT*." (incf (car (action-counter *context*))) (let ((aname (if ctx (format nil "opossum-action-~D-srcpos-~D-~D" @@ -142,7 +148,9 @@ (coerce char-list 'string)) (defmacro build-parser-function (name parser) + "Return a function of 1 argument, the offset in *CONTEXT*, parsing using the given PARSER." `(lambda (offset) + ,(format nil "Parse a ~A at the given OFFSET." name) (let ((indent (depth *context*))) (when *trace* (format *trace-output* "~vTTrying to parse a ~A at pos ~D~%" indent ,name offset)) (let* ((*context* (clone-ctx *context* ,name)) @@ -162,6 +170,7 @@ (defun match-string (string) + "Return a function of 1 argument, the offset in *CONTEXT*, that tries to match STRING at that position." #'(lambda (offset) (let ((input (input *context*)) (len (length string))) -- 2.11.4.GIT