You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

56 lines
1.8KB

  1. (module parse (parse-line lift followed-by-consuming is-not parse-whitespace skip-whitespace parse-symbol parse-number parse-string followed-by-consuming separated-by parse-symbol-or-number-or-string completely-parse parse-statement parse-line)
  2. (import scheme)
  3. (import chicken.base)
  4. (import srfi-13)
  5. (import srfi-14)
  6. (import util)
  7. (import comparse)
  8. (define +letter-char-set+
  9. (string->char-set "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVwXYZ"))
  10. (define +symbol-char-set+
  11. (char-set-union +letter-char-set+ (string->char-set "-0123456789")))
  12. (define (lift fn parser)
  13. (bind parser (compose result fn)))
  14. (define (is-not x)
  15. (satisfies (lambda (y)
  16. (not (eqv? x y)))))
  17. (define parse-whitespace
  18. (one-or-more (is #\space)))
  19. (define skip-whitespace
  20. (skip (zero-or-more (is #\space))))
  21. (define parse-symbol
  22. (lift (compose string->symbol string-downcase list->string (applied append))
  23. (sequence (lift list (in +letter-char-set+)) (zero-or-more (in +symbol-char-set+)))))
  24. (define parse-number
  25. (lift (compose string->number list->string) (one-or-more (in char-set:digit))))
  26. (define parse-string
  27. (lift list->string (enclosed-by (is #\") (one-or-more (is-not #\")) (is #\"))))
  28. (define (followed-by-consuming parser separator)
  29. (sequence* ((value parser) (_ separator))
  30. (result value)))
  31. (define (separated-by separator parser)
  32. (one-or-more (any-of (followed-by-consuming parser separator) parser)))
  33. (define parse-symbol-or-number-or-string
  34. (any-of parse-number parse-symbol parse-string))
  35. (define (completely-parse parser)
  36. (followed-by parser end-of-input))
  37. (define parse-statement
  38. (all-of skip-whitespace (separated-by parse-whitespace parse-symbol-or-number-or-string)))
  39. (define (parse-line line)
  40. (parse (completely-parse parse-statement) line)))