aboutsummaryrefslogtreecommitdiff
path: root/docgen.lisp
diff options
context:
space:
mode:
authorcolin <colin@cicadas.surf>2023-08-02 21:01:03 -0700
committercolin <colin@cicadas.surf>2023-08-02 21:01:03 -0700
commit5800a49934ab75be17f03af8c9a2243120a97339 (patch)
tree86c5f02f0dcc2c884f5a1dddeac8b22675f23e94 /docgen.lisp
parent483867e966e5b009be1892cc3f81de0b5885ba17 (diff)
Add docgen
Diffstat (limited to 'docgen.lisp')
-rw-r--r--docgen.lisp56
1 files changed, 56 insertions, 0 deletions
diff --git a/docgen.lisp b/docgen.lisp
new file mode 100644
index 0000000..cc19133
--- /dev/null
+++ b/docgen.lisp
@@ -0,0 +1,56 @@
+;;;; docgen.lisp -- generate a docstring from a grammar
+
+(in-package #:argot)
+
+(defun write-rule-doc (lhs pattern)
+ (format *standard-output* "~15s ::= " lhs)
+ (write-pattern-doc pattern ))
+
+(defun write-sequence-doc (args )
+ (loop :for (a . more) :on args
+ :do (write-pattern-doc a )
+ (when more
+ (princ " " ))))
+
+(defun write-optional-doc (arg)
+ (princ "[")
+ (write-pattern-doc arg)
+ (princ "]"))
+
+(defun write-kleene-doc (arg)
+ (write-pattern-doc arg)
+ (princ "*"))
+
+(defun write-one-or-more-doc (arg)
+ (write-pattern-doc arg)
+ (princ "+"))
+
+(defun write-alternatives-doc (args)
+ (loop :for (a . more) :on args
+ :do (write-pattern-doc a)
+ (when more
+ (princ " | "))))
+
+(defun write-grammar-pattern-doc (grammar-name)
+ (princ "{") (princ grammar-name) (princ "}"))
+
+(defun write-pattern-doc (pattern )
+ (if (atom pattern)
+ (princ pattern)
+ (destructuring-bind (op . args) pattern
+ (case op
+ ((:seq :seq=) (write-sequence-doc args ))
+ ((:? :?=) (write-optional-doc (first args)))
+ ((:* :*=) (write-kleene-doc (first args)))
+ ((:+ :+=) (write-one-or-more-doc (first args)))
+ ((:or :or=) (write-alternatives-doc args))
+
+ (:= (princ (first args)))
+ (:@ (write-pattern-doc (second args)))
+ (:{} (write-grammar-pattern-doc (first args)))
+
+ (:item (princ "::TOKEN::"))
+ (:eof (princ "::EOF::"))))))
+
+
+