syntax/parse: added ~parse action pattern
svn: r16097
This commit is contained in:
parent
95f81d4b50
commit
5ababfac9c
|
@ -19,7 +19,7 @@
|
||||||
(make-fce x (list #'(+ 0))))
|
(make-fce x (list #'(+ 0))))
|
||||||
|
|
||||||
(define (done-frontier x)
|
(define (done-frontier x)
|
||||||
(make-fce x (list #'(+ +inf.0))))
|
(make-fce x (list #'(+ 0) #'(+ +inf.0))))
|
||||||
|
|
||||||
(define (frontier:add-car fc x)
|
(define (frontier:add-car fc x)
|
||||||
(make-fce x (cons #'(+ 0) (fce-indexes fc))))
|
(make-fce x (cons #'(+ 0) (fce-indexes fc))))
|
||||||
|
@ -49,6 +49,11 @@
|
||||||
(define (frontier:add-unpstruct fc x)
|
(define (frontier:add-unpstruct fc x)
|
||||||
(frontier:add-car fc x))
|
(frontier:add-car fc x))
|
||||||
|
|
||||||
|
(define (frontier:add-subparse fc x)
|
||||||
|
(frontier:add-car
|
||||||
|
(frontier:add-index (frontier:add-car fc x) +inf.0)
|
||||||
|
x))
|
||||||
|
|
||||||
;; A DynamicFrontierContext (DFC) is a list of numbers.
|
;; A DynamicFrontierContext (DFC) is a list of numbers.
|
||||||
;; More operations on DFCs in runtime.ss
|
;; More operations on DFCs in runtime.ss
|
||||||
|
|
||||||
|
|
|
@ -329,7 +329,11 @@
|
||||||
(fail x
|
(fail x
|
||||||
#:expect (expectation pattern0)
|
#:expect (expectation pattern0)
|
||||||
#:fce fc)
|
#:fce fc)
|
||||||
k)])]))
|
k)]
|
||||||
|
[#s(ghost:parse _ pattern expr)
|
||||||
|
#`(let ([y (datum->syntax #f (without-fails expr))])
|
||||||
|
(parse:S y #,(frontier:add-subparse (wash #'fc) #'y)
|
||||||
|
pattern k))])]))
|
||||||
|
|
||||||
(begin-for-syntax
|
(begin-for-syntax
|
||||||
;; convert-list-pattern : ListPattern id -> SinglePattern
|
;; convert-list-pattern : ListPattern id -> SinglePattern
|
||||||
|
|
|
@ -55,6 +55,7 @@ A GhostPattern is one of
|
||||||
(make-ghost:fail Base stx stx)
|
(make-ghost:fail Base stx stx)
|
||||||
(make-ghost:bind Base (listof clause:attr))
|
(make-ghost:bind Base (listof clause:attr))
|
||||||
* (make-ghost:and Base (listof GhostPattern))
|
* (make-ghost:and Base (listof GhostPattern))
|
||||||
|
(make-ghost:parse Base SinglePattern stx)
|
||||||
|
|
||||||
ghost:and is desugared below in create-* procedures
|
ghost:and is desugared below in create-* procedures
|
||||||
|#
|
|#
|
||||||
|
@ -63,6 +64,7 @@ ghost:and is desugared below in create-* procedures
|
||||||
(define-struct ghost:fail (attrs when message) #:prefab)
|
(define-struct ghost:fail (attrs when message) #:prefab)
|
||||||
(define-struct ghost:bind (attrs clauses) #:prefab)
|
(define-struct ghost:bind (attrs clauses) #:prefab)
|
||||||
(define-struct ghost:and (attrs patterns) #:prefab)
|
(define-struct ghost:and (attrs patterns) #:prefab)
|
||||||
|
(define-struct ghost:parse (attrs pattern expr) #:prefab)
|
||||||
|
|
||||||
#|
|
#|
|
||||||
A HeadPattern is one of
|
A HeadPattern is one of
|
||||||
|
@ -126,7 +128,8 @@ A Kind is one of
|
||||||
(or (ghost:cut? x)
|
(or (ghost:cut? x)
|
||||||
(ghost:bind? x)
|
(ghost:bind? x)
|
||||||
(ghost:fail? x)
|
(ghost:fail? x)
|
||||||
(ghost:and? x)))
|
(ghost:and? x)
|
||||||
|
(ghost:parse? x)))
|
||||||
|
|
||||||
(define (head-pattern? x)
|
(define (head-pattern? x)
|
||||||
(or (hpat:var? x)
|
(or (hpat:var? x)
|
||||||
|
@ -163,7 +166,7 @@ A Kind is one of
|
||||||
[else (raise-type-error 'pattern-attrs "pattern" x)])))]))
|
[else (raise-type-error 'pattern-attrs "pattern" x)])))]))
|
||||||
(mk-get-attrs pat:any pat:var pat:datum pat:literal pat:ghost pat:head
|
(mk-get-attrs pat:any pat:var pat:datum pat:literal pat:ghost pat:head
|
||||||
pat:dots pat:and pat:or pat:not pat:compound pat:describe
|
pat:dots pat:and pat:or pat:not pat:compound pat:describe
|
||||||
ghost:cut ghost:bind ghost:fail ghost:and
|
ghost:cut ghost:bind ghost:fail ghost:and ghost:parse
|
||||||
hpat:var hpat:seq hpat:ghost hpat:and hpat:or hpat:describe
|
hpat:var hpat:seq hpat:ghost hpat:and hpat:or hpat:describe
|
||||||
hpat:optional
|
hpat:optional
|
||||||
ehpat)))
|
ehpat)))
|
||||||
|
@ -233,6 +236,9 @@ A Kind is one of
|
||||||
(let ([attrs (append-iattrs (map pattern-attrs patterns))])
|
(let ([attrs (append-iattrs (map pattern-attrs patterns))])
|
||||||
(make ghost:and attrs patterns)))
|
(make ghost:and attrs patterns)))
|
||||||
|
|
||||||
|
(define (create-ghost:parse pattern expr)
|
||||||
|
(make ghost:parse (pattern-attrs pattern) pattern expr))
|
||||||
|
|
||||||
;; ----
|
;; ----
|
||||||
|
|
||||||
(define (create-hpat:var name parser args nested-attrs)
|
(define (create-hpat:var name parser args nested-attrs)
|
||||||
|
|
|
@ -85,10 +85,11 @@
|
||||||
(quote-syntax ~bounds)
|
(quote-syntax ~bounds)
|
||||||
(quote-syntax ~rest)
|
(quote-syntax ~rest)
|
||||||
(quote-syntax ~struct)
|
(quote-syntax ~struct)
|
||||||
(quote-syntax ~!)
|
|
||||||
(quote-syntax ~describe)
|
(quote-syntax ~describe)
|
||||||
|
(quote-syntax ~!)
|
||||||
(quote-syntax ~bind)
|
(quote-syntax ~bind)
|
||||||
(quote-syntax ~fail)))
|
(quote-syntax ~fail)
|
||||||
|
(quote-syntax ~parse)))
|
||||||
|
|
||||||
(define (reserved? stx)
|
(define (reserved? stx)
|
||||||
(and (identifier? stx)
|
(and (identifier? stx)
|
||||||
|
@ -279,8 +280,8 @@
|
||||||
[(not allow-head?) (ghost-pattern->single-pattern x)]
|
[(not allow-head?) (ghost-pattern->single-pattern x)]
|
||||||
[else
|
[else
|
||||||
(wrong-syntax stx "action pattern not allowed here")]))
|
(wrong-syntax stx "action pattern not allowed here")]))
|
||||||
(syntax-case stx (~var ~literal ~and ~or ~not ~rest ~struct
|
(syntax-case stx (~var ~literal ~and ~or ~not ~rest ~struct ~describe
|
||||||
~! ~describe ~bind ~fail ~seq ~optional)
|
~seq ~optional ~! ~bind ~fail ~parse)
|
||||||
[wildcard
|
[wildcard
|
||||||
(wildcard? #'wildcard)
|
(wildcard? #'wildcard)
|
||||||
(create-pat:any)]
|
(create-pat:any)]
|
||||||
|
@ -322,6 +323,9 @@
|
||||||
[(~fail . rest)
|
[(~fail . rest)
|
||||||
(check-ghost!
|
(check-ghost!
|
||||||
(parse-pat:fail stx decls))]
|
(parse-pat:fail stx decls))]
|
||||||
|
[(~parse . rest)
|
||||||
|
(check-ghost!
|
||||||
|
(parse-pat:parse stx decls))]
|
||||||
[(head dots . tail)
|
[(head dots . tail)
|
||||||
(dots? #'dots)
|
(dots? #'dots)
|
||||||
(parse-pat:dots stx #'head #'tail decls)]
|
(parse-pat:dots stx #'head #'tail decls)]
|
||||||
|
@ -630,7 +634,16 @@
|
||||||
[()
|
[()
|
||||||
(wrong-syntax stx "missing message expression")]
|
(wrong-syntax stx "missing message expression")]
|
||||||
[_
|
[_
|
||||||
(wrong-syntax stx "bad fail pattern")])))]))
|
(wrong-syntax stx "bad ~fail pattern")])))]))
|
||||||
|
|
||||||
|
(define (parse-pat:parse stx decls)
|
||||||
|
(syntax-case stx (~parse)
|
||||||
|
[(~parse pattern expr)
|
||||||
|
(let ([p (parse-single-pattern #'pattern decls)])
|
||||||
|
(create-ghost:parse p #'expr))]
|
||||||
|
[_
|
||||||
|
(wrong-syntax stx "bad ~parse pattern")]))
|
||||||
|
|
||||||
|
|
||||||
(define (parse-pat:rest stx decls)
|
(define (parse-pat:rest stx decls)
|
||||||
(syntax-case stx ()
|
(syntax-case stx ()
|
||||||
|
|
|
@ -22,10 +22,11 @@
|
||||||
~optional
|
~optional
|
||||||
~rest
|
~rest
|
||||||
~struct
|
~struct
|
||||||
~!
|
|
||||||
~describe
|
~describe
|
||||||
|
~!
|
||||||
~bind
|
~bind
|
||||||
~fail
|
~fail
|
||||||
|
~parse
|
||||||
|
|
||||||
current-expression
|
current-expression
|
||||||
current-macro-name
|
current-macro-name
|
||||||
|
@ -88,10 +89,11 @@
|
||||||
(define-keyword ~optional)
|
(define-keyword ~optional)
|
||||||
(define-keyword ~rest)
|
(define-keyword ~rest)
|
||||||
(define-keyword ~struct)
|
(define-keyword ~struct)
|
||||||
(define-keyword ~!)
|
|
||||||
(define-keyword ~describe)
|
(define-keyword ~describe)
|
||||||
|
(define-keyword ~!)
|
||||||
(define-keyword ~bind)
|
(define-keyword ~bind)
|
||||||
(define-keyword ~fail)
|
(define-keyword ~fail)
|
||||||
|
(define-keyword ~parse)
|
||||||
|
|
||||||
;; == Parameters & Syntax Parameters
|
;; == Parameters & Syntax Parameters
|
||||||
|
|
||||||
|
|
|
@ -37,10 +37,11 @@
|
||||||
~optional
|
~optional
|
||||||
~rest
|
~rest
|
||||||
~struct
|
~struct
|
||||||
~!
|
|
||||||
~describe
|
~describe
|
||||||
|
~!
|
||||||
~bind
|
~bind
|
||||||
~fail
|
~fail
|
||||||
|
~parse
|
||||||
|
|
||||||
attribute
|
attribute
|
||||||
this-syntax)
|
this-syntax)
|
||||||
|
|
|
@ -83,9 +83,9 @@ When a special form in this manual refers to @svar[syntax-pattern]
|
||||||
(eg, the description of the @scheme[syntax-parse] special form), it
|
(eg, the description of the @scheme[syntax-parse] special form), it
|
||||||
means specifically @tech{@Spattern}.
|
means specifically @tech{@Spattern}.
|
||||||
|
|
||||||
@schemegrammar*[#:literals (_ ~var ~literal ~or ~and ~not ~seq
|
@schemegrammar*[#:literals (_ ~var ~literal ~or ~and ~not ~rest ~struct
|
||||||
~rep ~once ~optional
|
~describe ~seq ~optional ~rep ~once
|
||||||
~rest ~struct ~! ~describe ~bind ~fail)
|
~! ~bind ~fail ~parse)
|
||||||
[S-pattern
|
[S-pattern
|
||||||
pvar-id
|
pvar-id
|
||||||
pvar-id:syntax-class-id
|
pvar-id:syntax-class-id
|
||||||
|
@ -130,6 +130,7 @@ means specifically @tech{@Spattern}.
|
||||||
~!
|
~!
|
||||||
(~bind [attr-id expr] ...)
|
(~bind [attr-id expr] ...)
|
||||||
(~fail maybe-fail-condition message-expr)
|
(~fail maybe-fail-condition message-expr)
|
||||||
|
(~parse S-pattern stx-expr)
|
||||||
(@#,ref[~and a] A-pattern ...+)]
|
(@#,ref[~and a] A-pattern ...+)]
|
||||||
[proper-S-pattern
|
[proper-S-pattern
|
||||||
#, @elem{a @svar{S-pattern} that is not a @svar{A-pattern}}]
|
#, @elem{a @svar{S-pattern} that is not a @svar{A-pattern}}]
|
||||||
|
@ -800,6 +801,13 @@ specific ill-formed terms and address them with specially-created
|
||||||
failure messages.
|
failure messages.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@specsubform[(@#,defhere[~parse] S-pattern stx-expr)
|
||||||
|
#:contracts ([stx-expr syntax?])]{
|
||||||
|
|
||||||
|
Evaluates @scheme[stx-expr] to a syntax object and matches it against
|
||||||
|
@scheme[S-pattern].
|
||||||
|
}
|
||||||
|
|
||||||
@specsubform[(@#,def[~and a] A-pattern ...+)]{
|
@specsubform[(@#,def[~and a] A-pattern ...+)]{
|
||||||
|
|
||||||
Performs the actions of each @scheme[A-pattern].
|
Performs the actions of each @scheme[A-pattern].
|
||||||
|
|
|
@ -198,6 +198,27 @@
|
||||||
(tok (1 2) (~and x:two :two)
|
(tok (1 2) (~and x:two :two)
|
||||||
(and (bound (x 0) (x.a 0) (a 0)) (s= x '(1 2)) (s= x.a 1) (s= a 1)))
|
(and (bound (x 0) (x.a 0) (a 0)) (s= x '(1 2)) (s= x.a 1) (s= a 1)))
|
||||||
|
|
||||||
|
;; -- H patterns
|
||||||
|
|
||||||
|
;; seq
|
||||||
|
(tok (1 2 3) ((~seq 1 2) 3))
|
||||||
|
(tok (1 2 3) (1 (~seq 2) 3))
|
||||||
|
(tok (1 2 3) ((~seq) 1 2 3))
|
||||||
|
|
||||||
|
;; or
|
||||||
|
(tok (1 2 3) ((~or (~seq 1 2) 1) 3))
|
||||||
|
(tok (1 2 3) ((~or 1 (~seq 1 2)) 3))
|
||||||
|
(tok (1 2 3) ((~or (~seq 1) (~seq 1 2)) 3))
|
||||||
|
(tok (1 2 3) ((~or (~seq 1) (~seq)) 1 2 3))
|
||||||
|
(tok (1 2 3) ((~or (~seq 1) (~seq)) 1 2 3 (~or (~seq 4) (~seq))))
|
||||||
|
|
||||||
|
;; describe
|
||||||
|
(tok (1 2 3) ((~describe "one-two" (~seq 1 2)) 3))
|
||||||
|
(terx (1 3 3) ((~describe "one-two" (~seq 1 2)) 3)
|
||||||
|
"one-two")
|
||||||
|
|
||||||
|
;; -- A patterns
|
||||||
|
|
||||||
;; cut patterns
|
;; cut patterns
|
||||||
(terx* (1 2 3) [(1 ~! 4) (1 2 3)]
|
(terx* (1 2 3) [(1 ~! 4) (1 2 3)]
|
||||||
"4" (not "2"))
|
"4" (not "2"))
|
||||||
|
@ -227,24 +248,15 @@
|
||||||
(terx 1 (~and n:nat (~fail #:unless (even? (syntax-e #'n)) "wanted even number"))
|
(terx 1 (~and n:nat (~fail #:unless (even? (syntax-e #'n)) "wanted even number"))
|
||||||
#rx"wanted even number")
|
#rx"wanted even number")
|
||||||
|
|
||||||
;; -- H patterns
|
;; fail as S-pattern
|
||||||
|
(terx 1 (~fail "grr")
|
||||||
|
#rx"grr")
|
||||||
|
|
||||||
;; seq
|
(tok (1 2 3) (x:nat y:nat (~parse (~or 2 3) (+ (syntax-e #'x) (syntax-e #'y))) z:nat))
|
||||||
(tok (1 2 3) ((~seq 1 2) 3))
|
(terx (1 2 3) (x:nat y:nat (~parse 4 (+ (syntax-e #'x) (syntax-e #'y))) z:nat)
|
||||||
(tok (1 2 3) (1 (~seq 2) 3))
|
"expected the literal 4")
|
||||||
(tok (1 2 3) ((~seq) 1 2 3))
|
(terx (1 2 3) (x:nat y:nat (~parse (2 4) #'(x y)))
|
||||||
|
"expected the literal 2")
|
||||||
;; or
|
|
||||||
(tok (1 2 3) ((~or (~seq 1 2) 1) 3))
|
|
||||||
(tok (1 2 3) ((~or 1 (~seq 1 2)) 3))
|
|
||||||
(tok (1 2 3) ((~or (~seq 1) (~seq 1 2)) 3))
|
|
||||||
(tok (1 2 3) ((~or (~seq 1) (~seq)) 1 2 3))
|
|
||||||
(tok (1 2 3) ((~or (~seq 1) (~seq)) 1 2 3 (~or (~seq 4) (~seq))))
|
|
||||||
|
|
||||||
;; describe
|
|
||||||
(tok (1 2 3) ((~describe "one-two" (~seq 1 2)) 3))
|
|
||||||
(terx (1 3 3) ((~describe "one-two" (~seq 1 2)) 3)
|
|
||||||
"one-two")
|
|
||||||
|
|
||||||
;; == Lib tests
|
;; == Lib tests
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user