test-parser.lisp 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. #-esrap (ql:quickload :esrap)
  2. (require :esrap)
  3. (defpackage #:test-parser
  4. (:use :esrap
  5. :cl)
  6. (:export :display-parse-tree))
  7. (in-package :test-parser)
  8. (defvar *routines* (make-hash-table))
  9. (defvar *variables* (make-hash-table))
  10. (defvar *arrays* (make-hash-table))
  11. (defun not-doublequote (char)
  12. (not (eql #\" char)))
  13. (defun not-integer (string)
  14. (when (find-if-not #'digit-char-p string)
  15. t))
  16. (defrule name
  17. (+ (alphanumericp character))
  18. (:text t))
  19. (defrule space
  20. (+ (or #\Space #\Tab #\Newline))
  21. (:constant nil))
  22. (defrule variable
  23. (and "*v:" name)
  24. (:destructure (vv name)
  25. (declare (ignore vv))
  26. (list :variable name)))
  27. (defrule string-char
  28. (or (not-doublequote character)
  29. (and #\\ #\")))
  30. (defrule string
  31. (and #\" (* string-char) #\")
  32. (:destructure (q1 string q2)
  33. (declare (ignore q1 q2))
  34. (list :string (text string))))
  35. (defrule number
  36. (+ (or "0" "1" "2" "3" "4" "5" "6" "7" "8" "9"))
  37. (:lambda (list)
  38. (list :number (parse-integer (text list)))))
  39. (defrule call-routine
  40. (and "*r:" name "(" (? val-list) ")")
  41. (:destructure (call-syntax name lpar vals rpar)
  42. (declare (ignore call-syntax lpar rpar))
  43. (list 'handle-call-routine name vals)))
  44. (defrule val-list
  45. (+ (or possible-value ", "))
  46. (:destructure (&rest vals)
  47. (let ((list '(:val-list)))
  48. (dolist (value vals)
  49. (if (not (stringp value))
  50. (push value list)))
  51. (reverse list))))
  52. (defrule possible-value
  53. (or string variable number call-routine builtins array array-in))
  54. (defrule assignment
  55. (and (or variable array)
  56. (? space)
  57. #\=
  58. (? space)
  59. possible-value)
  60. (:destructure (var s1 eqlsgn s2 value)
  61. (declare (ignore s1 eqlsgn s2))
  62. (list 'handle-assignment var value)))
  63. (defrule builtins
  64. (and (or "out" "in" "system" "open" "close" "return" "argument" "random") "(" val-list ")")
  65. (:destructure (name start vals end)
  66. (declare (ignore start end))
  67. (list
  68. (cond
  69. ((string= name "out")
  70. 'do-out)
  71. ((string= name "in")
  72. 'do-in)
  73. ((string= name "system")
  74. 'do-system)
  75. ((string= name "open")
  76. 'do-open)
  77. ((string= name "close")
  78. 'do-close)
  79. ((string= name "return")
  80. 'do-return)
  81. ((string= name "argument")
  82. 'do-argument)
  83. ((string= name "random")
  84. 'do-random))
  85. vals)))
  86. (defrule arith-ops
  87. (or "+" "-" "*" "/" "%" "^")
  88. (:lambda (operator)
  89. (cond
  90. ((string= operator "+") :PLUS)
  91. ((string= operator "-") :SUBT)
  92. ((string= operator "*") :MULT)
  93. ((string= operator "/") :DIVD)
  94. ((string= operator "%") :MODU)
  95. ((string= operator "^") :EXPT))))
  96. (defrule arithmetic
  97. (or (and (? "(") (? space) arithmetic (? space) arith-ops (? space) arithmetic (? space) (? ")"))
  98. (or variable number))
  99. (:destructure (first second &optional aritha mspace op mmspace arithb mmmspace rpar)
  100. (if (symbolp first)
  101. (list (list first second))
  102. (list :ARITH
  103. op
  104. aritha
  105. arithb))))
  106. (defrule index
  107. (and ":" possible-value ":")
  108. (:destructure (s val e)
  109. (declare (ignore s e))
  110. val))
  111. (defrule array
  112. (and "*a:" name (? index))
  113. (:destructure (va name index)
  114. (declare (ignore va))
  115. (list :ARRAY name index)))
  116. (defrule array-in
  117. (and "<" val-list ">")
  118. (:destructure (s vals e)
  119. (declare (ignore s e))
  120. (list :aval vals)))
  121. ;; rest goes here
  122. (defrule boolean
  123. (and variable (? space) (or "==" "!=" ">" "<" ">=" "<=") (? space) possible-value)
  124. (:destructure (variable s1 type s2 value)
  125. (declare (ignore s1 s2))
  126. (list :boolean variable type value)))
  127. (defrule bool-name
  128. (or "AND" "NOT" "OR" "NOR")
  129. (:lambda (name)
  130. (cond
  131. ((string= name "AND")
  132. :AND)
  133. ((string= name "NOT")
  134. :NOT)
  135. ((string= name "OR")
  136. :OR)
  137. ((string= name "NOR")
  138. :NOR))))
  139. (defrule statement
  140. (and (? space)
  141. (or assignment call-routine builtins)
  142. (? space) #\; (? space))
  143. (:destructure (space1 statement space2 semicolon space3)
  144. (declare (ignore semicolon space1 space2 space3))
  145. statement))
  146. (defrule block
  147. (* statement)
  148. (:destructure (&rest statements)
  149. (list :block statements)))
  150. (defrule else
  151. (and "ELSE:" space block)
  152. (:destructure (name space block)
  153. (declare (ignore name space))
  154. (list :ELSE block)))
  155. (defrule else-if
  156. (and "ELSE-IF" space boolean #\: block)
  157. (:destructure (start space bool colon block)
  158. (declare (ignore start space colon))
  159. (list :ELSEIF bool block)))
  160. (defrule if
  161. (and "IF" space boolean #\: space
  162. block
  163. (* (or else else-if))
  164. "ENDIF")
  165. (:destructure (start space bool colon morespace block else-else-ifs end)
  166. (declare (ignore start space colon morespace end))
  167. (list :IF bool block else-else-ifs)))
  168. (defrule routine
  169. (and "ROUTINE" (? space) name #\:
  170. block
  171. "END-ROUTINE")
  172. (:destructure (rtn spc1 name colon block end-rtn)
  173. (declare (ignore rtn spc1 colon end-rtn))
  174. (list :routine name block)))
  175. (defrule program
  176. (* (or statement if routine)))
  177. (defun run-string (string)
  178. (run-program (parse 'program string)))
  179. (defun run-program (program-list)
  180. (dolist (chunk program-list)
  181. (let ((type (car chunk)))
  182. (cond
  183. ((eq type :call-routine)
  184. (handle-call-routine chunk))
  185. ((eq type :assignment)
  186. (handle-assignment chunk))
  187. ((eq type :builtins)
  188. (handle-builtins chunk))
  189. ((eq type :block)
  190. (run-program (cdr chunk)))
  191. ((eq type :routine)
  192. (handle-routine chunk))
  193. ((eq type :if)
  194. (handle-if chunk))))))
  195. (defun handle-call-routine (list))
  196. (defun handle-assignment (list))
  197. (defun handle-builtins (list))
  198. (defun handle-routine (list)
  199. (let ((routine-name (cadr list))
  200. (routine (caddr list)))
  201. (setf (gethash (intern routine-name) *routines*) routine)))
  202. (defun handle-if (list))
  203. (defun set-variable (name value))
  204. (defun set-whole-array (name vil value))
  205. (defun set-array-indexed (name index values))
  206. (defun display-parse-tree (string)
  207. (parse 'program string))