bnf

Concise Typed Racket syntax for declaring recursive data in BNF


Keywords
bnf, data, grammar, typed-racket

Documentation

Build Status bnf

Concise Typed Racket syntax for declaring data in BNF.

Install

raco pkg install bnf

Examples

Defining syntax of Ī»-calculus terms e with based type Number and meta-function fv computing its free variables:

#lang typed/racket/base
(require racket/match racket/set bnf)
(e . ::= . (Lam x e)
           (App e e)
           x
           Number)
(x . ::= . Symbol)

(: fv : e ā†’ (Setof x))
(define fv
  (match-lambda
    [(Lam x e*) (set-remove (fv e*) x)]
    [(App eā‚ eā‚‚) (set-union (fv eā‚) (fv eā‚‚))]
    [(? x? x) {set x}]
    [(? number?) {set}]))

(fv (App (Lam 'x (App 'x 'x)) (Lam 'y (App 'y 'y)))) ; ==> (set)
(fv (Lam 'x 'y)) ; ==> (set 'y)

You can specify existing type with identifiers or quoted datum, or [#:old Type]. In the example below, the macro would generate new struct Pairof without the #:old declaration.

#lang typed/racket/base
(require racket/match bnf)
(Tree . ::= . 'nil [#:old (Pairof Tree Tree)])

(: height : Tree ā†’ Natural)
(define height
  (match-lambda
    ['nil 0]
    [(cons l r) (+ 1 (max (height l) (height r)))]))

(height (cons (cons 'nil 'nil) 'nil)) ; ==> 2