|
|
@ -47,18 +47,16 @@
|
|
|
|
(define-struct tasks (active active-back waits multi-waits cache progress?))
|
|
|
|
(define-struct tasks (active active-back waits multi-waits cache progress?))
|
|
|
|
|
|
|
|
|
|
|
|
(define-for-syntax make-token-identifier-mapping make-hasheq)
|
|
|
|
(define-for-syntax make-token-identifier-mapping make-hasheq)
|
|
|
|
(define-for-syntax token-identifier-mapping-get
|
|
|
|
(define-for-syntax (token-identifier-mapping-get t tok [fail #f])
|
|
|
|
(case-lambda
|
|
|
|
(if fail
|
|
|
|
[(t tok)
|
|
|
|
(hash-ref t (syntax-e tok) fail)
|
|
|
|
(hash-ref t (syntax-e tok))]
|
|
|
|
(hash-ref t (syntax-e tok))))
|
|
|
|
[(t tok fail)
|
|
|
|
|
|
|
|
(hash-ref t (syntax-e tok) fail)]))
|
|
|
|
(define-for-syntax (token-identifier-mapping-put! t tok v)
|
|
|
|
(define-for-syntax token-identifier-mapping-put!
|
|
|
|
(hash-set! t (syntax-e tok) v))
|
|
|
|
(lambda (t tok v)
|
|
|
|
|
|
|
|
(hash-set! t (syntax-e tok) v)))
|
|
|
|
(define-for-syntax (token-identifier-mapping-map t f)
|
|
|
|
(define-for-syntax token-identifier-mapping-map
|
|
|
|
(hash-map t f))
|
|
|
|
(lambda (t f)
|
|
|
|
|
|
|
|
(hash-map t f)))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;; Used to calculate information on the grammar, such as whether
|
|
|
|
;; Used to calculate information on the grammar, such as whether
|
|
|
|
;; a particular non-terminal is "simple" instead of recursively defined.
|
|
|
|
;; a particular non-terminal is "simple" instead of recursively defined.
|
|
|
@ -71,7 +69,7 @@
|
|
|
|
(cdr as) (cdr bs))]))
|
|
|
|
(cdr as) (cdr bs))]))
|
|
|
|
(let loop ()
|
|
|
|
(let loop ()
|
|
|
|
(when (ormap-all #f
|
|
|
|
(when (ormap-all #f
|
|
|
|
(lambda (nt pats)
|
|
|
|
(λ (nt pats)
|
|
|
|
(let ([old (bound-identifier-mapping-get nts nt)])
|
|
|
|
(let ([old (bound-identifier-mapping-get nts nt)])
|
|
|
|
(let ([new (proc nt pats old)])
|
|
|
|
(let ([new (proc nt pats old)])
|
|
|
|
(if (equal? old new)
|
|
|
|
(if (equal? old new)
|
|
|
@ -88,149 +86,120 @@
|
|
|
|
(define (parse-and simple-a? parse-a parse-b
|
|
|
|
(define (parse-and simple-a? parse-a parse-b
|
|
|
|
stream last-consumed-token depth end success-k fail-k
|
|
|
|
stream last-consumed-token depth end success-k fail-k
|
|
|
|
max-depth tasks)
|
|
|
|
max-depth tasks)
|
|
|
|
(letrec ([mk-got-k
|
|
|
|
(define ((mk-got-k success-k fail-k) val stream last-consumed-token depth max-depth tasks next1-k)
|
|
|
|
(lambda (success-k fail-k)
|
|
|
|
|
|
|
|
(lambda (val stream last-consumed-token depth max-depth tasks next1-k)
|
|
|
|
|
|
|
|
(if simple-a?
|
|
|
|
(if simple-a?
|
|
|
|
(parse-b val stream last-consumed-token depth end
|
|
|
|
(parse-b val stream last-consumed-token depth end
|
|
|
|
(mk-got2-k success-k fail-k next1-k)
|
|
|
|
(mk-got2-k success-k fail-k next1-k)
|
|
|
|
(mk-fail2-k success-k fail-k next1-k)
|
|
|
|
(mk-fail2-k success-k fail-k next1-k)
|
|
|
|
max-depth tasks)
|
|
|
|
max-depth tasks)
|
|
|
|
(parallel-or
|
|
|
|
(parallel-or
|
|
|
|
(lambda (success-k fail-k max-depth tasks)
|
|
|
|
(λ (success-k fail-k max-depth tasks)
|
|
|
|
(parse-b val stream last-consumed-token depth end
|
|
|
|
(parse-b val stream last-consumed-token depth end
|
|
|
|
success-k fail-k
|
|
|
|
success-k fail-k
|
|
|
|
max-depth tasks))
|
|
|
|
max-depth tasks))
|
|
|
|
(lambda (success-k fail-k max-depth tasks)
|
|
|
|
(λ (success-k fail-k max-depth tasks)
|
|
|
|
(next1-k (mk-got-k success-k fail-k)
|
|
|
|
(next1-k (mk-got-k success-k fail-k)
|
|
|
|
fail-k max-depth tasks))
|
|
|
|
fail-k max-depth tasks))
|
|
|
|
success-k fail-k max-depth tasks))))]
|
|
|
|
success-k fail-k max-depth tasks)))
|
|
|
|
[mk-got2-k
|
|
|
|
|
|
|
|
(lambda (success-k fail-k next1-k)
|
|
|
|
(define ((mk-got2-k success-k fail-k next1-k) val stream last-consumed-token depth max-depth tasks next-k)
|
|
|
|
(lambda (val stream last-consumed-token depth max-depth tasks next-k)
|
|
|
|
|
|
|
|
(success-k val stream last-consumed-token depth max-depth tasks
|
|
|
|
(success-k val stream last-consumed-token depth max-depth tasks
|
|
|
|
(lambda (success-k fail-k max-depth tasks)
|
|
|
|
(λ (success-k fail-k max-depth tasks)
|
|
|
|
(next-k (mk-got2-k success-k fail-k next1-k)
|
|
|
|
(next-k (mk-got2-k success-k fail-k next1-k)
|
|
|
|
(mk-fail2-k success-k fail-k next1-k)
|
|
|
|
(mk-fail2-k success-k fail-k next1-k)
|
|
|
|
max-depth tasks)))))]
|
|
|
|
max-depth tasks))))
|
|
|
|
[mk-fail2-k
|
|
|
|
|
|
|
|
(lambda (success-k fail-k next1-k)
|
|
|
|
(define ((mk-fail2-k success-k fail-k next1-k) max-depth tasks)
|
|
|
|
(lambda (max-depth tasks)
|
|
|
|
(next1-k (mk-got-k success-k fail-k) fail-k max-depth tasks))
|
|
|
|
(next1-k (mk-got-k success-k fail-k)
|
|
|
|
|
|
|
|
fail-k
|
|
|
|
|
|
|
|
max-depth
|
|
|
|
|
|
|
|
tasks)))])
|
|
|
|
|
|
|
|
(parse-a stream last-consumed-token depth end
|
|
|
|
(parse-a stream last-consumed-token depth end
|
|
|
|
(mk-got-k success-k fail-k)
|
|
|
|
(mk-got-k success-k fail-k)
|
|
|
|
fail-k
|
|
|
|
fail-k
|
|
|
|
max-depth tasks)))
|
|
|
|
max-depth tasks))
|
|
|
|
|
|
|
|
|
|
|
|
;; Parallel or for non-terminal alternatives
|
|
|
|
;; Parallel or for non-terminal alternatives
|
|
|
|
(define (parse-parallel-or parse-a parse-b stream last-consumed-token depth end success-k fail-k max-depth tasks)
|
|
|
|
(define (parse-parallel-or parse-a parse-b stream last-consumed-token depth end success-k fail-k max-depth tasks)
|
|
|
|
(parallel-or (lambda (success-k fail-k max-depth tasks)
|
|
|
|
(parallel-or (λ (success-k fail-k max-depth tasks)
|
|
|
|
(parse-a stream last-consumed-token depth end success-k fail-k max-depth tasks))
|
|
|
|
(parse-a stream last-consumed-token depth end success-k fail-k max-depth tasks))
|
|
|
|
(lambda (success-k fail-k max-depth tasks)
|
|
|
|
(λ (success-k fail-k max-depth tasks)
|
|
|
|
(parse-b stream last-consumed-token depth end success-k fail-k max-depth tasks))
|
|
|
|
(parse-b stream last-consumed-token depth end success-k fail-k max-depth tasks))
|
|
|
|
success-k fail-k max-depth tasks))
|
|
|
|
success-k fail-k max-depth tasks))
|
|
|
|
|
|
|
|
|
|
|
|
;; Generic parallel-or
|
|
|
|
;; Generic parallel-or
|
|
|
|
(define (parallel-or parse-a parse-b success-k fail-k max-depth tasks)
|
|
|
|
(define (parallel-or parse-a parse-b success-k fail-k max-depth tasks)
|
|
|
|
(define answer-key (gensym))
|
|
|
|
(define answer-key (gensym))
|
|
|
|
(letrec ([gota-k
|
|
|
|
(define (gota-k val stream last-consumed-token depth max-depth tasks next-k)
|
|
|
|
(lambda (val stream last-consumed-token depth max-depth tasks next-k)
|
|
|
|
|
|
|
|
(report-answer answer-key
|
|
|
|
(report-answer answer-key
|
|
|
|
max-depth
|
|
|
|
max-depth
|
|
|
|
tasks
|
|
|
|
tasks
|
|
|
|
(list val stream last-consumed-token depth next-k)))]
|
|
|
|
(list val stream last-consumed-token depth next-k)))
|
|
|
|
[faila-k
|
|
|
|
(define (faila-k max-depth tasks)
|
|
|
|
(lambda (max-depth tasks)
|
|
|
|
|
|
|
|
(report-answer answer-key
|
|
|
|
(report-answer answer-key
|
|
|
|
max-depth
|
|
|
|
max-depth
|
|
|
|
tasks
|
|
|
|
tasks
|
|
|
|
null))])
|
|
|
|
null))
|
|
|
|
(let* ([tasks (queue-task
|
|
|
|
(let* ([tasks (queue-task tasks (λ (max-depth tasks)
|
|
|
|
tasks
|
|
|
|
(parse-a gota-k faila-k max-depth tasks)))]
|
|
|
|
(lambda (max-depth tasks)
|
|
|
|
[tasks (queue-task tasks (λ (max-depth tasks)
|
|
|
|
(parse-a gota-k
|
|
|
|
(parse-b gota-k faila-k max-depth tasks)))]
|
|
|
|
faila-k
|
|
|
|
[queue-next (λ (next-k tasks)
|
|
|
|
max-depth tasks)))]
|
|
|
|
(queue-task tasks (λ (max-depth tasks)
|
|
|
|
[tasks (queue-task
|
|
|
|
(next-k gota-k faila-k max-depth tasks))))])
|
|
|
|
tasks
|
|
|
|
(define ((mk-got-one immediate-next? get-nth success-k) val stream last-consumed-token depth max-depth tasks next-k)
|
|
|
|
(lambda (max-depth tasks)
|
|
|
|
|
|
|
|
(parse-b gota-k
|
|
|
|
|
|
|
|
faila-k
|
|
|
|
|
|
|
|
max-depth tasks)))]
|
|
|
|
|
|
|
|
[queue-next (lambda (next-k tasks)
|
|
|
|
|
|
|
|
(queue-task tasks
|
|
|
|
|
|
|
|
(lambda (max-depth tasks)
|
|
|
|
|
|
|
|
(next-k gota-k
|
|
|
|
|
|
|
|
faila-k
|
|
|
|
|
|
|
|
max-depth tasks))))])
|
|
|
|
|
|
|
|
(letrec ([mk-got-one
|
|
|
|
|
|
|
|
(lambda (immediate-next? get-nth success-k)
|
|
|
|
|
|
|
|
(lambda (val stream last-consumed-token depth max-depth tasks next-k)
|
|
|
|
|
|
|
|
(let ([tasks (if immediate-next?
|
|
|
|
(let ([tasks (if immediate-next?
|
|
|
|
(queue-next next-k tasks)
|
|
|
|
(queue-next next-k tasks)
|
|
|
|
tasks)])
|
|
|
|
tasks)])
|
|
|
|
(success-k val stream last-consumed-token depth max-depth
|
|
|
|
(success-k val stream last-consumed-token depth max-depth
|
|
|
|
tasks
|
|
|
|
tasks
|
|
|
|
(lambda (success-k fail-k max-depth tasks)
|
|
|
|
(λ (success-k fail-k max-depth tasks)
|
|
|
|
(let ([tasks (if immediate-next?
|
|
|
|
(let ([tasks (if immediate-next?
|
|
|
|
tasks
|
|
|
|
tasks
|
|
|
|
(queue-next next-k tasks))])
|
|
|
|
(queue-next next-k tasks))])
|
|
|
|
(get-nth max-depth tasks success-k fail-k)))))))]
|
|
|
|
(get-nth max-depth tasks success-k fail-k))))))
|
|
|
|
[get-first
|
|
|
|
(define (get-first max-depth tasks success-k fail-k)
|
|
|
|
(lambda (max-depth tasks success-k fail-k)
|
|
|
|
|
|
|
|
(wait-for-answer #f max-depth tasks answer-key
|
|
|
|
(wait-for-answer #f max-depth tasks answer-key
|
|
|
|
(mk-got-one #t get-first success-k)
|
|
|
|
(mk-got-one #t get-first success-k)
|
|
|
|
(lambda (max-depth tasks)
|
|
|
|
(λ (max-depth tasks)
|
|
|
|
(get-second max-depth tasks success-k fail-k))
|
|
|
|
(get-second max-depth tasks success-k fail-k))
|
|
|
|
#f))]
|
|
|
|
#f))
|
|
|
|
[get-second
|
|
|
|
(define (get-second max-depth tasks success-k fail-k)
|
|
|
|
(lambda (max-depth tasks success-k fail-k)
|
|
|
|
|
|
|
|
(wait-for-answer #f max-depth tasks answer-key
|
|
|
|
(wait-for-answer #f max-depth tasks answer-key
|
|
|
|
(mk-got-one #f get-second success-k)
|
|
|
|
(mk-got-one #f get-second success-k)
|
|
|
|
fail-k #f))])
|
|
|
|
fail-k #f))
|
|
|
|
(get-first max-depth tasks success-k fail-k)))))
|
|
|
|
(get-first max-depth tasks success-k fail-k)))
|
|
|
|
|
|
|
|
|
|
|
|
;; Non-terminal alternatives where the first is "simple" can be done
|
|
|
|
;; Non-terminal alternatives where the first is "simple" can be done
|
|
|
|
;; sequentially, which is simpler
|
|
|
|
;; sequentially, which is simpler
|
|
|
|
(define (parse-or parse-a parse-b
|
|
|
|
(define (parse-or parse-a parse-b
|
|
|
|
stream last-consumed-token depth end success-k fail-k max-depth tasks)
|
|
|
|
stream last-consumed-token depth end success-k fail-k max-depth tasks)
|
|
|
|
(letrec ([mk-got-k
|
|
|
|
(define ((mk-got-k success-k fail-k) val stream last-consumed-token depth max-depth tasks next-k)
|
|
|
|
(lambda (success-k fail-k)
|
|
|
|
|
|
|
|
(lambda (val stream last-consumed-token depth max-depth tasks next-k)
|
|
|
|
|
|
|
|
(success-k val stream last-consumed-token depth
|
|
|
|
(success-k val stream last-consumed-token depth
|
|
|
|
max-depth tasks
|
|
|
|
max-depth tasks
|
|
|
|
(lambda (success-k fail-k max-depth tasks)
|
|
|
|
(λ (success-k fail-k max-depth tasks)
|
|
|
|
(next-k (mk-got-k success-k fail-k)
|
|
|
|
(next-k (mk-got-k success-k fail-k)
|
|
|
|
(mk-fail-k success-k fail-k)
|
|
|
|
(mk-fail-k success-k fail-k)
|
|
|
|
max-depth tasks)))))]
|
|
|
|
max-depth tasks))))
|
|
|
|
[mk-fail-k
|
|
|
|
(define ((mk-fail-k success-k fail-k) max-depth tasks)
|
|
|
|
(lambda (success-k fail-k)
|
|
|
|
(parse-b stream last-consumed-token depth end success-k fail-k max-depth tasks))
|
|
|
|
(lambda (max-depth tasks)
|
|
|
|
|
|
|
|
(parse-b stream last-consumed-token depth end success-k fail-k max-depth tasks)))])
|
|
|
|
|
|
|
|
(parse-a stream last-consumed-token depth end
|
|
|
|
(parse-a stream last-consumed-token depth end
|
|
|
|
(mk-got-k success-k fail-k)
|
|
|
|
(mk-got-k success-k fail-k)
|
|
|
|
(mk-fail-k success-k fail-k)
|
|
|
|
(mk-fail-k success-k fail-k)
|
|
|
|
max-depth tasks)))
|
|
|
|
max-depth tasks))
|
|
|
|
|
|
|
|
|
|
|
|
;; Starts a thread
|
|
|
|
;; Starts a thread
|
|
|
|
(define queue-task
|
|
|
|
(define (queue-task tasks t [progress? #t])
|
|
|
|
(lambda (tasks t [progress? #t])
|
|
|
|
|
|
|
|
(make-tasks (tasks-active tasks)
|
|
|
|
(make-tasks (tasks-active tasks)
|
|
|
|
(cons t (tasks-active-back tasks))
|
|
|
|
(cons t (tasks-active-back tasks))
|
|
|
|
(tasks-waits tasks)
|
|
|
|
(tasks-waits tasks)
|
|
|
|
(tasks-multi-waits tasks)
|
|
|
|
(tasks-multi-waits tasks)
|
|
|
|
(tasks-cache tasks)
|
|
|
|
(tasks-cache tasks)
|
|
|
|
(or progress? (tasks-progress? tasks)))))
|
|
|
|
(or progress? (tasks-progress? tasks))))
|
|
|
|
|
|
|
|
|
|
|
|
;; Reports an answer to a waiting thread:
|
|
|
|
;; Reports an answer to a waiting thread:
|
|
|
|
(define (report-answer answer-key max-depth tasks val)
|
|
|
|
(define (report-answer answer-key max-depth tasks val)
|
|
|
|
(let ([v (hash-ref (tasks-waits tasks) answer-key (lambda () #f))])
|
|
|
|
(define v (hash-ref (tasks-waits tasks) answer-key (λ () #f)))
|
|
|
|
(if v
|
|
|
|
(if v
|
|
|
|
(let ([tasks (make-tasks (cons (v val)
|
|
|
|
(let ([tasks (make-tasks (cons (v val) (tasks-active tasks))
|
|
|
|
(tasks-active tasks))
|
|
|
|
|
|
|
|
(tasks-active-back tasks)
|
|
|
|
(tasks-active-back tasks)
|
|
|
|
(tasks-waits tasks)
|
|
|
|
(tasks-waits tasks)
|
|
|
|
(tasks-multi-waits tasks)
|
|
|
|
(tasks-multi-waits tasks)
|
|
|
@ -241,29 +210,29 @@
|
|
|
|
;; We have an answer ready too fast; wait
|
|
|
|
;; We have an answer ready too fast; wait
|
|
|
|
(swap-task max-depth
|
|
|
|
(swap-task max-depth
|
|
|
|
(queue-task tasks
|
|
|
|
(queue-task tasks
|
|
|
|
(lambda (max-depth tasks)
|
|
|
|
(λ (max-depth tasks)
|
|
|
|
(report-answer answer-key max-depth tasks val))
|
|
|
|
(report-answer answer-key max-depth tasks val))
|
|
|
|
#f)))))
|
|
|
|
#f))))
|
|
|
|
|
|
|
|
|
|
|
|
;; Reports an answer to multiple waiting threads:
|
|
|
|
;; Reports an answer to multiple waiting threads:
|
|
|
|
(define (report-answer-all answer-key max-depth tasks val k)
|
|
|
|
(define (report-answer-all answer-key max-depth tasks val k)
|
|
|
|
(let ([v (hash-ref (tasks-multi-waits tasks) answer-key (lambda () null))])
|
|
|
|
(define v (hash-ref (tasks-multi-waits tasks) answer-key (λ () null)))
|
|
|
|
(hash-remove! (tasks-multi-waits tasks) answer-key)
|
|
|
|
(hash-remove! (tasks-multi-waits tasks) answer-key)
|
|
|
|
(let ([tasks (make-tasks (append (map (lambda (a) (a val)) v)
|
|
|
|
(let ([tasks (make-tasks (append (map (λ (a) (a val)) v)
|
|
|
|
(tasks-active tasks))
|
|
|
|
(tasks-active tasks))
|
|
|
|
(tasks-active-back tasks)
|
|
|
|
(tasks-active-back tasks)
|
|
|
|
(tasks-waits tasks)
|
|
|
|
(tasks-waits tasks)
|
|
|
|
(tasks-multi-waits tasks)
|
|
|
|
(tasks-multi-waits tasks)
|
|
|
|
(tasks-cache tasks)
|
|
|
|
(tasks-cache tasks)
|
|
|
|
#t)])
|
|
|
|
#t)])
|
|
|
|
(k max-depth tasks))))
|
|
|
|
(k max-depth tasks)))
|
|
|
|
|
|
|
|
|
|
|
|
;; Waits for an answer; if `multi?' is #f, this is sole waiter, otherwise
|
|
|
|
;; Waits for an answer; if `multi?' is #f, this is sole waiter, otherwise
|
|
|
|
;; there might be many. Use wither #t or #f (and `report-answer' or
|
|
|
|
;; there might be many. Use wither #t or #f (and `report-answer' or
|
|
|
|
;; `report-answer-all', resptively) consistently for a particular answer key.
|
|
|
|
;; `report-answer-all', resptively) consistently for a particular answer key.
|
|
|
|
(define (wait-for-answer multi? max-depth tasks answer-key success-k fail-k deadlock-k)
|
|
|
|
(define (wait-for-answer multi? max-depth tasks answer-key success-k fail-k deadlock-k)
|
|
|
|
(let ([wait (lambda (val)
|
|
|
|
(let ([wait (λ (val)
|
|
|
|
(lambda (max-depth tasks)
|
|
|
|
(λ (max-depth tasks)
|
|
|
|
(if val
|
|
|
|
(if val
|
|
|
|
(if (null? val)
|
|
|
|
(if (null? val)
|
|
|
|
(fail-k max-depth tasks)
|
|
|
|
(fail-k max-depth tasks)
|
|
|
@ -273,7 +242,7 @@
|
|
|
|
(if multi?
|
|
|
|
(if multi?
|
|
|
|
(hash-set! (tasks-multi-waits tasks) answer-key
|
|
|
|
(hash-set! (tasks-multi-waits tasks) answer-key
|
|
|
|
(cons wait (hash-ref (tasks-multi-waits tasks) answer-key
|
|
|
|
(cons wait (hash-ref (tasks-multi-waits tasks) answer-key
|
|
|
|
(lambda () null))))
|
|
|
|
(λ () null))))
|
|
|
|
(hash-set! (tasks-waits tasks) answer-key wait))
|
|
|
|
(hash-set! (tasks-waits tasks) answer-key wait))
|
|
|
|
(let ([tasks (make-tasks (tasks-active tasks)
|
|
|
|
(let ([tasks (make-tasks (tasks-active tasks)
|
|
|
|
(tasks-active-back tasks)
|
|
|
|
(tasks-active-back tasks)
|
|
|
@ -302,8 +271,8 @@
|
|
|
|
(make-tasks (apply
|
|
|
|
(make-tasks (apply
|
|
|
|
append
|
|
|
|
append
|
|
|
|
(hash-map (tasks-multi-waits tasks)
|
|
|
|
(hash-map (tasks-multi-waits tasks)
|
|
|
|
(lambda (k l)
|
|
|
|
(λ (k l)
|
|
|
|
(map (lambda (v) (v #f)) l))))
|
|
|
|
(map (λ (v) (v #f)) l))))
|
|
|
|
(tasks-active-back tasks)
|
|
|
|
(tasks-active-back tasks)
|
|
|
|
(tasks-waits tasks)
|
|
|
|
(tasks-waits tasks)
|
|
|
|
(make-hasheq)
|
|
|
|
(make-hasheq)
|
|
|
@ -325,11 +294,9 @@
|
|
|
|
(define no-pos-val (make-position #f #f #f))
|
|
|
|
(define no-pos-val (make-position #f #f #f))
|
|
|
|
(define-for-syntax no-pos
|
|
|
|
(define-for-syntax no-pos
|
|
|
|
(let ([npv ((syntax-local-certifier) #'no-pos-val)])
|
|
|
|
(let ([npv ((syntax-local-certifier) #'no-pos-val)])
|
|
|
|
(lambda (stx) npv)))
|
|
|
|
(λ (stx) npv)))
|
|
|
|
(define-for-syntax at-tok-pos
|
|
|
|
(define-for-syntax ((at-tok-pos sel expr) stx)
|
|
|
|
(lambda (sel expr)
|
|
|
|
#`(let ([v #,expr]) (if v (#,sel v) no-pos-val)))
|
|
|
|
(lambda (stx)
|
|
|
|
|
|
|
|
#`(let ([v #,expr]) (if v (#,sel v) no-pos-val)))))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;; Builds a matcher for a particular alternative
|
|
|
|
;; Builds a matcher for a particular alternative
|
|
|
|
(define-for-syntax (build-match nts toks pat handle $ctx)
|
|
|
|
(define-for-syntax (build-match nts toks pat handle $ctx)
|
|
|
@ -337,27 +304,23 @@
|
|
|
|
[pos 1])
|
|
|
|
[pos 1])
|
|
|
|
(if (null? pat)
|
|
|
|
(if (null? pat)
|
|
|
|
#`(success-k #,handle stream last-consumed-token depth max-depth tasks
|
|
|
|
#`(success-k #,handle stream last-consumed-token depth max-depth tasks
|
|
|
|
(lambda (success-k fail-k max-depth tasks)
|
|
|
|
(λ (success-k fail-k max-depth tasks)
|
|
|
|
(fail-k max-depth tasks)))
|
|
|
|
(fail-k max-depth tasks)))
|
|
|
|
(let ([id (datum->syntax (car pat)
|
|
|
|
(let ([id (datum->syntax (car pat) (string->symbol (format "$~a" pos)))]
|
|
|
|
(string->symbol (format "$~a" pos)))]
|
|
|
|
[id-start-pos (datum->syntax (car pat) (string->symbol (format "$~a-start-pos" pos)))]
|
|
|
|
[id-start-pos (datum->syntax (car pat)
|
|
|
|
[id-end-pos (datum->syntax (car pat) (string->symbol (format "$~a-end-pos" pos)))]
|
|
|
|
(string->symbol (format "$~a-start-pos" pos)))]
|
|
|
|
[n-end-pos (and (null? (cdr pat)) (datum->syntax (car pat) '$n-end-pos))])
|
|
|
|
[id-end-pos (datum->syntax (car pat)
|
|
|
|
|
|
|
|
(string->symbol (format "$~a-end-pos" pos)))]
|
|
|
|
|
|
|
|
[n-end-pos (and (null? (cdr pat))
|
|
|
|
|
|
|
|
(datum->syntax (car pat) '$n-end-pos))])
|
|
|
|
|
|
|
|
(cond
|
|
|
|
(cond
|
|
|
|
[(bound-identifier-mapping-get nts (car pat) (lambda () #f))
|
|
|
|
[(bound-identifier-mapping-get nts (car pat) (λ () #f))
|
|
|
|
;; Match non-termimal
|
|
|
|
;; Match non-termimal
|
|
|
|
#`(parse-and
|
|
|
|
#`(parse-and
|
|
|
|
;; First part is simple? (If so, we don't have to parallelize the `and'.)
|
|
|
|
;; First part is simple? (If so, we don't have to parallelize the `and'.)
|
|
|
|
#,(let ([l (bound-identifier-mapping-get nts (car pat) (lambda () #f))])
|
|
|
|
#,(let ([l (bound-identifier-mapping-get nts (car pat) (λ () #f))])
|
|
|
|
(or (not l)
|
|
|
|
(or (not l)
|
|
|
|
(andmap values (caddr l))))
|
|
|
|
(andmap values (caddr l))))
|
|
|
|
#,(car pat)
|
|
|
|
#,(car pat)
|
|
|
|
(let ([original-stream stream])
|
|
|
|
(let ([original-stream stream])
|
|
|
|
(lambda (#,id stream last-consumed-token depth end success-k fail-k max-depth tasks)
|
|
|
|
(λ (#,id stream last-consumed-token depth end success-k fail-k max-depth tasks)
|
|
|
|
(let-syntax ([#,id-start-pos (at-tok-pos #'(if (eq? original-stream stream)
|
|
|
|
(let-syntax ([#,id-start-pos (at-tok-pos #'(if (eq? original-stream stream)
|
|
|
|
tok-end
|
|
|
|
tok-end
|
|
|
|
tok-start)
|
|
|
|
tok-start)
|
|
|
@ -372,10 +335,10 @@
|
|
|
|
#,(loop (cdr pat) (add1 pos)))))
|
|
|
|
#,(loop (cdr pat) (add1 pos)))))
|
|
|
|
stream last-consumed-token depth
|
|
|
|
stream last-consumed-token depth
|
|
|
|
#,(let ([cnt (apply +
|
|
|
|
#,(let ([cnt (apply +
|
|
|
|
(map (lambda (item)
|
|
|
|
(map (λ (item)
|
|
|
|
(cond
|
|
|
|
(cond
|
|
|
|
[(bound-identifier-mapping-get nts item (lambda () #f))
|
|
|
|
[(bound-identifier-mapping-get nts item (λ () #f))
|
|
|
|
=> (lambda (l) (car l))]
|
|
|
|
=> (λ (l) (car l))]
|
|
|
|
[else 1]))
|
|
|
|
[else 1]))
|
|
|
|
(cdr pat)))])
|
|
|
|
(cdr pat)))])
|
|
|
|
#`(- end #,cnt))
|
|
|
|
#`(- end #,cnt))
|
|
|
@ -419,37 +382,36 @@
|
|
|
|
[max-depth max-depth]
|
|
|
|
[max-depth max-depth]
|
|
|
|
[tasks tasks]
|
|
|
|
[tasks tasks]
|
|
|
|
[k k])
|
|
|
|
[k k])
|
|
|
|
(let ([answer-key (gensym)]
|
|
|
|
(define answer-key (gensym))
|
|
|
|
[table-key (vector key depth n)]
|
|
|
|
(define table-key (vector key depth n))
|
|
|
|
[old-depth depth]
|
|
|
|
(define old-depth depth)
|
|
|
|
[old-stream stream])
|
|
|
|
(define old-stream stream)
|
|
|
|
#;(printf "Loop ~a\n" table-key)
|
|
|
|
#;(printf "Loop ~a\n" table-key)
|
|
|
|
(cond
|
|
|
|
(cond
|
|
|
|
[(hash-ref (tasks-cache tasks) table-key (lambda () #f))
|
|
|
|
[(hash-ref (tasks-cache tasks) table-key (λ () #f))
|
|
|
|
=> (lambda (result)
|
|
|
|
=> (λ (result)
|
|
|
|
#;(printf "Reuse ~a\n" table-key)
|
|
|
|
#;(printf "Reuse ~a\n" table-key)
|
|
|
|
(result success-k fail-k max-depth tasks))]
|
|
|
|
(result success-k fail-k max-depth tasks))]
|
|
|
|
[else
|
|
|
|
[else
|
|
|
|
#;(printf "Try ~a ~a\n" table-key (map tok-name stream))
|
|
|
|
#;(printf "Try ~a ~a\n" table-key (map tok-name stream))
|
|
|
|
(hash-set! (tasks-cache tasks) table-key
|
|
|
|
(hash-set! (tasks-cache tasks) table-key
|
|
|
|
(lambda (success-k fail-k max-depth tasks)
|
|
|
|
(λ (success-k fail-k max-depth tasks)
|
|
|
|
#;(printf "Wait ~a ~a\n" table-key answer-key)
|
|
|
|
#;(printf "Wait ~a ~a\n" table-key answer-key)
|
|
|
|
(wait-for-answer #t max-depth tasks answer-key success-k fail-k
|
|
|
|
(wait-for-answer #t max-depth tasks answer-key success-k fail-k
|
|
|
|
(lambda (max-depth tasks)
|
|
|
|
(λ (max-depth tasks)
|
|
|
|
#;(printf "Deadlock ~a ~a\n" table-key answer-key)
|
|
|
|
#;(printf "Deadlock ~a ~a\n" table-key answer-key)
|
|
|
|
(fail-k max-depth tasks)))))
|
|
|
|
(fail-k max-depth tasks)))))
|
|
|
|
(let result-loop ([max-depth max-depth][tasks tasks][k k])
|
|
|
|
(let result-loop ([max-depth max-depth][tasks tasks][k k])
|
|
|
|
(letrec ([orig-stream stream]
|
|
|
|
(define orig-stream stream)
|
|
|
|
[new-got-k
|
|
|
|
(define (new-got-k val stream last-consumed-token depth max-depth tasks next-k)
|
|
|
|
(lambda (val stream last-consumed-token depth max-depth tasks next-k)
|
|
|
|
|
|
|
|
;; Check whether we already have a result that consumed the same amount:
|
|
|
|
;; Check whether we already have a result that consumed the same amount:
|
|
|
|
(let ([result-key (vector #f key old-depth depth)])
|
|
|
|
(define result-key (vector #f key old-depth depth))
|
|
|
|
(cond
|
|
|
|
(cond
|
|
|
|
[(hash-ref (tasks-cache tasks) result-key (lambda () #f))
|
|
|
|
[(hash-ref (tasks-cache tasks) result-key (λ () #f))
|
|
|
|
;; Go for the next-result
|
|
|
|
;; Go for the next-result
|
|
|
|
(result-loop max-depth
|
|
|
|
(result-loop max-depth
|
|
|
|
tasks
|
|
|
|
tasks
|
|
|
|
(lambda (end max-depth tasks success-k fail-k)
|
|
|
|
(λ (end max-depth tasks success-k fail-k)
|
|
|
|
(next-k success-k fail-k max-depth tasks)))]
|
|
|
|
(next-k success-k fail-k max-depth tasks)))]
|
|
|
|
[else
|
|
|
|
[else
|
|
|
|
#;(printf "Success ~a ~a\n" table-key
|
|
|
|
#;(printf "Success ~a ~a\n" table-key
|
|
|
@ -457,37 +419,36 @@
|
|
|
|
(if (= d depth)
|
|
|
|
(if (= d depth)
|
|
|
|
null
|
|
|
|
null
|
|
|
|
(cons (car s) (loop (add1 d) (cdr s)))))))
|
|
|
|
(cons (car s) (loop (add1 d) (cdr s)))))))
|
|
|
|
(let ([next-k (lambda (success-k fail-k max-depth tasks)
|
|
|
|
(let ([next-k (λ (success-k fail-k max-depth tasks)
|
|
|
|
(loop (add1 n)
|
|
|
|
(loop (add1 n)
|
|
|
|
success-k
|
|
|
|
success-k
|
|
|
|
fail-k
|
|
|
|
fail-k
|
|
|
|
max-depth
|
|
|
|
max-depth
|
|
|
|
tasks
|
|
|
|
tasks
|
|
|
|
(lambda (end max-depth tasks success-k fail-k)
|
|
|
|
(λ (end max-depth tasks success-k fail-k)
|
|
|
|
(next-k success-k fail-k max-depth tasks))))])
|
|
|
|
(next-k success-k fail-k max-depth tasks))))])
|
|
|
|
(hash-set! (tasks-cache tasks) result-key #t)
|
|
|
|
(hash-set! (tasks-cache tasks) result-key #t)
|
|
|
|
(hash-set! (tasks-cache tasks) table-key
|
|
|
|
(hash-set! (tasks-cache tasks) table-key
|
|
|
|
(lambda (success-k fail-k max-depth tasks)
|
|
|
|
(λ (success-k fail-k max-depth tasks)
|
|
|
|
(success-k val stream last-consumed-token depth max-depth tasks next-k)))
|
|
|
|
(success-k val stream last-consumed-token depth max-depth tasks next-k)))
|
|
|
|
(report-answer-all answer-key
|
|
|
|
(report-answer-all answer-key
|
|
|
|
max-depth
|
|
|
|
max-depth
|
|
|
|
tasks
|
|
|
|
tasks
|
|
|
|
(list val stream last-consumed-token depth next-k)
|
|
|
|
(list val stream last-consumed-token depth next-k)
|
|
|
|
(lambda (max-depth tasks)
|
|
|
|
(λ (max-depth tasks)
|
|
|
|
(success-k val stream last-consumed-token depth max-depth tasks next-k))))])))]
|
|
|
|
(success-k val stream last-consumed-token depth max-depth tasks next-k))))]))
|
|
|
|
[new-fail-k
|
|
|
|
(define (new-fail-k max-depth tasks)
|
|
|
|
(lambda (max-depth tasks)
|
|
|
|
|
|
|
|
#;(printf "Failure ~a\n" table-key)
|
|
|
|
#;(printf "Failure ~a\n" table-key)
|
|
|
|
(hash-set! (tasks-cache tasks) table-key
|
|
|
|
(hash-set! (tasks-cache tasks) table-key
|
|
|
|
(lambda (success-k fail-k max-depth tasks)
|
|
|
|
(λ (success-k fail-k max-depth tasks)
|
|
|
|
(fail-k max-depth tasks)))
|
|
|
|
(fail-k max-depth tasks)))
|
|
|
|
(report-answer-all answer-key
|
|
|
|
(report-answer-all answer-key
|
|
|
|
max-depth
|
|
|
|
max-depth
|
|
|
|
tasks
|
|
|
|
tasks
|
|
|
|
null
|
|
|
|
null
|
|
|
|
(lambda (max-depth tasks)
|
|
|
|
(λ (max-depth tasks)
|
|
|
|
(fail-k max-depth tasks))))])
|
|
|
|
(fail-k max-depth tasks))))
|
|
|
|
(k end max-depth tasks new-got-k new-fail-k)))])))))
|
|
|
|
(k end max-depth tasks new-got-k new-fail-k))]))))
|
|
|
|
|
|
|
|
|
|
|
|
;; These temp identifiers can't be `gensym` or `generate-temporary`
|
|
|
|
;; These temp identifiers can't be `gensym` or `generate-temporary`
|
|
|
|
;; because they have to be consistent between module loads
|
|
|
|
;; because they have to be consistent between module loads
|
|
|
@ -497,39 +458,34 @@
|
|
|
|
(define-for-syntax atok-id-temp 'atok_wrutdjgecmybyfipiwsgjlvsveryodlgassuzcargiuznzgdghrykfqfbwcjgzdhdoeqxcucmtjkuyucskzethozhqkasphdwbht)
|
|
|
|
(define-for-syntax atok-id-temp 'atok_wrutdjgecmybyfipiwsgjlvsveryodlgassuzcargiuznzgdghrykfqfbwcjgzdhdoeqxcucmtjkuyucskzethozhqkasphdwbht)
|
|
|
|
(define-syntax (cfg-parser stx)
|
|
|
|
(define-syntax (cfg-parser stx)
|
|
|
|
(syntax-case stx ()
|
|
|
|
(syntax-case stx ()
|
|
|
|
[(_ clause ...)
|
|
|
|
[(_ CLAUSE ...)
|
|
|
|
(let ([clauses (syntax->list #'(clause ...))])
|
|
|
|
(let ([clauses (syntax->list #'(CLAUSE ...))])
|
|
|
|
(let-values ([(start grammar cfg-error parser-clauses src-pos?)
|
|
|
|
(let-values ([(start grammar cfg-error parser-clauses src-pos?)
|
|
|
|
(let ([all-toks (apply
|
|
|
|
(let ([all-toks (apply
|
|
|
|
append
|
|
|
|
append
|
|
|
|
(map (lambda (clause)
|
|
|
|
(for/list ([clause (in-list clauses)])
|
|
|
|
(syntax-case clause (tokens)
|
|
|
|
(syntax-case clause (tokens)
|
|
|
|
[(tokens t ...)
|
|
|
|
[(tokens T ...)
|
|
|
|
(apply
|
|
|
|
(apply
|
|
|
|
append
|
|
|
|
append
|
|
|
|
(map (lambda (t)
|
|
|
|
(for/list ([t (in-list (syntax->list #'(T ...)))])
|
|
|
|
(let ([v (syntax-local-value t (lambda () #f))])
|
|
|
|
(define v (syntax-local-value t (λ () #f)))
|
|
|
|
(cond
|
|
|
|
(cond
|
|
|
|
[(terminals-def? v)
|
|
|
|
[(terminals-def? v)
|
|
|
|
(map (lambda (v)
|
|
|
|
(for/list ([v (in-list (syntax->list (terminals-def-t v)))])
|
|
|
|
(cons v #f))
|
|
|
|
(cons v #f))]
|
|
|
|
(syntax->list (terminals-def-t v)))]
|
|
|
|
|
|
|
|
[(e-terminals-def? v)
|
|
|
|
[(e-terminals-def? v)
|
|
|
|
(map (lambda (v)
|
|
|
|
(for/list ([v (in-list (syntax->list (e-terminals-def-t v)))])
|
|
|
|
(cons v #t))
|
|
|
|
(cons v #t))]
|
|
|
|
(syntax->list (e-terminals-def-t v)))]
|
|
|
|
[else null])))]
|
|
|
|
[else null])))
|
|
|
|
[_else null])))]
|
|
|
|
(syntax->list #'(t ...))))]
|
|
|
|
|
|
|
|
[_else null]))
|
|
|
|
|
|
|
|
clauses))]
|
|
|
|
|
|
|
|
[all-end-toks (apply
|
|
|
|
[all-end-toks (apply
|
|
|
|
append
|
|
|
|
append
|
|
|
|
(map (lambda (clause)
|
|
|
|
(for/list ([clause (in-list clauses)])
|
|
|
|
(syntax-case clause (end)
|
|
|
|
(syntax-case clause (end)
|
|
|
|
[(end t ...)
|
|
|
|
[(end T ...)
|
|
|
|
(syntax->list #'(t ...))]
|
|
|
|
(syntax->list #'(T ...))]
|
|
|
|
[_else null]))
|
|
|
|
[_else null])))])
|
|
|
|
clauses))])
|
|
|
|
|
|
|
|
(let loop ([clauses clauses]
|
|
|
|
(let loop ([clauses clauses]
|
|
|
|
[cfg-start #f]
|
|
|
|
[cfg-start #f]
|
|
|
|
[cfg-grammar #f]
|
|
|
|
[cfg-grammar #f]
|
|
|
@ -543,47 +499,35 @@
|
|
|
|
(reverse parser-clauses)
|
|
|
|
(reverse parser-clauses)
|
|
|
|
src-pos?)
|
|
|
|
src-pos?)
|
|
|
|
(syntax-case (car clauses) (start error grammar src-pos)
|
|
|
|
(syntax-case (car clauses) (start error grammar src-pos)
|
|
|
|
[(start tok)
|
|
|
|
[(start TOK)
|
|
|
|
(loop (cdr clauses) #'tok cfg-grammar cfg-error src-pos? parser-clauses)]
|
|
|
|
(loop (cdr clauses) #'TOK cfg-grammar cfg-error src-pos? parser-clauses)]
|
|
|
|
[(error expr)
|
|
|
|
[(error EXPR)
|
|
|
|
(loop (cdr clauses) cfg-start cfg-grammar #'expr src-pos? parser-clauses)]
|
|
|
|
(loop (cdr clauses) cfg-start cfg-grammar #'EXPR src-pos? parser-clauses)]
|
|
|
|
[(grammar [nt [pat handle0 handle ...] ...] ...)
|
|
|
|
[(grammar [NT [PAT HANDLE0 HANDLE ...] ...] ...)
|
|
|
|
(let ([nts (make-bound-identifier-mapping)]
|
|
|
|
(let ([nts (make-bound-identifier-mapping)]
|
|
|
|
[toks (make-token-identifier-mapping)]
|
|
|
|
[toks (make-token-identifier-mapping)]
|
|
|
|
[end-toks (make-token-identifier-mapping)]
|
|
|
|
[end-toks (make-token-identifier-mapping)]
|
|
|
|
[nt-ids (syntax->list #'(nt ...))]
|
|
|
|
[nt-ids (syntax->list #'(NT ...))]
|
|
|
|
[patss (map (lambda (stx)
|
|
|
|
[patss (map (λ (stx)
|
|
|
|
(map syntax->list (syntax->list stx)))
|
|
|
|
(map syntax->list (syntax->list stx)))
|
|
|
|
(syntax->list #'((pat ...) ...)))])
|
|
|
|
(syntax->list #'((PAT ...) ...)))])
|
|
|
|
(for-each (lambda (nt)
|
|
|
|
(for ([nt (in-list nt-ids)])
|
|
|
|
(bound-identifier-mapping-put! nts nt (list 0)))
|
|
|
|
(bound-identifier-mapping-put! nts nt (list 0)))
|
|
|
|
nt-ids)
|
|
|
|
(for ([t (in-list all-end-toks)])
|
|
|
|
(for-each (lambda (t)
|
|
|
|
|
|
|
|
(token-identifier-mapping-put! end-toks t #t))
|
|
|
|
(token-identifier-mapping-put! end-toks t #t))
|
|
|
|
all-end-toks)
|
|
|
|
(for ([t (in-list all-toks)]
|
|
|
|
(for-each (lambda (t)
|
|
|
|
#:unless (token-identifier-mapping-get end-toks (car t) (λ () #f)))
|
|
|
|
(unless (token-identifier-mapping-get end-toks (car t) (lambda () #f))
|
|
|
|
(define id (gensym (syntax-e (car t))))
|
|
|
|
(let ([id (gensym (syntax-e (car t)))])
|
|
|
|
(token-identifier-mapping-put! toks (car t) (cons id (cdr t))))
|
|
|
|
(token-identifier-mapping-put! toks (car t)
|
|
|
|
|
|
|
|
(cons id (cdr t))))))
|
|
|
|
|
|
|
|
all-toks)
|
|
|
|
|
|
|
|
;; Compute min max size for each non-term:
|
|
|
|
;; Compute min max size for each non-term:
|
|
|
|
(nt-fixpoint
|
|
|
|
(nt-fixpoint
|
|
|
|
nts
|
|
|
|
nts
|
|
|
|
(lambda (nt pats old-list)
|
|
|
|
(λ (nt pats old-list)
|
|
|
|
(let ([new-cnt
|
|
|
|
(let ([new-cnt
|
|
|
|
(apply
|
|
|
|
(apply min (for/list ([pat (in-list pats)])
|
|
|
|
min
|
|
|
|
(for/sum ([elem (in-list pat)])
|
|
|
|
(map (lambda (pat)
|
|
|
|
(car (bound-identifier-mapping-get
|
|
|
|
(apply
|
|
|
|
nts elem (λ () (list 1)))))))])
|
|
|
|
+
|
|
|
|
|
|
|
|
(map (lambda (elem)
|
|
|
|
|
|
|
|
(car
|
|
|
|
|
|
|
|
(bound-identifier-mapping-get nts
|
|
|
|
|
|
|
|
elem
|
|
|
|
|
|
|
|
(lambda () (list 1)))))
|
|
|
|
|
|
|
|
pat)))
|
|
|
|
|
|
|
|
pats))])
|
|
|
|
|
|
|
|
(if (new-cnt . > . (car old-list))
|
|
|
|
(if (new-cnt . > . (car old-list))
|
|
|
|
(cons new-cnt (cdr old-list))
|
|
|
|
(cons new-cnt (cdr old-list))
|
|
|
|
old-list)))
|
|
|
|
old-list)))
|
|
|
@ -592,17 +536,17 @@
|
|
|
|
;; for a non-terminal
|
|
|
|
;; for a non-terminal
|
|
|
|
(nt-fixpoint
|
|
|
|
(nt-fixpoint
|
|
|
|
nts
|
|
|
|
nts
|
|
|
|
(lambda (nt pats old-list)
|
|
|
|
(λ (nt pats old-list)
|
|
|
|
(let ([new-list
|
|
|
|
(let ([new-list
|
|
|
|
(apply
|
|
|
|
(apply
|
|
|
|
append
|
|
|
|
append
|
|
|
|
(map (lambda (pat)
|
|
|
|
(for/list ([pat (in-list pats)])
|
|
|
|
(let loop ([pat pat])
|
|
|
|
(let loop ([pat pat])
|
|
|
|
(if (pair? pat)
|
|
|
|
(if (pair? pat)
|
|
|
|
(let ([l (bound-identifier-mapping-get
|
|
|
|
(let ([l (bound-identifier-mapping-get
|
|
|
|
nts
|
|
|
|
nts
|
|
|
|
(car pat)
|
|
|
|
(car pat)
|
|
|
|
(lambda ()
|
|
|
|
(λ ()
|
|
|
|
(list 1 (map-token toks (car pat)))))])
|
|
|
|
(list 1 (map-token toks (car pat)))))])
|
|
|
|
;; If the non-terminal can match 0 things,
|
|
|
|
;; If the non-terminal can match 0 things,
|
|
|
|
;; then it might match something from the
|
|
|
|
;; then it might match something from the
|
|
|
@ -611,10 +555,9 @@
|
|
|
|
(if (zero? (car l))
|
|
|
|
(if (zero? (car l))
|
|
|
|
(append (cdr l) (loop (cdr pat)))
|
|
|
|
(append (cdr l) (loop (cdr pat)))
|
|
|
|
(cdr l)))
|
|
|
|
(cdr l)))
|
|
|
|
null)))
|
|
|
|
null))))])
|
|
|
|
pats))])
|
|
|
|
(let ([new (filter (λ (id)
|
|
|
|
(let ([new (filter (lambda (id)
|
|
|
|
(andmap (λ (id2)
|
|
|
|
(andmap (lambda (id2)
|
|
|
|
|
|
|
|
(not (eq? id id2)))
|
|
|
|
(not (eq? id id2)))
|
|
|
|
(cdr old-list)))
|
|
|
|
(cdr old-list)))
|
|
|
|
new-list)])
|
|
|
|
new-list)])
|
|
|
@ -623,7 +566,7 @@
|
|
|
|
(let ([new (let loop ([new new])
|
|
|
|
(let ([new (let loop ([new new])
|
|
|
|
(if (null? (cdr new))
|
|
|
|
(if (null? (cdr new))
|
|
|
|
new
|
|
|
|
new
|
|
|
|
(if (ormap (lambda (id)
|
|
|
|
(if (ormap (λ (id)
|
|
|
|
(eq? (car new) id))
|
|
|
|
(eq? (car new) id))
|
|
|
|
(cdr new))
|
|
|
|
(cdr new))
|
|
|
|
(loop (cdr new))
|
|
|
|
(loop (cdr new))
|
|
|
@ -632,26 +575,26 @@
|
|
|
|
old-list))))
|
|
|
|
old-list))))
|
|
|
|
nt-ids patss)
|
|
|
|
nt-ids patss)
|
|
|
|
;; Determine left-recursive clauses:
|
|
|
|
;; Determine left-recursive clauses:
|
|
|
|
(for-each (lambda (nt pats)
|
|
|
|
(for-each (λ (nt pats)
|
|
|
|
(let ([l (bound-identifier-mapping-get nts nt)])
|
|
|
|
(let ([l (bound-identifier-mapping-get nts nt)])
|
|
|
|
(bound-identifier-mapping-put! nts nt (list (car l)
|
|
|
|
(bound-identifier-mapping-put! nts nt (list (car l)
|
|
|
|
(cdr l)
|
|
|
|
(cdr l)
|
|
|
|
(map (lambda (x) #f) pats)))))
|
|
|
|
(map (λ (x) #f) pats)))))
|
|
|
|
nt-ids patss)
|
|
|
|
nt-ids patss)
|
|
|
|
(nt-fixpoint
|
|
|
|
(nt-fixpoint
|
|
|
|
nts
|
|
|
|
nts
|
|
|
|
(lambda (nt pats old-list)
|
|
|
|
(λ (nt pats old-list)
|
|
|
|
(list (car old-list)
|
|
|
|
(list (car old-list)
|
|
|
|
(cadr old-list)
|
|
|
|
(cadr old-list)
|
|
|
|
(map (lambda (pat simple?)
|
|
|
|
(map (λ (pat simple?)
|
|
|
|
(or simple?
|
|
|
|
(or simple?
|
|
|
|
(let ([l (map (lambda (elem)
|
|
|
|
(let ([l (map (λ (elem)
|
|
|
|
(bound-identifier-mapping-get
|
|
|
|
(bound-identifier-mapping-get
|
|
|
|
nts
|
|
|
|
nts
|
|
|
|
elem
|
|
|
|
elem
|
|
|
|
(lambda () #f)))
|
|
|
|
(λ () #f)))
|
|
|
|
pat)])
|
|
|
|
pat)])
|
|
|
|
(andmap (lambda (i)
|
|
|
|
(andmap (λ (i)
|
|
|
|
(or (not i)
|
|
|
|
(or (not i)
|
|
|
|
(andmap values (caddr i))))
|
|
|
|
(andmap values (caddr i))))
|
|
|
|
l))))
|
|
|
|
l))))
|
|
|
@ -660,16 +603,16 @@
|
|
|
|
;; Build a definition for each non-term:
|
|
|
|
;; Build a definition for each non-term:
|
|
|
|
(loop (cdr clauses)
|
|
|
|
(loop (cdr clauses)
|
|
|
|
cfg-start
|
|
|
|
cfg-start
|
|
|
|
(map (lambda (nt pats handles $ctxs)
|
|
|
|
(map (λ (nt pats handles $ctxs)
|
|
|
|
(define info (bound-identifier-mapping-get nts nt))
|
|
|
|
(define info (bound-identifier-mapping-get nts nt))
|
|
|
|
(list nt
|
|
|
|
(list nt
|
|
|
|
#`(let ([key (gensym '#,nt)])
|
|
|
|
#`(let ([key (gensym '#,nt)])
|
|
|
|
(lambda (stream last-consumed-token depth end success-k fail-k max-depth tasks)
|
|
|
|
(λ (stream last-consumed-token depth end success-k fail-k max-depth tasks)
|
|
|
|
(parse-nt/share
|
|
|
|
(parse-nt/share
|
|
|
|
key #,(car info) '#,(cadr info) stream last-consumed-token depth end
|
|
|
|
key #,(car info) '#,(cadr info) stream last-consumed-token depth end
|
|
|
|
max-depth tasks
|
|
|
|
max-depth tasks
|
|
|
|
success-k fail-k
|
|
|
|
success-k fail-k
|
|
|
|
(lambda (end max-depth tasks success-k fail-k)
|
|
|
|
(λ (end max-depth tasks success-k fail-k)
|
|
|
|
#,(let loop ([pats pats]
|
|
|
|
#,(let loop ([pats pats]
|
|
|
|
[handles (syntax->list handles)]
|
|
|
|
[handles (syntax->list handles)]
|
|
|
|
[$ctxs (syntax->list $ctxs)]
|
|
|
|
[$ctxs (syntax->list $ctxs)]
|
|
|
@ -680,13 +623,13 @@
|
|
|
|
(car simple?s))
|
|
|
|
(car simple?s))
|
|
|
|
#'parse-or
|
|
|
|
#'parse-or
|
|
|
|
#'parse-parallel-or)
|
|
|
|
#'parse-parallel-or)
|
|
|
|
(lambda (stream last-consumed-token depth end success-k fail-k max-depth tasks)
|
|
|
|
(λ (stream last-consumed-token depth end success-k fail-k max-depth tasks)
|
|
|
|
#,(build-match nts
|
|
|
|
#,(build-match nts
|
|
|
|
toks
|
|
|
|
toks
|
|
|
|
(car pats)
|
|
|
|
(car pats)
|
|
|
|
(car handles)
|
|
|
|
(car handles)
|
|
|
|
(car $ctxs)))
|
|
|
|
(car $ctxs)))
|
|
|
|
(lambda (stream last-consumed-token depth end success-k fail-k max-depth tasks)
|
|
|
|
(λ (stream last-consumed-token depth end success-k fail-k max-depth tasks)
|
|
|
|
#,(loop (cdr pats)
|
|
|
|
#,(loop (cdr pats)
|
|
|
|
(cdr handles)
|
|
|
|
(cdr handles)
|
|
|
|
(cdr $ctxs)
|
|
|
|
(cdr $ctxs)
|
|
|
@ -694,14 +637,14 @@
|
|
|
|
stream last-consumed-token depth end success-k fail-k max-depth tasks)))))))))
|
|
|
|
stream last-consumed-token depth end success-k fail-k max-depth tasks)))))))))
|
|
|
|
nt-ids
|
|
|
|
nt-ids
|
|
|
|
patss
|
|
|
|
patss
|
|
|
|
(syntax->list #'(((begin handle0 handle ...) ...) ...))
|
|
|
|
(syntax->list #'(((begin HANDLE0 HANDLE ...) ...) ...))
|
|
|
|
(syntax->list #'((handle0 ...) ...)))
|
|
|
|
(syntax->list #'((HANDLE0 ...) ...)))
|
|
|
|
cfg-error
|
|
|
|
cfg-error
|
|
|
|
src-pos?
|
|
|
|
src-pos?
|
|
|
|
(list*
|
|
|
|
(list*
|
|
|
|
(with-syntax ([((tok tok-id . $e) ...)
|
|
|
|
(with-syntax ([((tok tok-id . $e) ...)
|
|
|
|
(token-identifier-mapping-map toks
|
|
|
|
(token-identifier-mapping-map toks
|
|
|
|
(lambda (k v)
|
|
|
|
(λ (k v)
|
|
|
|
(list* k
|
|
|
|
(list* k
|
|
|
|
(car v)
|
|
|
|
(car v)
|
|
|
|
(if (cdr v)
|
|
|
|
(if (cdr v)
|
|
|
@ -743,19 +686,19 @@
|
|
|
|
src-pos?
|
|
|
|
src-pos?
|
|
|
|
(cons (car clauses) parser-clauses))]))))])
|
|
|
|
(cons (car clauses) parser-clauses))]))))])
|
|
|
|
#`(let ([orig-parse (parser
|
|
|
|
#`(let ([orig-parse (parser
|
|
|
|
[error (lambda (a b c)
|
|
|
|
[error (λ (a b c)
|
|
|
|
(error 'cfg-parser "unexpected ~a token: ~a" b c))]
|
|
|
|
(error 'cfg-parser "unexpected ~a token: ~a" b c))]
|
|
|
|
. #,parser-clauses)]
|
|
|
|
. #,parser-clauses)]
|
|
|
|
[error-proc #,cfg-error])
|
|
|
|
[error-proc #,cfg-error])
|
|
|
|
(letrec #,grammar
|
|
|
|
(letrec #,grammar
|
|
|
|
(lambda (get-tok)
|
|
|
|
(λ (get-tok)
|
|
|
|
(let ([tok-list (orig-parse get-tok)])
|
|
|
|
(let ([tok-list (orig-parse get-tok)])
|
|
|
|
(letrec ([success-k
|
|
|
|
(letrec ([success-k
|
|
|
|
(lambda (val stream last-consumed-token depth max-depth tasks next)
|
|
|
|
(λ (val stream last-consumed-token depth max-depth tasks next)
|
|
|
|
(if (null? stream)
|
|
|
|
(if (null? stream)
|
|
|
|
val
|
|
|
|
val
|
|
|
|
(next success-k fail-k max-depth tasks)))]
|
|
|
|
(next success-k fail-k max-depth tasks)))]
|
|
|
|
[fail-k (lambda (max-depth tasks)
|
|
|
|
[fail-k (λ (max-depth tasks)
|
|
|
|
(cond
|
|
|
|
(cond
|
|
|
|
[(null? tok-list)
|
|
|
|
[(null? tok-list)
|
|
|
|
(if error-proc
|
|
|
|
(if error-proc
|
|
|
@ -847,7 +790,7 @@
|
|
|
|
(define (parse s)
|
|
|
|
(define (parse s)
|
|
|
|
(define ip (open-input-string s))
|
|
|
|
(define ip (open-input-string s))
|
|
|
|
(port-count-lines! ip)
|
|
|
|
(port-count-lines! ip)
|
|
|
|
(-parse (lambda () (lex ip))))
|
|
|
|
(-parse (λ () (lex ip))))
|
|
|
|
|
|
|
|
|
|
|
|
(check-equal? (parse "abc")
|
|
|
|
(check-equal? (parse "abc")
|
|
|
|
'(unanchored (lit "abc" 1 4) 1 4))
|
|
|
|
'(unanchored (lit "abc" 1 4) 1 4))
|
|
|
@ -881,7 +824,7 @@
|
|
|
|
(tokens non-terminals)
|
|
|
|
(tokens non-terminals)
|
|
|
|
(start <program>)
|
|
|
|
(start <program>)
|
|
|
|
(end EOF)
|
|
|
|
(end EOF)
|
|
|
|
(error (lambda (a b stx)
|
|
|
|
(error (λ (a b stx)
|
|
|
|
(error 'parse "failed at ~s" stx)))
|
|
|
|
(error 'parse "failed at ~s" stx)))
|
|
|
|
(grammar [<program> [(PLUS) "plus"]
|
|
|
|
(grammar [<program> [(PLUS) "plus"]
|
|
|
|
[(<minus-program> BAR <minus-program>) (list $1 $2 $3)]
|
|
|
|
[(<minus-program> BAR <minus-program>) (list $1 $2 $3)]
|
|
|
@ -903,7 +846,7 @@
|
|
|
|
-|-*|-|-**|-|-*|-|-***|-|-*|-|-**|-|-*|-|-*****"
|
|
|
|
-|-*|-|-**|-|-*|-|-***|-|-*|-|-**|-|-*|-|-*****"
|
|
|
|
;; This one fails:
|
|
|
|
;; This one fails:
|
|
|
|
#;"+*")])
|
|
|
|
#;"+*")])
|
|
|
|
(check-equal? (parse (lambda () (lex p)))
|
|
|
|
(check-equal? (parse (λ () (lex p)))
|
|
|
|
'((((((((((("minus" || "minus") . *) || (("minus" || "minus") . *)) . *) || (((("minus" || "minus") . *) || (("minus" || "minus") . *)) . *)) . *)
|
|
|
|
'((((((((((("minus" || "minus") . *) || (("minus" || "minus") . *)) . *) || (((("minus" || "minus") . *) || (("minus" || "minus") . *)) . *)) . *)
|
|
|
|
||
|
|
|
|
||
|
|
|
|
(((((("minus" || "minus") . *) || (("minus" || "minus") . *)) . *) || (((("minus" || "minus") . *) || (("minus" || "minus") . *)) . *)) . *))
|
|
|
|
(((((("minus" || "minus") . *) || (("minus" || "minus") . *)) . *) || (((("minus" || "minus") . *) || (("minus" || "minus") . *)) . *)) . *))
|
|
|
|