config-parser.lisp 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. ;;;; config-parser.lisp
  2. #+quicklisp (ql:quickload :parse-number)
  3. (defpackage #:config-parser
  4. (:use :esrap
  5. :cl)
  6. (:import-from #:parse-number
  7. #:parse-number)
  8. (:export open-configuration-file
  9. get-config-drive))
  10. (in-package #:config-parser)
  11. ;;; "config-parser" goes here. Hacks and glory await!
  12. (defrule space
  13. (+ (or #\Space #\Tab #\Newline))
  14. (:constant nil))
  15. (defrule identifier
  16. (* (or (alphanumericp character) "_" "-" "."))
  17. (:text t)
  18. (:lambda (identifier)
  19. (intern (string-upcase identifier) "KEYWORD")))
  20. (defun not-doublequote (character)
  21. (not (eql #\" character)))
  22. (defrule string-chars
  23. (or (not-doublequote character)
  24. (and #\\ #\")))
  25. (defrule string
  26. (and #\" (* string-chars) #\")
  27. (:destructure (sq string eq)
  28. (declare (ignore sq eq))
  29. (text string)))
  30. (defrule number
  31. (and (? (or "-" "+"))
  32. (+ (or "0" "1" "2" "3" "4" "5" "6" "7" "8" "9"))
  33. (? (and "."
  34. (+ (or "0" "1" "2" "3" "4" "5" "6" "7" "8" "9"))))
  35. (? (and (or "e" "E")
  36. (? "-")
  37. (+ (or "0" "1" "2" "3" "4" "5" "6" "7" "8" "9")))))
  38. (:text t)
  39. (:lambda (num-string)
  40. (parse-number num-string)))
  41. (defrule block-title
  42. (and (? #\Newline) "[" (? space) identifier (? space) "]" (? #\Newline))
  43. (:destructure (nl1 lb sp1 ident sp2 rb nl)
  44. (declare (ignore nl1 lb sp1 sp2 rb nl))
  45. ident))
  46. (defrule ident-path
  47. (and identifier (? space) "/" (? space) identifier)
  48. (:destructure (identa sp1 sep sp2 identb)
  49. (declare (ignore sp1 sep sp2))
  50. (list identa identb)))
  51. (defrule variable-expression
  52. (and identifier (? space) "=" (? space) (or string number ident-path) (? #\Newline))
  53. (:destructure (identifier sp1 eq sp2 value nl)
  54. (declare (ignore sp1 eq sp2 nl))
  55. (cons identifier value)))
  56. (defrule block-contents
  57. (* variable-expression)
  58. (:lambda (expressions)
  59. (loop for expression in expressions
  60. collect expression)))
  61. (defrule block
  62. (and block-title block-contents)
  63. (:destructure (title contents)
  64. (cons title contents)))
  65. (defrule file
  66. (* block)
  67. (:lambda (blocks)
  68. (loop for block in blocks
  69. collect block)))
  70. (defun open-configuration-file (filename)
  71. (parse 'file
  72. (concatenate 'string
  73. (with-open-file (input-file filename)
  74. (loop for char = (read-char input-file nil 'foo)
  75. until (eq char 'foo)
  76. collect char)))))
  77. (defun get-config-drive (section ident config)
  78. (cdr (assoc ident (cdr (assoc section config)))))