Added ~peek-not, cf packrat/PEG ! operator
This commit is contained in:
parent
ff7fd55d86
commit
c941db0bfa
|
@ -603,6 +603,23 @@ Conventions:
|
||||||
(parse:H x cx dummy-x dummy-cx dummy-pr pattern pr es
|
(parse:H x cx dummy-x dummy-cx dummy-pr pattern pr es
|
||||||
(let ([rest-x saved-x] [rest-cx saved-cx] [rest-pr saved-pr])
|
(let ([rest-x saved-x] [rest-cx saved-cx] [rest-pr saved-pr])
|
||||||
k)))]
|
k)))]
|
||||||
|
[#s(hpat:peek-not () subpattern)
|
||||||
|
#`(let* ([fh0 fail-handler]
|
||||||
|
[pr0 pr]
|
||||||
|
[es0 es]
|
||||||
|
[fail-to-succeed
|
||||||
|
(lambda (fs)
|
||||||
|
(let ([rest-x x]
|
||||||
|
[rest-cx cx]
|
||||||
|
[rest-pr pr])
|
||||||
|
k))])
|
||||||
|
;; ~not implicitly prompts to be safe,
|
||||||
|
;; but ~! not allowed within ~not (unless within ~delimit-cut, etc)
|
||||||
|
;; (statically checked!)
|
||||||
|
(with ([fail-handler fail-to-succeed]
|
||||||
|
[cut-prompt fail-to-succeed]) ;; to be safe
|
||||||
|
(parse:H x cx rest-x rest-cx rest-pr subpattern pr es
|
||||||
|
(fh0 (failure pr0 es0)))))]
|
||||||
[_
|
[_
|
||||||
(with-syntax ([attrs (pattern-attrs (wash #'head))])
|
(with-syntax ([attrs (pattern-attrs (wash #'head))])
|
||||||
#'(parse:S x cx
|
#'(parse:S x cx
|
||||||
|
|
|
@ -105,6 +105,7 @@ A HeadPattern is one of
|
||||||
(hpat:reflect Base stx Arguments (listof SAttr) id (listof IAttr))
|
(hpat:reflect Base stx Arguments (listof SAttr) id (listof IAttr))
|
||||||
(hpat:post Base HeadPattern)
|
(hpat:post Base HeadPattern)
|
||||||
(hpat:peek Base HeadPattern)
|
(hpat:peek Base HeadPattern)
|
||||||
|
(hpat:peek-not Base HeadPattern)
|
||||||
|#
|
|#
|
||||||
|
|
||||||
(define-struct hpat:var (attrs name parser argu nested-attrs attr-count commit?) #:prefab)
|
(define-struct hpat:var (attrs name parser argu nested-attrs attr-count commit?) #:prefab)
|
||||||
|
@ -119,6 +120,7 @@ A HeadPattern is one of
|
||||||
(define-struct hpat:reflect (attrs obj argu attr-decls name nested-attrs) #:prefab)
|
(define-struct hpat:reflect (attrs obj argu attr-decls name nested-attrs) #:prefab)
|
||||||
(define-struct hpat:post (attrs pattern) #:prefab)
|
(define-struct hpat:post (attrs pattern) #:prefab)
|
||||||
(define-struct hpat:peek (attrs pattern) #:prefab)
|
(define-struct hpat:peek (attrs pattern) #:prefab)
|
||||||
|
(define-struct hpat:peek-not (attrs pattern) #:prefab)
|
||||||
|
|
||||||
#|
|
#|
|
||||||
An EllipsisHeadPattern is
|
An EllipsisHeadPattern is
|
||||||
|
@ -192,7 +194,8 @@ A SideClause is one of
|
||||||
(hpat:commit? x)
|
(hpat:commit? x)
|
||||||
(hpat:reflect? x)
|
(hpat:reflect? x)
|
||||||
(hpat:post? x)
|
(hpat:post? x)
|
||||||
(hpat:peek? x)))
|
(hpat:peek? x)
|
||||||
|
(hpat:peek-not? x)))
|
||||||
|
|
||||||
(define (ellipsis-head-pattern? x)
|
(define (ellipsis-head-pattern? x)
|
||||||
(ehpat? x))
|
(ehpat? x))
|
||||||
|
@ -224,7 +227,7 @@ A SideClause is one of
|
||||||
action:do action:post
|
action:do action:post
|
||||||
hpat:var hpat:seq hpat:action hpat:and hpat:or hpat:describe
|
hpat:var hpat:seq hpat:action hpat:and hpat:or hpat:describe
|
||||||
hpat:optional hpat:delimit hpat:commit hpat:reflect hpat:post
|
hpat:optional hpat:delimit hpat:commit hpat:reflect hpat:post
|
||||||
hpat:peek
|
hpat:peek hpat:peek-not
|
||||||
ehpat)))
|
ehpat)))
|
||||||
|
|
||||||
;; ----
|
;; ----
|
||||||
|
@ -375,6 +378,9 @@ A SideClause is one of
|
||||||
(define (create-hpat:peek pattern)
|
(define (create-hpat:peek pattern)
|
||||||
(make hpat:peek (pattern-attrs pattern) pattern))
|
(make hpat:peek (pattern-attrs pattern) pattern))
|
||||||
|
|
||||||
|
(define (create-hpat:peek-not pattern)
|
||||||
|
(make hpat:peek-not null pattern))
|
||||||
|
|
||||||
;; ----
|
;; ----
|
||||||
|
|
||||||
(define (action/head-pattern->list-pattern p)
|
(define (action/head-pattern->list-pattern p)
|
||||||
|
|
|
@ -120,7 +120,8 @@
|
||||||
(quote-syntax ~reflect)
|
(quote-syntax ~reflect)
|
||||||
(quote-syntax ~splicing-reflect)
|
(quote-syntax ~splicing-reflect)
|
||||||
(quote-syntax ~eh-var)
|
(quote-syntax ~eh-var)
|
||||||
(quote-syntax ~peek)))
|
(quote-syntax ~peek)
|
||||||
|
(quote-syntax ~peek-not)))
|
||||||
|
|
||||||
(define (reserved? stx)
|
(define (reserved? stx)
|
||||||
(and (identifier? stx)
|
(and (identifier? stx)
|
||||||
|
@ -464,7 +465,7 @@ A syntax class is integrable if
|
||||||
(wrong-syntax stx "action pattern not allowed here")]))
|
(wrong-syntax stx "action pattern not allowed here")]))
|
||||||
(syntax-case stx (~var ~literal ~datum ~and ~or ~not ~rest ~describe
|
(syntax-case stx (~var ~literal ~datum ~and ~or ~not ~rest ~describe
|
||||||
~seq ~optional ~! ~bind ~fail ~parse ~do
|
~seq ~optional ~! ~bind ~fail ~parse ~do
|
||||||
~post ~peek ~delimit-cut ~commit ~reflect
|
~post ~peek ~peek-not ~delimit-cut ~commit ~reflect
|
||||||
~splicing-reflect)
|
~splicing-reflect)
|
||||||
[wildcard
|
[wildcard
|
||||||
(wildcard? #'wildcard)
|
(wildcard? #'wildcard)
|
||||||
|
@ -550,6 +551,10 @@ A syntax class is integrable if
|
||||||
(disappeared! stx)
|
(disappeared! stx)
|
||||||
(check-head!
|
(check-head!
|
||||||
(parse-pat:peek stx decls))]
|
(parse-pat:peek stx decls))]
|
||||||
|
[(~peek-not . rest)
|
||||||
|
(disappeared! stx)
|
||||||
|
(check-head!
|
||||||
|
(parse-pat:peek-not stx decls))]
|
||||||
[(~parse . rest)
|
[(~parse . rest)
|
||||||
(disappeared! stx)
|
(disappeared! stx)
|
||||||
(check-action!
|
(check-action!
|
||||||
|
@ -1028,6 +1033,12 @@ A syntax class is integrable if
|
||||||
(let ([p (parse-head-pattern #'pattern decls)])
|
(let ([p (parse-head-pattern #'pattern decls)])
|
||||||
(create-hpat:peek p))]))
|
(create-hpat:peek p))]))
|
||||||
|
|
||||||
|
(define (parse-pat:peek-not stx decls)
|
||||||
|
(syntax-case stx (~peek-not)
|
||||||
|
[(~peek-not pattern)
|
||||||
|
(let ([p (parse-head-pattern #'pattern decls)])
|
||||||
|
(create-hpat:peek-not p))]))
|
||||||
|
|
||||||
(define (parse-pat:parse stx decls)
|
(define (parse-pat:parse stx decls)
|
||||||
(syntax-case stx (~parse)
|
(syntax-case stx (~parse)
|
||||||
[(~parse pattern expr)
|
[(~parse pattern expr)
|
||||||
|
|
|
@ -29,7 +29,18 @@ Allow reflected syntax classes in conventions.
|
||||||
|
|
||||||
Rename "conventions" to "convention-set"?
|
Rename "conventions" to "convention-set"?
|
||||||
|
|
||||||
|
Unify convention-sets and literal-sets?
|
||||||
|
|
||||||
For documentation, talk about "primary attributes" vs "nested
|
For documentation, talk about "primary attributes" vs "nested
|
||||||
attributes". Helps explain ~eh-var and #:auto-nested-attributes.
|
attributes". Helps explain ~eh-var and #:auto-nested-attributes.
|
||||||
|
|
||||||
|
For documentation, deftech "term-sequence", use consistently in
|
||||||
|
H-pattern docs, etc.
|
||||||
|
|
||||||
|
Add documentation sections:
|
||||||
|
- Pattern matching model
|
||||||
|
- Static semantics (attributes)
|
||||||
|
|
||||||
|
Add syntax exception variant with more information.
|
||||||
|
|
||||||
Fix syntaxes pinpointed for repetition constraint violations.
|
Fix syntaxes pinpointed for repetition constraint violations.
|
||||||
|
|
|
@ -32,7 +32,7 @@ means specifically @tech{@Spattern}.
|
||||||
|
|
||||||
@schemegrammar*[#:literals (_ ~var ~literal ~or ~and ~not ~rest ~datum
|
@schemegrammar*[#:literals (_ ~var ~literal ~or ~and ~not ~rest ~datum
|
||||||
~describe ~seq ~optional ~rep ~once ~between
|
~describe ~seq ~optional ~rep ~once ~between
|
||||||
~! ~bind ~fail ~parse ~peek)
|
~! ~bind ~fail ~parse ~peek ~peek-not)
|
||||||
[S-pattern
|
[S-pattern
|
||||||
pvar-id
|
pvar-id
|
||||||
pvar-id:syntax-class-id
|
pvar-id:syntax-class-id
|
||||||
|
@ -77,6 +77,7 @@ means specifically @tech{@Spattern}.
|
||||||
(@#,ref[~commit h] H-pattern)
|
(@#,ref[~commit h] H-pattern)
|
||||||
(@#,ref[~delimit-cut h] H-pattern)
|
(@#,ref[~delimit-cut h] H-pattern)
|
||||||
(~peek H-pattern)
|
(~peek H-pattern)
|
||||||
|
(~peek-not H-pattern)
|
||||||
proper-S-pattern]
|
proper-S-pattern]
|
||||||
[EH-pattern
|
[EH-pattern
|
||||||
(@#,ref[~or eh] EH-pattern ...)
|
(@#,ref[~or eh] EH-pattern ...)
|
||||||
|
@ -733,6 +734,25 @@ a sequence.
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@specsubform[(@#,defhere[~peek-not] H-pattern)]{
|
||||||
|
|
||||||
|
Like @racket[~peek], but succeeds if the subpattern fails and fails if
|
||||||
|
the subpattern succeeds. On success, the @racket[~peek-not] resets the
|
||||||
|
matching position, so the pattern consumes no input. Used to look
|
||||||
|
ahead in a sequence. None of the subpattern's attributes are bound
|
||||||
|
outside of the @scheme[~peek-not]-pattern.
|
||||||
|
|
||||||
|
@myexamples[
|
||||||
|
(define-splicing-syntax-class final (code:comment "final term")
|
||||||
|
(pattern (~seq x (~peek-not _))))
|
||||||
|
|
||||||
|
(syntax-parse #'(a b c)
|
||||||
|
[((~or f:final o:other) ...)
|
||||||
|
(printf "finals are ~s\n" (syntax->datum #'(f.x ...)))
|
||||||
|
(printf "others are ~s\n" (syntax->datum #'(o ...)))])
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
@specsubform[S-pattern]{
|
@specsubform[S-pattern]{
|
||||||
|
|
||||||
Matches a sequence of one element, which must be a term matching
|
Matches a sequence of one element, which must be a term matching
|
||||||
|
|
Loading…
Reference in New Issue
Block a user