tl-rpc.lisp 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. ;;; This file contains modified code from cl-m4 that demonstrates how graylex
  2. ;;; can be used. If you want a full-fledged example including recursive descent
  3. ;;; parsing, please checkout http://github.com/e-user/cl-m4
  4. (defpackage example
  5. (:use :cl :parser-combinators :alexandria))
  6. (in-package :example)
  7. (defun not-equal (a b)
  8. (not (equal a b)))
  9. (defun <ml-not-end> ()
  10. (named-seq? (<- char
  11. (choice (sat (curry #'not-equal #\*))
  12. (except? #\* "*/")))
  13. (string char)))
  14. (defun <ml-content> (ml-comment)
  15. (named-seq? (<- content
  16. (many? (choice (named-seq? (<- inner ml-comment)
  17. (concatenate 'string "/*" inner "*/"))
  18. (<ml-not-end>))))
  19. (apply #'concatenate 'string content)))
  20. (defun <ml-comment> ()
  21. (named? ml-comment
  22. (bracket? "/*" (<ml-content> ml-comment) "*/")))
  23. (defun <sl-comment> ()
  24. (bracket? "//"
  25. (named-seq? (<- comment (many? (sat (curry #'not-equal #\Newline))))
  26. (coerce comment 'string))
  27. #\Newline))
  28. (defun <punctuation> ()
  29. (sat (rcurry #'member '(#\; #\( #\) #\{ #\} #\. #\# #\: #\[ #\] #\= #\? #\% #\+ #\< #\> #\, #\* #\!))))
  30. (defun <token> ()
  31. (choice
  32. (between? (sat #'(lambda (i) (or (alphanumericp i)
  33. (member i '(#\_))))) 1 nil 'string)
  34. (quoted? :quote-char #\`)))
  35. (defun strip-comments (input)
  36. (apply #'concatenate 'string
  37. (remove :comment
  38. (substitute " " nil
  39. (parse-string*
  40. (many? (choices (<token>)
  41. (named-seq? (<- p (<punctuation>)) (string p))
  42. "---"
  43. (whitespace?)
  44. (named-seq? (<sl-comment>) :comment)
  45. (named-seq? (<ml-comment>) :comment)))
  46. input)))))
  47. ;; Actual parser
  48. (defun <hex-digit> ()
  49. (choice (digit?) (sat (rcurry #'member '(#\a #\b #\c #\d #\e #\f)))))
  50. (defun <letter> ()
  51. (choice (lower?) (upper?)))
  52. (defun <ident-char> ()
  53. (choices (<letter>) (digit?) #\_))
  54. (defun concat (&rest args)
  55. (apply #'concatenate 'string args))
  56. (defun string-concat (args)
  57. (apply #'concatenate 'string (mapcar 'string args)))
  58. (defun <lc-ident> ()
  59. (named-seq? (<- hd (lower?))
  60. (<- tl (many? (<ident-char>)))
  61. (coerce (cons hd tl) 'string)))
  62. (defun <uc-ident> ()
  63. (named-seq? (<- hd (upper?))
  64. (<- tl (many? (<ident-char>)))
  65. (coerce (cons hd tl) 'string)))
  66. (defun <namespace-ident> () (<lc-ident>))
  67. (defun <lc-ident-ns> ()
  68. (named-seq? (<- ns (opt? (seq-list? (<namespace-ident>) #\.)))
  69. (<- id (<lc-ident>))
  70. (concat (when ns (string-concat ns)) id)))
  71. (defun <uc-ident-ns> ()
  72. (named-seq? (<- ns (opt? (seq-list? (<namespace-ident>) #\.)))
  73. (<- id (<uc-ident>))
  74. (concat (when ns (string-concat ns)) id)))
  75. (defun <lc-ident-full> ()
  76. (named-seq? (<- id (<lc-ident-ns>))
  77. (<- name (opt? (seq-list? #\# (times? (<hex-digit>) 8))))
  78. (concat id (when name (coerce (apply #'cons name) 'string)))))
  79. (defun <nat-const> ()
  80. (many1? (digit?)))
  81. (defun <boxed-type-ident> () (<uc-ident-ns>))
  82. (defun sep? (&optional accept-empty) (whitespace? :accept-empty accept-empty))
  83. (defun <full-combinator-id> ()
  84. (choice (<lc-ident-full>) "_"))
  85. (defun <combinator-id> ()
  86. (choice (<lc-ident-ns>) "_"))
  87. (defun <type-ident> ()
  88. (choices
  89. (<boxed-type-ident>)
  90. (<lc-ident-ns>)
  91. "#"))
  92. (defun <var-ident> ()
  93. (choice (<lc-ident>) (<uc-ident>)))
  94. (defun <term> (expr)
  95. (named? term
  96. (choices
  97. (seq-list? "(" expr ")")
  98. (<type-ident>)
  99. (<var-ident>)
  100. (<nat-const>)
  101. (seq-list? "%" term)
  102. (seq-list? (<type-ident>) "<" (sepby1? expr ",") ">")
  103. )))
  104. (defun <subexpr> (expr)
  105. (named? subexpr
  106. (choices
  107. (<term> expr)
  108. (seq-list? (<nat-const>) "+" subexpr)
  109. (seq-list? subexpr "+" (<nat-const>)))))
  110. (defun <expr> ()
  111. (named? expr
  112. (many? (<subexpr> expr))))
  113. (defun <type-expr> () (<expr>))
  114. (defun <nat-expr> () (<expr>))
  115. (defun <type-term> () (<term> (<expr>)))
  116. (defun <nat-term> () (<term> (<expr>)))
  117. (defun <opt-args> ()
  118. (named-seq?
  119. "{" (sep? t)
  120. (<- vars (sepby1? (<var-ident>) (sep?))) (sep? t)
  121. ":"
  122. (opt? "!")
  123. (<- type-expr (<type-expr>)) (sep? t)
  124. "}" (sep? t)
  125. (list :opt-args vars type-expr)))
  126. (defun <multiplicity> () (<nat-term>))
  127. (defun <var-ident-opt> () (choices (<var-ident>) "_"))
  128. (defun <conditional-def> ()
  129. (seq-list? (<var-ident>) (opt? (seq-list? "." (<nat-const>))) "?"))
  130. (defun <args> ()
  131. (named? args
  132. (choices
  133. (seq-list? (<var-ident-opt>) ":" (opt? (<conditional-def>)) (opt? "!") (<type-term>))
  134. (seq-list? (opt? (seq-list? (<var-ident-opt>) ":"))
  135. (opt? (seq-list? (<multiplicity>) "*"))
  136. "[" (many? args) "]")
  137. (seq-list? "(" (many1? (<var-ident-opt>)) ":" (opt? "!") (<type-term>) ")")
  138. (seq-list? (opt? "!") (<type-term>)))))
  139. (defun <result-type> ()
  140. (choices
  141. (seq-list? (<boxed-type-ident>) (many? (<subexpr> (<expr>))))
  142. (seq-list? (<boxed-type-ident>) "<" (sepby1? (<subexpr> (<expr>)) ",") ">")))
  143. (defun <combinator-decl> ()
  144. (named-seq?
  145. (<- comb (<full-combinator-id>)) (sep?)
  146. (<- opt-args (many? (<opt-args>))) (sep? t)
  147. (<- args (many? (<args>))) (sep? t)
  148. "=" (sep?)
  149. (<- result-type (<result-type>)) (sep? t)
  150. ";"
  151. (list :comb-decl comb opt-args args result-type)))
  152. (defun <partial-type-app-decl> ()
  153. (choices
  154. (named-seq?
  155. (<- type (<boxed-type-ident>)) (sep?)
  156. (<- ex (many1? (<subexpr> (<expr>)))) (sep?)
  157. ";"
  158. (list :part-type type ex))
  159. (named-seq?
  160. (<- type (<boxed-type-ident>)) (sep?)
  161. "<" (<- ex (sepby1? (<expr>) ",")) ">"
  162. (list :part-type type ex))))
  163. (defun <partial-comb-app-decl> ()
  164. (seq-list? (<combinator-id>) (many1? (<subexpr> (<expr>)))))
  165. (defun <partial-app-decl> ()
  166. (choices
  167. (<partial-type-app-decl>)
  168. (<partial-comb-app-decl>)))
  169. (defun <builtin-combinator-decl> ()
  170. (named-seq?
  171. (<- comb (<full-combinator-id>)) (sep?)
  172. "?" (sep?)
  173. "=" (sep?)
  174. (<- type (<boxed-type-ident>)) (sep? t)
  175. ";"
  176. (list :builtin-decl comb type)))
  177. (defun <final-decl> ()
  178. (named-seq?
  179. (<- type (choices "New" "Final" "Empty"))
  180. (whitespace?)
  181. (<- ind (<boxed-type-ident>)) #\;
  182. (list :final-decl type ind)))
  183. (defun <declaration> ()
  184. (choices (<builtin-combinator-decl>)
  185. (<combinator-decl>)
  186. (<partial-app-decl>)
  187. (<final-decl>)))
  188. (defun <constr-declarations> ()
  189. (many? (named-seq? (<- dec (<declaration>)) #\; dec)))
  190. (defun <fun-declarations> ()
  191. (many? (named-seq? (<- dec (<declaration>)) #\; dec)))
  192. (defun <tl-program> ()
  193. (named-seq? (<- hd (<constr-declarations>))
  194. (whitespace? :accept-empty t)
  195. (<- tl (many?
  196. (choice
  197. (mdo "---" "functions" "---"
  198. (<fun-declarations>))
  199. (mdo "---" "types" "---"
  200. (<constr-declarations>)))))
  201. (cons hd tl)))