Isoraqathedh

Full betza parser

Aug 5th, 2014
274
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lisp 1.59 KB | None | 0 0
  1. (define-matcher uppercase (in #\A #\Z))
  2. (define-matcher numerals (in #\0 #\9))
  3.  
  4. (defun read-bracket ()
  5.   "Reads fragments of funny notation inside brackets"
  6.   (consume)
  7.   (loop for next = (peek)
  8.         while (and next (char/= next #\]))
  9.         collect (read-piece)
  10.         finally (consume)))
  11.  
  12. (defun read-piece ()
  13.   "Reads a fragment of funny notation up to a landmark (rN rNN cpR4, up to 1 or 2 capital letter + opt. digit)"
  14.   (let ((tag (consume-until (make-matcher (or :uppercase (any #\[ #\])))))
  15.         (next (peek)))
  16.     (case next
  17.       (#\[ (cons tag (read-bracket)))
  18.       (#\] tag)
  19.       (T (let ((landmark-letter (consume))
  20.                (next-next (peek))
  21.                (not-a-number (make-matcher (not :numerals))))
  22.            (cond ((null next) tag)
  23.                  ((null next-next) (format nil "~a~a" tag landmark-letter))
  24.                  ((char= next-next landmark-letter)
  25.                   ;; Case: doubled and ONLY doubled letters (AA, NN) followed by a number
  26.                   (consume)
  27.                   (format nil "~a~a~a~:[~;~:*~a~]" tag next-next next-next (consume-until not-a-number)))
  28.                  ((find next-next "0123456789" :test #'char-equal) ;; Case: followed ONLY by a number
  29.                   (format nil "~a~a~a" tag landmark-letter (consume-until not-a-number)))
  30.                  (t (format nil "~a~a" tag landmark-letter))))))))
  31.  
  32. (defun funny-notation->parsed-fragments (string)
  33.   "Parses funny notation into smaller pieces for easier processing"
  34.   (with-lexer-environment (string)
  35.     (loop while (peek)
  36.           collect (read-piece))))
Advertisement
Add Comment
Please, Sign In to add comment