PageRenderTime 24ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/racket-5-0-2-bin-i386-osx-mac-dmg/collects/macro-debugger/model/yacc-interrupted.rkt

http://github.com/smorin/f4f.arc
Racket | 298 lines | 269 code | 21 blank | 8 comment | 16 complexity | ea88c5a638892c65a0a73faacc8e4a15 MD5 | raw file
Possible License(s): LGPL-2.0
  1. #lang racket/base
  2. (require (for-syntax racket/base
  3. unstable/syntax)
  4. "yacc-ext.rkt")
  5. (provide ! ? !!
  6. define-production-splitter
  7. skipped-token-values
  8. %skipped
  9. %action)
  10. ;; Grammar macros for "interrupted parses"
  11. (define-syntax !
  12. (lambda (stx)
  13. (raise-syntax-error #f "keyword ! used out of context" stx)))
  14. (define-syntax !!
  15. (lambda (stx)
  16. (raise-syntax-error #f "keyword !! used out of context" stx)))
  17. (define-syntax ?
  18. (lambda (stx)
  19. (raise-syntax-error #f "keyword ? used out of context" stx)))
  20. (define-syntax define-production-splitter
  21. (syntax-rules ()
  22. [(define-production-splitter name ok intW)
  23. (define-syntax name
  24. (make-production-splitter #'ok #'intW))]))
  25. (define-for-syntax (partition-options/alternates forms)
  26. (let loop ([forms forms] [options null] [alts null])
  27. (if (pair? forms)
  28. (syntax-case (car forms) ()
  29. [(#:args . args)
  30. (loop (cdr forms) (cons (cons '#:args #'args) options) alts)]
  31. [(#:skipped expr)
  32. (loop (cdr forms) (cons (cons '#:skipped #'expr) options) alts)]
  33. [(#:wrap)
  34. (loop (cdr forms) (cons (cons '#:wrap #t) options) alts)]
  35. [(#:no-wrap)
  36. (loop (cdr forms) (cons (cons '#:no-wrap #t) options) alts)]
  37. [(kw . args)
  38. (keyword? (syntax-e #'kw))
  39. (raise-syntax-error 'split "bad keyword" (car forms))]
  40. [(pattern action)
  41. (loop (cdr forms) options (cons (cons #'pattern #'action) alts))]
  42. [other
  43. (raise-syntax-error 'split "bad grammar option or alternate" #'other)])
  44. (values options (reverse alts)))))
  45. (define-for-syntax (I symbol)
  46. (syntax-local-introduce
  47. (syntax-local-get-shadower (datum->syntax #f symbol))))
  48. (define-for-syntax ($name n)
  49. (I (format-symbol "$~a" n)))
  50. (define-for-syntax (interrupted-name id)
  51. (I (format-symbol "~a/Interrupted" (syntax-e id))))
  52. (define-for-syntax (skipped-name id)
  53. (I (format-symbol "~a/Skipped" (syntax-e id))))
  54. (define-for-syntax (elaborate-skipped-tail head tail position args mk-action)
  55. (define-values (new-tail new-arguments)
  56. (let loop ([parts tail] [position position] [rtail null] [arguments null])
  57. (syntax-case parts (? ! !!)
  58. [()
  59. (values (reverse rtail) (reverse arguments))]
  60. [(! . parts-rest)
  61. (loop #'parts-rest position rtail (cons #'#f arguments))]
  62. [(!! . parts-rest)
  63. (raise-syntax-error 'split
  64. "cannot have !! after potential error"
  65. #'!!)]
  66. [((? NT) . parts-rest)
  67. (loop #'(NT . parts-rest) position rtail arguments)]
  68. [(NT . parts-rest)
  69. (identifier? #'NT)
  70. (loop #'parts-rest
  71. (add1 position)
  72. (cons (skipped-name #'NT) rtail)
  73. (cons ($name position) arguments))])))
  74. (define arguments (append (reverse args) new-arguments))
  75. (cons #`(#,head . #,new-tail)
  76. (mk-action arguments)))
  77. (define-for-syntax ((make-elaborate-successful-alternate wrap? okW) alt)
  78. (define pattern (car alt))
  79. (define action-function (cdr alt))
  80. (define-values (new-patterns arguments)
  81. (let loop ([parts pattern] [rpattern null] [position 1] [args null])
  82. (syntax-case parts (? ! !!)
  83. [() (values (list (reverse rpattern)) (reverse args))]
  84. [(! . parts-rest)
  85. (loop #'parts-rest rpattern position (cons #'#f args))]
  86. [(!!)
  87. (values null null)]
  88. [((? NT) . parts-rest)
  89. (loop (cons #'NT #'parts-rest) rpattern position args)]
  90. [(NT . parts-rest)
  91. (identifier? #'NT)
  92. (loop #'parts-rest (cons #'NT rpattern)
  93. (add1 position) (cons ($name position) args))])))
  94. (map (lambda (new-pattern)
  95. (cons (datum->syntax #f new-pattern pattern)
  96. #`(#,action-function #,(if wrap? okW #'values) #,@arguments)))
  97. new-patterns))
  98. (define-for-syntax ((make-elaborate-interrupted-alternate wrap? intW) alt)
  99. (define pattern (car alt))
  100. (define action-function (cdr alt))
  101. (define (int-action args)
  102. (let ([wrapf (if wrap? #`(lambda (x) (#,intW x)) #'values)])
  103. #`(#,action-function #,wrapf #,@args)))
  104. (let loop ([parts pattern] [position 1] [args null])
  105. (syntax-case parts (? ! !!)
  106. [()
  107. ;; Can't be interrupted
  108. null]
  109. [(! . parts-rest)
  110. (cons
  111. ;; Error occurs
  112. (elaborate-skipped-tail (I 'syntax-error)
  113. #'parts-rest
  114. (add1 position)
  115. (cons ($name position) args)
  116. int-action)
  117. ;; Error doesn't occur
  118. (loop #'parts-rest position (cons #'#f args)))]
  119. [(!!)
  120. (cons
  121. (elaborate-skipped-tail (I 'syntax-error)
  122. #'()
  123. (add1 position)
  124. (cons ($name position) args)
  125. int-action)
  126. null)]
  127. [((? NT) . parts-rest)
  128. (cons
  129. ;; NT is interrupted
  130. (elaborate-skipped-tail (interrupted-name #'NT)
  131. #'parts-rest
  132. (add1 position)
  133. (cons ($name position) args)
  134. int-action)
  135. ;; NT is not interrupted
  136. (loop #'(NT . parts-rest) position args))]
  137. [(part0 . parts-rest)
  138. (identifier? #'part0)
  139. (map (lambda (clause) (cons #`(part0 . #,(car clause)) (cdr clause)))
  140. (loop #'parts-rest (add1 position) (cons ($name position) args)))])))
  141. (define-for-syntax (generate-action-name nt pos)
  142. (syntax-local-get-shadower
  143. (format-id #f "action-for-~a/~a" (syntax-e nt) pos)))
  144. (define-for-syntax ((make-rewrite-alt+def nt args-spec) alt pos)
  145. (define pattern (car alt))
  146. (define action (cdr alt))
  147. (define-values (var-indexes non-var-indexes)
  148. (let loop ([pattern pattern] [n 1] [vars null] [nonvars null])
  149. (syntax-case pattern ()
  150. [(first . more)
  151. (syntax-case #'first (! ? !!)
  152. [!
  153. (loop #'more (add1 n) (cons n vars) nonvars)]
  154. [(! . _)
  155. (raise-syntax-error 'split
  156. "misuse of ! grammar form"
  157. pattern #'first)]
  158. [!!
  159. (when (pair? (syntax-e #'more))
  160. (raise-syntax-error 'split
  161. "nothing may follow !!"
  162. pattern))
  163. (loop #'more (add1 n) (cons n vars) nonvars)]
  164. [(!! . _)
  165. (raise-syntax-error 'split
  166. "misuse of !! grammar form"
  167. pattern #'first)]
  168. [(? NT)
  169. (identifier? #'NT)
  170. (loop #'more (add1 n) (cons n vars) nonvars)]
  171. [(? . _)
  172. (raise-syntax-error 'split
  173. "misuse of ? grammar form"
  174. pattern #'first)]
  175. [NT
  176. (identifier? #'NT)
  177. (loop #'more (add1 n) (cons n vars) nonvars)]
  178. [other
  179. (raise-syntax-error 'rewrite-pattern
  180. "invalid grammar pattern"
  181. pattern #'first)])]
  182. [()
  183. (values (reverse vars) (reverse nonvars))])))
  184. (define variables (map $name var-indexes))
  185. (define non-var-names (map $name non-var-indexes))
  186. (define action-function (generate-action-name nt pos))
  187. (cons (cons pattern action-function)
  188. (with-syntax ([(var ...) variables]
  189. [(nonvar ...) non-var-names]
  190. [action-function action-function]
  191. [action action])
  192. #`(define (action-function wrap var ...)
  193. (let-syntax ([nonvar invalid-$name-use] ...)
  194. #,(if args-spec
  195. #`(lambda #,args-spec (wrap action))
  196. #`(wrap action)))))))
  197. (define-for-syntax (invalid-$name-use stx)
  198. (raise-syntax-error #f "no value for positional variable" stx))
  199. ;; An alternate is (cons pattern action-expr)
  200. ;; An alternate* is (cons pattern action-function-name)
  201. (define-for-syntax ((make-production-splitter okW intW) stx)
  202. (syntax-case stx ()
  203. [(_ (name form ...))
  204. (let ()
  205. (define-values (options alternates0)
  206. (partition-options/alternates (syntax->list #'(form ...))))
  207. (define wrap?
  208. (let ([wrap? (assq '#:wrap options)]
  209. [no-wrap? (assq '#:no-wrap options)])
  210. (when (and wrap? no-wrap?)
  211. (raise-syntax-error 'split
  212. "cannot specify both #:wrap and #:no-wrap"
  213. stx))
  214. #;
  215. (unless (and (or wrap? no-wrap?) (not (and wrap? no-wrap?)))
  216. (raise-syntax-error 'split
  217. "must specify exactly one of #:wrap, #:no-wrap"
  218. stx))
  219. (and wrap? #t)))
  220. (define args-spec
  221. (let ([p (assq '#:args options)]) (and p (cdr p))))
  222. (define rewrite-alt+def (make-rewrite-alt+def #'name args-spec))
  223. (define alternates+definitions
  224. (map rewrite-alt+def alternates0 (build-list (length alternates0) add1)))
  225. (define alternates (map car alternates+definitions))
  226. (define action-definitions (map cdr alternates+definitions))
  227. (define elaborate-successful-alternate
  228. (make-elaborate-successful-alternate wrap? okW))
  229. (define elaborate-interrupted-alternate
  230. (make-elaborate-interrupted-alternate wrap? intW))
  231. (define successful-alternates
  232. (apply append (map elaborate-successful-alternate alternates)))
  233. (define interrupted-alternates
  234. (apply append (map elaborate-interrupted-alternate alternates)))
  235. (with-syntax ([((success-pattern . success-action) ...)
  236. successful-alternates]
  237. [((interrupted-pattern . interrupted-action) ...)
  238. interrupted-alternates]
  239. [skip-spec (assq '#:skipped options)]
  240. [args-spec (assq '#:args options)]
  241. [name/Skipped (skipped-name #'name)]
  242. [name/Interrupted (interrupted-name #'name)]
  243. [%action ((syntax-local-certifier) #'%action)])
  244. #`(begin
  245. (definitions #,@action-definitions)
  246. (productions
  247. (name [success-pattern success-action] ...)
  248. #,(if (pair? interrupted-alternates)
  249. #'(name/Interrupted [interrupted-pattern interrupted-action]
  250. ...)
  251. #'(name/Interrupted [(IMPOSSIBLE) #f]))
  252. (name/Skipped [() (%skipped args-spec skip-spec)])))))]))
  253. (define-syntax (skipped-token-values stx)
  254. (syntax-case stx ()
  255. [(skipped-token-values)
  256. #'(begin)]
  257. [(skipped-token-values name . more)
  258. (identifier? #'name)
  259. (with-syntax ([name/Skipped (skipped-name #'name)])
  260. #'(begin (productions (name/Skipped [() #f]))
  261. (skipped-token-values . more)))]
  262. [(skipped-token-values (name value) . more)
  263. (with-syntax ([name/Skipped (skipped-name #'name)])
  264. #'(begin (productions (name/Skipped [() value]))
  265. (skipped-token-values . more)))]))
  266. (define-syntax (%skipped stx)
  267. (syntax-case stx ()
  268. [(%skipped args (#:skipped . expr))
  269. #'(%action args expr)]
  270. [(%skipped args #f)
  271. #'(%action args #f)]))
  272. (define-syntax (%action stx)
  273. (syntax-case stx ()
  274. [(%action (#:args . args) action)
  275. #'(lambda args action)]
  276. [(%action #f action)
  277. #'action]))