1#lang scribble/doc 2@(require scribble/manual "utils.rkt" scribble/bnf 3 ;; "utils.rkt" provides scribble/bnf for-label 4 ) 5 6@title[#:tag "bnf"]{BNF Grammars} 7 8@defmodule[scribble/bnf]{The @racket[scribble/bnf] library 9provides utilities for typesetting grammars.} 10 11For example, 12 13@verbatim[#:indent 2]|{ 14@(let ([open @litchar{(}] 15 [close @litchar{)}]) 16 @BNF[(list @nonterm{expr} 17 @nonterm{id} 18 @BNF-seq[open @kleeneplus[@nonterm{expr}] close] 19 @BNF-seq[open @litchar{lambda} 20 open @kleenestar[@nonterm{id}] close 21 @nonterm{expr} close] 22 @nonterm{val}) 23 (list @nonterm{val} 24 @BNF-alt[@nonterm{number} @nonterm{primop}]) 25 (list @nonterm{id} 26 @elem{any name except for @litchar{lambda}})]) 27}| 28 29produces the output 30 31@(let ([open @litchar{(}] 32 [close @litchar{)}]) 33 @BNF[(list @nonterm{expr} 34 @nonterm{id} 35 @BNF-seq[open @kleeneplus[@nonterm{expr}] close] 36 @BNF-seq[open @litchar{lambda} 37 open @kleenestar[@nonterm{id}] close 38 @nonterm{expr} close] 39 @nonterm{val}) 40 (list @nonterm{val} 41 @BNF-alt[@nonterm{number} @nonterm{primop}]) 42 (list @nonterm{id} 43 @elem{any name except for @litchar{lambda}})]) 44 45See also @racket[racketgrammar]. 46 47@defproc[(BNF [prod (cons/c (or/c block? content?) 48 (non-empty-listof (or/c block? content?)))] 49 ...) 50 table?]{ 51 52Typesets a grammar table. Each production starts with an element 53(typically constructed with @racket[nonterm]) for the non-terminal 54being defined, and then a list of possibilities (typically constructed 55with @racket[BNF-seq], etc.) to show on separate lines.} 56 57@defproc[(nonterm [pre-content pre-content?] ...) element?]{ 58 59Typesets a non-terminal: italic in angle brackets.} 60 61@defproc[(BNF-seq [elem content?] ...) (or/c element? "")]{ 62 63Typesets a sequence.} 64 65@defproc[(BNF-seq-lines [elems (listof content?)] ...) block?]{ 66 67Typesets a sequence that is broken into multiple lines, where each 68@racket[elems] is one line.} 69 70@defproc[(BNF-group [pre-content pre-content?] ...) element?]{ 71 72Typesets a group surrounded by curly braces (so the entire group can 73be repeated, for example).} 74 75@defproc[(optional [pre-content pre-content?] ...) element?]{ 76 77Typesets an optional element: in square brackets.} 78 79@defproc[(kleenestar [pre-content pre-content?] ...) element?]{ 80 81Typesets a 0-or-more repetition.} 82 83@defproc[(kleeneplus [pre-content pre-content?] ...) element?]{ 84 85Typesets a 1-or-more repetition.} 86 87@defproc[(kleenerange [n any/c] [m any/c] [pre-content pre-content?] ...) 88 element?]{ 89 90Typesets a @racket[n]-to-@racket[m] repetition. The @racket[n] and 91@racket[m] arguments are converted to a string using @racket[(format 92"~a" n)] and @racket[(format "~a" m)].} 93 94@defproc[(BNF-alt [elem element?] ...) element?]{ 95 96Typesets alternatives for a production's right-hand side to appear on 97a single line. The result is normally used as a single possibility in 98a production list for @racket[BNF].} 99 100@; BNF-alt/close is exported but undocumented. 101@; It looks like it produces a more densely packed version of 102@; BNF-alt, but I haven't confirmed this. 103 104@defthing[BNF-etc element?]{ 105 106An element to use for omitted productions or content. 107Renders as: @BNF-etc 108} 109 110 111