scribble/bnf: Add contracts & correct docs
This commit is contained in:
parent
58b270adba
commit
a2d2f0472f
|
@ -1,6 +1,7 @@
|
||||||
#lang scribble/doc
|
#lang scribble/doc
|
||||||
@(require scribble/manual "utils.rkt" scribble/bnf
|
@(require scribble/manual "utils.rkt" scribble/bnf
|
||||||
(for-label scribble/bnf))
|
;; "utils.rkt" provides scribble/bnf for-label
|
||||||
|
)
|
||||||
|
|
||||||
@title[#:tag "bnf"]{BNF Grammars}
|
@title[#:tag "bnf"]{BNF Grammars}
|
||||||
|
|
||||||
|
@ -43,44 +44,48 @@ produces the output
|
||||||
|
|
||||||
See also @racket[racketgrammar].
|
See also @racket[racketgrammar].
|
||||||
|
|
||||||
@defproc[(BNF [prod (cons element? (listof (or/c block? element?)))] ...) table?]{
|
@defproc[(BNF [prod (cons/c (or/c block? content?)
|
||||||
|
(non-empty-listof (or/c block? content?)))]
|
||||||
|
...)
|
||||||
|
table?]{
|
||||||
|
|
||||||
Typesets a grammar table. Each production starts with an element
|
Typesets a grammar table. Each production starts with an element
|
||||||
(typically constructed with @racket[nonterm]) for the non-terminal
|
(typically constructed with @racket[nonterm]) for the non-terminal
|
||||||
being defined, and then a list of possibilities (typically constructed
|
being defined, and then a list of possibilities (typically constructed
|
||||||
with @racket[BNF-seq], etc.) to show on separate lines.}
|
with @racket[BNF-seq], etc.) to show on separate lines.}
|
||||||
|
|
||||||
@defproc[(nonterm (pre-content any/c) ...) element?]{
|
@defproc[(nonterm [pre-content pre-content?] ...) element?]{
|
||||||
|
|
||||||
Typesets a non-terminal: italic in angle brackets.}
|
Typesets a non-terminal: italic in angle brackets.}
|
||||||
|
|
||||||
@defproc[(BNF-seq [elem element?] ...) element?]{
|
@defproc[(BNF-seq [elem content?] ...) (or/c element? "")]{
|
||||||
|
|
||||||
Typesets a sequence.}
|
Typesets a sequence.}
|
||||||
|
|
||||||
@defproc[(BNF-seq-lines [elems (listof element?)] ...) block?]{
|
@defproc[(BNF-seq-lines [elems (listof content?)] ...) block?]{
|
||||||
|
|
||||||
Typesets a sequence that is broken into multiple lines, where each
|
Typesets a sequence that is broken into multiple lines, where each
|
||||||
@racket[elems] is one line.}
|
@racket[elems] is one line.}
|
||||||
|
|
||||||
@defproc[(BNF-group [pre-content any/c] ...) element?]{
|
@defproc[(BNF-group [pre-content pre-content?] ...) element?]{
|
||||||
|
|
||||||
Typesets a group surrounded by curly braces (so the entire group can
|
Typesets a group surrounded by curly braces (so the entire group can
|
||||||
be repeated, for example).}
|
be repeated, for example).}
|
||||||
|
|
||||||
@defproc[(optional [pre-content any/c] ...) element?]{
|
@defproc[(optional [pre-content pre-content?] ...) element?]{
|
||||||
|
|
||||||
Typesets an optional element: in square brackets.}
|
Typesets an optional element: in square brackets.}
|
||||||
|
|
||||||
@defproc[(kleenestar [pre-content any/c] ...) element?]{
|
@defproc[(kleenestar [pre-content pre-content?] ...) element?]{
|
||||||
|
|
||||||
Typesets a 0-or-more repetition.}
|
Typesets a 0-or-more repetition.}
|
||||||
|
|
||||||
@defproc[(kleeneplus [pre-content any/c] ...) element?]{
|
@defproc[(kleeneplus [pre-content pre-content?] ...) element?]{
|
||||||
|
|
||||||
Typesets a 1-or-more repetition.}
|
Typesets a 1-or-more repetition.}
|
||||||
|
|
||||||
@defproc[(kleenerange [n any/c] [m any/c] [pre-content any/c] ...) element?]{
|
@defproc[(kleenerange [n any/c] [m any/c] [pre-content pre-content?] ...)
|
||||||
|
element?]{
|
||||||
|
|
||||||
Typesets a @racket[n]-to-@racket[m] repetition. The @racket[n] and
|
Typesets a @racket[n]-to-@racket[m] repetition. The @racket[n] and
|
||||||
@racket[m] arguments are converted to a string using @racket[(format
|
@racket[m] arguments are converted to a string using @racket[(format
|
||||||
|
@ -92,6 +97,14 @@ Typesets alternatives for a production's right-hand side to appear on
|
||||||
a single line. The result is normally used as a single possibility in
|
a single line. The result is normally used as a single possibility in
|
||||||
a production list for @racket[BNF].}
|
a production list for @racket[BNF].}
|
||||||
|
|
||||||
@defthing[BNF-etc string?]{
|
@; BNF-alt/close is exported but undocumented.
|
||||||
|
@; It looks like it produces a more densely packed version of
|
||||||
|
@; BNF-alt, but I haven't confirmed this.
|
||||||
|
|
||||||
|
@defthing[BNF-etc element?]{
|
||||||
|
|
||||||
|
An element to use for omitted productions or content.
|
||||||
|
Renders as: @BNF-etc
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
A string to use for omitted productions or content.}
|
|
||||||
|
|
|
@ -1,18 +1,44 @@
|
||||||
(module bnf racket
|
(module bnf racket
|
||||||
(require "struct.rkt"
|
(require scribble/decode
|
||||||
"decode.rkt"
|
(except-in scribble/struct
|
||||||
(only-in "core.rkt"
|
element?)
|
||||||
|
(only-in scribble/core
|
||||||
|
content?
|
||||||
|
element?
|
||||||
make-style
|
make-style
|
||||||
make-table-columns)
|
make-table-columns)
|
||||||
mzlib/kw)
|
)
|
||||||
|
|
||||||
|
(provide (contract-out
|
||||||
|
[BNF (-> (cons/c (or/c block? content?)
|
||||||
|
(non-empty-listof (or/c block? content?)))
|
||||||
|
...
|
||||||
|
table?)]
|
||||||
|
[BNF-etc element?]
|
||||||
|
;; operate on content
|
||||||
|
[BNF-seq (-> content? ...
|
||||||
|
(or/c element? ""))]
|
||||||
|
[BNF-seq-lines (-> (listof content?) ...
|
||||||
|
block?)]
|
||||||
|
[BNF-alt (-> content? ...
|
||||||
|
element?)]
|
||||||
|
[BNF-alt/close (-> content? ...
|
||||||
|
element?)]
|
||||||
|
;; operate on pre-content
|
||||||
|
[BNF-group (-> pre-content? ...
|
||||||
|
element?)]
|
||||||
|
[nonterm (-> pre-content? ...
|
||||||
|
element?)]
|
||||||
|
[optional (-> pre-content? ...
|
||||||
|
element?)]
|
||||||
|
[kleenestar (-> pre-content? ...
|
||||||
|
element?)]
|
||||||
|
[kleeneplus (-> pre-content? ...
|
||||||
|
element?)]
|
||||||
|
[kleenerange (-> any/c any/c pre-content? ...
|
||||||
|
element?)]
|
||||||
|
))
|
||||||
|
|
||||||
(provide BNF
|
|
||||||
nonterm
|
|
||||||
BNF-seq BNF-seq-lines
|
|
||||||
BNF-alt BNF-alt/close ; single-line alternatives
|
|
||||||
BNF-etc
|
|
||||||
BNF-group
|
|
||||||
optional kleenestar kleeneplus kleenerange)
|
|
||||||
|
|
||||||
(define spacer (make-element 'hspace (list " ")))
|
(define spacer (make-element 'hspace (list " ")))
|
||||||
(define equals (make-element 'tt (list spacer "::=" spacer)))
|
(define equals (make-element 'tt (list spacer "::=" spacer)))
|
||||||
|
@ -33,14 +59,16 @@
|
||||||
(list baseline baseline baseline baseline))))
|
(list baseline baseline baseline baseline))))
|
||||||
(apply
|
(apply
|
||||||
append
|
append
|
||||||
(map (lambda (defn)
|
(map (match-lambda
|
||||||
|
[(cons lhs (cons rhs0 more-rhs))
|
||||||
(cons
|
(cons
|
||||||
(list (as-flow spacer) (as-flow (car defn)) (as-flow equals) (as-flow (cadr defn)))
|
(list (as-flow spacer) (as-flow lhs) (as-flow equals) (as-flow rhs0))
|
||||||
(map (lambda (i)
|
(map (lambda (i)
|
||||||
(list (as-flow spacer) (as-flow " ") (as-flow alt) (as-flow i)))
|
(list (as-flow spacer) (as-flow " ") (as-flow alt) (as-flow i)))
|
||||||
(cddr defn))))
|
more-rhs))])
|
||||||
defns))))
|
defns))))
|
||||||
|
|
||||||
|
;; interleave : (listof content?) element? -> element?
|
||||||
(define (interleave l spacer)
|
(define (interleave l spacer)
|
||||||
(make-element #f (cons (car l)
|
(make-element #f (cons (car l)
|
||||||
(apply append
|
(apply append
|
||||||
|
@ -65,28 +93,28 @@
|
||||||
|
|
||||||
(define BNF-etc (make-element 'roman "..."))
|
(define BNF-etc (make-element 'roman "..."))
|
||||||
|
|
||||||
(define/kw (nonterm #:body s)
|
(define (nonterm . s)
|
||||||
(make-element 'roman (append (list 'lang)
|
(make-element 'roman (append (list 'lang)
|
||||||
(list (make-element 'italic (decode-content s)))
|
(list (make-element 'italic (decode-content s)))
|
||||||
(list 'rang))))
|
(list 'rang))))
|
||||||
|
|
||||||
(define/kw (optional #:body s)
|
(define (optional . s)
|
||||||
(make-element #f (append (list (make-element 'roman "["))
|
(make-element #f (append (list (make-element 'roman "["))
|
||||||
(decode-content s)
|
(decode-content s)
|
||||||
(list (make-element 'roman "]")))))
|
(list (make-element 'roman "]")))))
|
||||||
|
|
||||||
(define/kw (BNF-group #:body s)
|
(define (BNF-group . s)
|
||||||
(make-element #f (append (list (make-element 'roman "{"))
|
(make-element #f (append (list (make-element 'roman "{"))
|
||||||
(list (apply BNF-seq (decode-content s)))
|
(list (apply BNF-seq (decode-content s)))
|
||||||
(list (make-element 'roman "}")))))
|
(list (make-element 'roman "}")))))
|
||||||
|
|
||||||
(define/kw (kleenestar #:body s)
|
(define (kleenestar . s)
|
||||||
(make-element #f (append (decode-content s) (list (make-element 'roman "*")))))
|
(make-element #f (append (decode-content s) (list (make-element 'roman "*")))))
|
||||||
|
|
||||||
(define/kw (kleeneplus #:body s)
|
(define (kleeneplus . s)
|
||||||
(make-element #f (append (decode-content s) (list (make-element 'superscript (list "+"))))))
|
(make-element #f (append (decode-content s) (list (make-element 'superscript (list "+"))))))
|
||||||
|
|
||||||
(define/kw (kleenerange a b #:body s)
|
(define (kleenerange a b . s)
|
||||||
(make-element #f (append (decode-content s)
|
(make-element #f (append (decode-content s)
|
||||||
(list (make-element 'roman
|
(list (make-element 'roman
|
||||||
(make-element 'superscript
|
(make-element 'superscript
|
||||||
|
|
Loading…
Reference in New Issue
Block a user