PasteRack.org
Paste # 49326
2014-10-29 17:34:28

Fork as a new paste.

Paste viewed 40 times.


Embed:

Parser

  1. #lang racket
  2. ;; The only visible export of this module will be parse-expr.
  3. (provide parse-expr)
  4.  
  5. ;; parse-expr: any input-port -> (U syntax eof)
  6. ;; Either produces a syntax object or the eof object.
  7. (define (parse-expr src in)
  8.   (define-values (line column position) (port-next-location in))
  9.   (define next-char (read-char in))
  10.  
  11.   ;; decorate: s-expression number -> syntax
  12.   ;; Wrap the s-expression with source location.
  13.   (define (decorate sexp span)
  14.     (datum->syntax #f sexp (list src line column position span)))
  15.  
  16.   (cond
  17.     [(eof-object? next-char) eof]
  18.     [else
  19.      (case next-char
  20.        [(#\<) (decorate '(less-than) 1)]
  21.        [(#\>) (decorate '(greater-than) 1)]
  22.        [(#\+) (decorate '(plus) 1)]
  23.        [(#\-) (decorate '(minus) 1)]
  24.        [(#\,) (decorate '(comma) 1)]
  25.        [(#\.) (decorate '(period) 1)]
  26.        [(#\!)
  27.         (define in-str (apply string (parse-input src in)))
  28.         (displayln in-str)
  29.         (decorate '(bang in-str) (- (+ position (string-length in-str)) 1))]
  30.        [(#\[)
  31.         ;; The slightly messy case is bracket.  We keep reading
  32.         ;; a list of exprs, and then construct a wrapping bracket
  33.         ;; around the whole thing.
  34.         (define elements (parse-exprs src in))
  35.         (define-values (l c tail-position)
  36.           (port-next-location in))
  37.         (decorate `(brackets ,@elements)
  38.                   (- tail-position position))]
  39.        [else
  40.         (parse-expr src in)])]))
  41.  
  42. ;; parse-exprs: input-port -> (listof syntax)
  43. ;; Parse a list of expressions.
  44. (define (parse-exprs source-name in)
  45.   (define peeked-char (peek-char in))
  46.   (cond
  47.     [(eof-object? peeked-char)
  48.      (error 'parse-exprs "Expected ], but read eof")]
  49.     [(char=? peeked-char #\!)
  50.      (error 'parse-exprs "Expected ], but read !")]
  51.     [(char=? peeked-char #\])
  52.      (read-char in)
  53.      empty]
  54.     [(member peeked-char (list #\< #\> #\+ #\- #\, #\. #\[))
  55.      (cons (parse-expr source-name in)
  56.            (parse-exprs source-name in))]
  57.     [else
  58.      (read-char in)
  59.      (parse-exprs source-name in)]))
  60.  
  61. (define (parse-input source-name in)
  62.   (define peeked-char (peek-char in))
  63.   (cond
  64.     [(eof-object? peeked-char)
  65.      (displayln "end")
  66.      (read-char in)
  67.      empty]
  68.     [#t
  69.      (cons
  70.        (read-char in)
  71.        (parse-input source-name in))]))

=>