Advertisement
Guest User

i am the cl-bnf god now

a guest
Dec 29th, 2018
99
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lisp 2.61 KB | None | 0 0
  1. (defun stringify (thing)
  2.   (coerce thing 'string))
  3.  
  4. (defmacro shuffle-parts (input-parts (tag &rest output-parts))
  5.   (let ((input-parts
  6.          (loop for part in input-parts collect (list part
  7.                                                      (gensym (string part))
  8.                                                      (eql part '_)))))
  9.     `(lambda (parts)
  10.        (destructuring-bind ,(mapcar #'second input-parts) parts
  11.          (declare (ignore ,@(mapcar #'second (remove-if-not #'third input-parts))))
  12.          (list ',tag ,@(loop for part in output-parts
  13.                           collect (second (assoc part input-parts))))))))
  14.  
  15. (set-dispatch-macro-character #\# #\~
  16.                               (lambda (s c n)
  17.                                 (destructuring-bind (input output) (read s)
  18.                                   (macroexpand-1 `(shuffle-parts ,input ,output)))))
  19.  
  20. (define-grammar pdl-parser
  21.     whitespace := (:many (:char #\Space))
  22.    
  23.     pdl-number := (:many (:one #'digit-char-p))
  24.                :call (lambda (match) (parse-integer (stringify match)))
  25.  
  26.     pdl-at          := (:char #\@)
  27.     pdl-left-paren  := (:char #\()
  28.     pdl-right-paren := (:char #\))
  29.     pdl-mutate      := (:string ":=")
  30.                
  31.     pdl-binop-colon := (:char #\:)
  32.     pdl-monop-stop  := (:char #\.)
  33.     pdl-binop-sym   := (:and #'pdl-word #'pdl-binop-colon)
  34.                     :call (lambda (match) (first match))
  35.     pdl-monop-sym   := (:and #'pdl-word #'pdl-monop-stop)
  36.                     :call (lambda (match) (first match))
  37.    
  38.     pdl-word        := (:many (:one #'alpha-char-p))
  39.                     :call (lambda (match) (stringify match))
  40.  
  41.     pdl-binop       := (:and #'pdl-term #'whitespace #'pdl-binop-sym
  42.                              #'whitespace #'pdl-expression)
  43.                     :call #~((a _ s _ c) (:binop s a c))
  44.  
  45.     pdl-monop       := (:and #'pdl-term #'whitespace #'pdl-monop-sym)
  46.                     :call #~((s _ t) (:monop t s))
  47.  
  48.     pdl-mutation    := (:and #'pdl-word #'whitespace #'pdl-mutate
  49.                              #'whitespace #'pdl-expression)
  50.                     :call #~((a _ _ _ b) (:mutate a b))
  51.    
  52.     pdl-getter-fn   := (:and #'pdl-at #'pdl-word)
  53.                     :call (lambda (match) `(:getter ,(second match)))
  54.                    
  55.     pdl-paren-wrap  := (:and #'pdl-left-paren #'pdl-expression #'pdl-right-paren)
  56.                     :call (lambda (match) (second match))
  57.    
  58.     pdl-term        := (:or #'pdl-getter-fn #'pdl-number #'pdl-word #'pdl-paren-wrap)
  59.  
  60.     pdl-expression  := (:or #'pdl-mutation #'pdl-monop #'pdl-binop #'pdl-term)
  61.     )
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement