syntax/parse: fix opaque head patterns and splicing syntax classes

closes PR 12537
This commit is contained in:
Ryan Culpepper 2012-02-07 04:03:12 -07:00
parent 2de9de9b26
commit e2404184ee
4 changed files with 95 additions and 12 deletions

View File

@ -267,7 +267,7 @@ Conventions:
;; Update the prompt, if required ;; Update the prompt, if required
;; FIXME: can be optimized away if no cut immediately within variants... ;; FIXME: can be optimized away if no cut immediately within variants...
(with-maybe-delimit-cut delimit-cut? (with-maybe-delimit-cut delimit-cut?
(parse:variants x cx relsattrs variants splicing? (parse:variants x cx relsattrs variants splicing? transparent?
pr es success cp0 commit?))))))))])) pr es success cp0 commit?))))))))]))
;; (with-maybe-delimit-cut bool expr) ;; (with-maybe-delimit-cut bool expr)
@ -281,27 +281,33 @@ Conventions:
;; (parse:variants x cx relsattrs variants splicing? pr es success cp0) : expr[Ans] ;; (parse:variants x cx relsattrs variants splicing? pr es success cp0) : expr[Ans]
(define-syntax (parse:variants stx) (define-syntax (parse:variants stx)
(syntax-case stx () (syntax-case stx ()
[(parse:variants x cx relsattrs () splicing? pr es success cp0 commit?) [(parse:variants x cx relsattrs () splicing? transparent?
pr es success cp0 commit?)
;; Special case: no variants ;; Special case: no variants
#'(fail (failure pr es))] #'(fail (failure pr es))]
[(parse:variants x cx relsattrs (variant ...) splicing? pr es success cp0 commit?) [(parse:variants x cx relsattrs (variant ...) splicing? transparent?
#'(try (parse:variant x cx relsattrs variant splicing? pr es success cp0 commit?) ...)])) pr es success cp0 commit?)
#'(try (parse:variant x cx relsattrs variant splicing? transparent?
pr es success cp0 commit?) ...)]))
;; (parse:variant x cx relsattrs variant splicing? pr es success cp0) : expr[Ans] ;; (parse:variant x cx relsattrs variant splicing? pr es success cp0) : expr[Ans]
(define-syntax (parse:variant stx) (define-syntax (parse:variant stx)
(syntax-case stx () (syntax-case stx ()
[(parse:variant x cx relsattrs variant #f pr es success cp0 commit?) [(parse:variant x cx relsattrs variant #f _ pr es success cp0 commit?)
(with-syntax ([#s(variant _ _ pattern (def ...)) #'variant]) (with-syntax ([#s(variant _ _ pattern (def ...)) #'variant])
#`(let () #`(let ()
def ... def ...
(parse:S x cx pattern pr es (parse:S x cx pattern pr es
(variant-success relsattrs variant () success cp0 commit?))))] (variant-success relsattrs variant
[(parse:variant x cx relsattrs variant #t pr es success cp0 commit?) ()
success cp0 commit?))))]
[(parse:variant x cx relsattrs variant #t transparent? pr es success cp0 commit?)
(with-syntax ([#s(variant _ _ pattern (def ...)) #'variant]) (with-syntax ([#s(variant _ _ pattern (def ...)) #'variant])
#`(let () #`(let ()
def ... def ...
(parse:H x cx rest-x rest-cx rest-pr pattern pr es (parse:H x cx rest-x rest-cx rest-pr pattern pr es
(variant-success relsattrs variant (rest-x rest-cx rest-pr) (variant-success relsattrs variant
(rest-x rest-cx (if 'transparent? rest-pr (ps-pop-opaque rest-pr)))
success cp0 commit?))))])) success cp0 commit?))))]))
;; (variant-success relsattrs variant (also:id ...) success bool) : expr[Ans] ;; (variant-success relsattrs variant (also:id ...) success bool) : expr[Ans]
@ -666,8 +672,11 @@ Conventions:
[(parse:H x cx rest-x rest-cx rest-pr head pr es k) [(parse:H x cx rest-x rest-cx rest-pr head pr es k)
(syntax-case #'head () (syntax-case #'head ()
[#s(hpat:describe _ description transparent? pattern) [#s(hpat:describe _ description transparent? pattern)
#`(let ([es (cons (expect:thing description transparent?) es)]) #`(let ([es* (cons (expect:thing description transparent?) es)]
(parse:H x cx rest-x rest-cx rest-pr pattern pr es k))] [pr (if 'transparent? pr (ps-add-opaque pr))])
(parse:H x cx rest-x rest-cx rest-pr pattern pr es*
(let ([rest-pr (if 'transparent? rest-pr (ps-pop-opaque rest-pr))])
k)))]
[#s(hpat:var _attrs name parser argu (nested-a ...) attr-count commit?) [#s(hpat:var _attrs name parser argu (nested-a ...) attr-count commit?)
(with-syntax ([(av ...) (generate-n-temporaries (syntax-e #'attr-count))] (with-syntax ([(av ...) (generate-n-temporaries (syntax-e #'attr-count))]
[(name-attr ...) [(name-attr ...)

View File

@ -14,6 +14,7 @@
ps-add-opaque ps-add-opaque
invert-ps invert-ps
ps-pop-opaque
ps->stx+index ps->stx+index
ps-context-syntax ps-context-syntax
ps-difference ps-difference
@ -152,6 +153,14 @@ Interpretation: Inner PS structures are applied first.
(define (invert-ps ps) (define (invert-ps ps)
(reverse (ps-truncate-opaque ps))) (reverse (ps-truncate-opaque ps)))
;; ps-pop-opaque : PS -> IPS
(define (ps-pop-opaque ps)
(match ps
[(cons (? exact-positive-integer? n) (cons 'opaque ps*))
(cons n ps*)]
[(cons 'opaque ps*)
ps*]
[_ (error 'ps-pop-opaque "opaque marker not found: ~e" ps)]))
;; ==== Failure ==== ;; ==== Failure ====
@ -202,7 +211,7 @@ The *-marked variants can only occur at the top of the stack.
expect->sexpr) expect->sexpr)
(define (failureset->sexpr fs) (define (failureset->sexpr fs)
(let ([fs (flatten fs null)]) (let ([fs (flatten fs)])
(case (length fs) (case (length fs)
((1) (failure->sexpr (car fs))) ((1) (failure->sexpr (car fs)))
(else `(union ,@(map failure->sexpr fs)))))) (else `(union ,@(map failure->sexpr fs))))))

View File

@ -5,7 +5,8 @@
syntax-patterns-fail) syntax-patterns-fail)
"kws.rkt") "kws.rkt")
(provide syntax-patterns-fail (provide syntax-patterns-fail
current-failure-handler) current-failure-handler
maximal-failures)
#| #|
Note: there is a cyclic dependence between residual.rkt and this module, Note: there is a cyclic dependence between residual.rkt and this module,

View File

@ -395,3 +395,67 @@
[(_ 1 ... . after-ones:expr) [(_ 1 ... . after-ones:expr)
(syntax? #'after-ones)])) (syntax? #'after-ones)]))
(void)) (void))
(begin
;; from samth 2/4/2012
;; opaque head patterns used to propagate progress *with opaque marker* to tail
(test-case "opaque H, ok"
(check-equal? (syntax-parse #'(a b)
[((~describe #:opaque "x" (~seq x)) y:id) 'ok])
'ok))
(test-case "opaque splicing stxclass, ok"
(check-equal? (let ()
(define-splicing-syntax-class foo
#:opaque
#:description "foo"
(pattern (~seq x)))
(syntax-parse #'(a b)
[(f:foo y:id) 'ok]))
'ok))
(test-case "opaque empty H, ok"
(check-equal? (syntax-parse #'(b)
[((~describe #:opaque "x" (~seq)) y:id) 'ok])
'ok))
(test-case "opaque empty splicing stxclass, ok"
(check-equal? (let ()
(define-splicing-syntax-class foo
#:opaque
#:description "foo"
(pattern (~seq)))
(syntax-parse #'(b)
[(f:foo y:id) 'ok]))
'ok))
(tcerr "extent of opaque in H pattern"
(syntax-parse #'(a b)
[((~describe #:opaque "x" (~seq x)) y:nat) (void)])
(not #rx"expected x") ;; y:nat was incorrectly considered part of opaque region
#rx"expected exact-nonnegative-integer")
(tcerr "extent of opaque in splicing stxclass"
(let ()
(define-splicing-syntax-class foo
#:description "foo"
#:opaque
(pattern (~seq x)))
(syntax-parse #'(a b)
[(f:foo n:nat) (void)]))
(not #rx"expected foo") ;; y:nat was incorrectly considered part of opaque region
#rx"expected exact-nonnegative-integer")
(tcerr "extent of opaque in empty H pattern"
(syntax-parse #'(b)
[((~describe #:opaque "x" (~seq)) y:nat) (void)])
(not #rx"expected x") ;; y:nat was incorrectly considered part of opaque region
#rx"expected exact-nonnegative-integer")
(tcerr "extent of opaque in empty splicing stxclass"
(let ()
(define-splicing-syntax-class foo
#:description "foo"
#:opaque
(pattern (~seq)))
(syntax-parse #'(b)
[(f:foo n:nat) (void)]))
(not #rx"expected foo") ;; y:nat was incorrectly considered part of opaque region
#rx"expected exact-nonnegative-integer")
)