The check-bnf Reference Manual

Table of Contents

Next: , Previous: , Up: (dir)   [Contents][Index]

The check-bnf Reference Manual

This is the check-bnf Reference Manual, version 6.5.3, generated automatically by Declt version 3.0 "Montgomery Scott" on Fri Jun 26 09:58:46 2020 GMT+0.


Next: , Previous: , Up: Top   [Contents][Index]

1 Introduction

CHECK-BNF 6.5.3

What is this?

Macro arguments checker.

Current lisp world

Common Lisp has true macro. Writing macro means extending compiler i.e. creating new language.

Issues

Lack of documentations. Do you want to use LANGUAGE which has no documentation nor BNF?

Proposal

Check-bnf provides bnf like syntax checker.

It allows you to write macro arguments definition.

It helps the third person to understand your macro.

Usage

(defmacro defun (&whole whole name lambda-list &body body)
  (check-bnf (:whole whole)
    ((name (or symbol setf-name))
     (setf-name ((eql setf) symbol)))
    ((lambda-list list)))
  (list* name lambda-list body))

(defun "name" () :dummy)
;; SYNTAX-ERROR
  Syntax-error in DEFUN

NAME      := [ SYMBOL | SETF-NAME ]
SETF-NAME := ((EQL SETF) SYMBOL)

but "name"

in (DEFUN "name" NIL :DUMMY)

For detail, see spec/check-bnf.lisp

From developer

Product's goal

License

MIT

Developed with

SBCL

Tested with

Installation


Next: , Previous: , Up: Top   [Contents][Index]

2 Systems

The main system appears first, followed by any subsystem dependency.


Previous: , Up: Systems   [Contents][Index]

2.1 check-bnf

Author

SATO Shinichi

License

MIT

Description

Macro arguments checker.

Version

6.5.3

Dependencies
Source

check-bnf.asd (file)

Component

check-bnf.lisp (file)


Next: , Previous: , Up: Top   [Contents][Index]

3 Files

Files are sorted by type and then listed depth-first from the systems components trees.


Previous: , Up: Files   [Contents][Index]

3.1 Lisp


Next: , Previous: , Up: Lisp files   [Contents][Index]

3.1.1 check-bnf.asd

Location

/home/quickref/quicklisp/dists/quicklisp/software/check-bnf-20200610-git/check-bnf.asd

Systems

check-bnf (system)


Previous: , Up: Lisp files   [Contents][Index]

3.1.2 check-bnf/check-bnf.lisp

Parent

check-bnf (system)

Location

check-bnf.lisp

Packages

check-bnf

Exported Definitions
Internal Definitions

Next: , Previous: , Up: Top   [Contents][Index]

4 Packages

Packages are listed by definition order.


Previous: , Up: Packages   [Contents][Index]

4.1 check-bnf

Source

check-bnf.lisp (file)

Use List

common-lisp

Exported Definitions
Internal Definitions

Next: , Previous: , Up: Top   [Contents][Index]

5 Definitions

Definitions are sorted by export status, category, package, and then by lexicographic order.


Next: , Previous: , Up: Definitions   [Contents][Index]

5.1 Exported definitions


Next: , Previous: , Up: Exported definitions   [Contents][Index]

5.1.1 Macros

Macro: check-bnf (&key (WHOLE WHOLE?)) &body DEF+

# CHECK-BNF

## Description:
Macro argument checker like CL:CHECK-TYPE.
In most simple case, its like CL:CHECK-TYPE.

“‘lisp
#?(let ((var ’symbol))
(check-bnf ()
((var symbol))))
=> NIL
“‘

“‘lisp
#?(let ((var "string"))
(check-bnf ()
((var symbol))))
:signals syntax-error
“‘
You can check some place at once.

“‘lisp
#?(let ((a ’symbol)
(b "string"))
(check-bnf ()
((a symbol))
((b string))))
=> NIL
“‘
When type-specifier is expanded to T,
Efficient code is generated.

“‘lisp
#?(check-bnf ()
((a t)))
:expanded-to (let ((check-bnf::*whole* nil))
(let ((check-bnf::*bnf* ’((a t))))
(labels ((a (a)
(declare (ignore a))
nil))
(a a))))
“‘

“‘lisp
#?(check-bnf ()
((a* t)))
:expanded-to (let ((check-bnf::*whole* nil))
(let ((check-bnf::*bnf* ’((a* t))))
(labels ((a* (a*)
(if (typep a* ’(and atom (not null)))
(syntax-error ’a* "Require LIST but ~S." a*) nil)))
(a* a*))))
“‘
Also it occur in OR form.

“‘lisp
#?(check-bnf ()
((a (or symbol t string))))
:expanded-to (let ((check-bnf::*whole* nil))
(let ((check-bnf::*bnf* ’((a (or symbol t string)))))
(labels ((a (a)
(declare (ignore a))
nil))
(a a))))
“‘

“‘lisp
#?(check-bnf ()
((a (or symbol b string))
(b t)))
:expanded-to (let ((check-bnf::*whole* nil))
(let ((check-bnf::*bnf* ’((a (or symbol b string))
(b t))))
(labels ((a (a)
(declare (ignore a))
nil)
(b (b)
(declare (ignore b))
nil))
(a a))))
“‘

“‘lisp
#?(check-bnf ()
((a (or b c))
(b integer)
(c t)))
:expanded-to (let ((check-bnf::*whole* nil))
(let ((check-bnf::*bnf* ’((a (or b c))
(b integer)
(c t))))
(labels ((a (a)
(declare (ignore a))
nil)
(b (b)
(unless (typep b ’integer)
(syntax-error ’b "but ~S, it is type-of ~S"
b (type-of b))))
(c (c)
(declare (ignore c))
nil))
(a a))))
“‘
When you know VAR is list, and it has 0 or more elt. (a.k.a. *)
You can write like below.

“‘lisp
#?(let ((var* nil))
(check-bnf ()
((var* symbol))))
=> NIL
“‘

“‘lisp
#?(let ((var* ’(symbol)))
(check-bnf ()
((var* symbol))))
=> NIL
“‘

“‘lisp
#?(let ((var* ’("string")))
(check-bnf ()
((var* symbol))))
:signals syntax-error
“‘

“‘lisp
#?(let ((var* :not-list))
(check-bnf ()
((var* symbol))))
:signals syntax-error
“‘
When expected T, efficient code is generated.

“‘lisp
#?(let ((option* ()))
(check-bnf:check-bnf ()
((option* keyword T))))
=> NIL
“‘
If you do not like names var as XXX*, you can specify alias.

“‘lisp
#?(let ((vars ’(symbol)))
(check-bnf ()
(((var* vars) symbol))))
=> NIL
“‘
e.g. specify for plist.

“‘lisp
#?(let ((var* ’(:key "value" :key2 "value2")))
(check-bnf ()
((var* keyword string))))
=> NIL
“‘

“‘lisp
#?(let ((var* ’(:key 2 :key2 "not integer")))
(check-bnf ()
((var* keyword integer))))
:signals syntax-error
“‘

“‘lisp
#?(let ((var* ’(:key 1 "not-key" 2)))
(check-bnf ()
((var* keyword integer))))
:signals syntax-error
“‘

“‘lisp
#?(let ((var* ’(not "ballanced" plist)))
(check-bnf ()
((var* keyword string))))
:signals syntax-error
“‘
e.g. specify for alist.

“‘lisp
#?(let ((var* ’((:key "value") (:key2 "value2"))))
(check-bnf ()
((var* (keyword string)))))
=> nil
“‘

“‘lisp
#?(let ((var* ’((:key "value") (:key2 :not-string))))
(check-bnf ()
((var* (keyword string)))))
:signals syntax-error
“‘

“‘lisp
#?(let ((var* ’((:key "value") (:not "ballanced" clause))))
(check-bnf ()
((var* (keyword string)))))
:signals syntax-error
“‘

“‘lisp
#?(let ((var* ’((:key "value") (:not-ballanced))))
(check-bnf ()
((var* (keyword string)))))
:signals syntax-error
“‘
of course dotted are valid.

“‘lisp
#?(let ((var* ’((:key . "value"))))
(check-bnf ()
((var* (keyword . string)))))
=> nil
“‘
when you know var is list, and it has 1 or more elt, (a.k.a. +)
you can write like below.

“‘lisp
#?(let ((var+ ’(1)))
(check-bnf ()
((var+ integer))))
=> nil
“‘

“‘lisp
#?(let ((var+ ’()))
(check-bnf ()
((var+ integer))))
:signals syntax-error
“‘

“‘lisp
#?(let ((var+ ’("not-integer")))
(check-bnf ()
((var+ integer))))
:signals syntax-error
“‘

“‘lisp
#?(let ((var+ :not-cons))
(check-bnf ()
((var+ integer))))
:signals syntax-error
“‘

### syntax
(check-bnf (&key ((:whole whole?))) &rest def+)
=> result

## arguments and values:
whole := form, evaluated.

“‘lisp
#?(check-bnf (:whole no-such-var)
((dummy dummy)))
:signals (or error
warning ; for ccl
)
“‘
expects var for &whole.
when specified, header and footer is generated in error message.
note! clisp specific bug(?).
i do not know why but clisp does not call specified report function.
so header and footer is not generated.
after bug is removed, guard below will be failed.
def := (clause+)+
clause := (var-spec spec+)
var-spec := [ name | (name name) ]
name := symbol, otherwise error.

“‘lisp
#?(check-bnf ()
(("not-symbol" dummy)))
:signals syntax-error
, :lazy
“‘
not evaluated.

“‘lisp
#?(check-bnf ()
(((intern "not evaluated") dummy)))
:signals syntax-error
, :lazy
“‘
clause require one or more, otherwise syntax error.

“‘lisp
#?(check-bnf ())
:signals syntax-error
, :lazy
“‘
spec := [ type-specifier | bnf ]
bnf := [ name | list-bnf | or-form ]
list-bnf := (spec+)
or-form := (or spec+)
spec require one or more, otherwise error.

“‘lisp
#?(check-bnf ()
((dummy)))
:signals syntax-error
, :lazy
“‘

“‘lisp
#?(check-bnf ()
((dummy+ nil)))
:signals syntax-error
, :lazy
“‘
result := null

## affected by:
none

## side-effects:
none

## notes:
to check optional argument (e.g. &optional or &key), you can write like below.

“‘lisp
#?(let ((option))
(check-bnf ()
((option (or null symbol)))))
=> nil
“‘

“‘lisp
#?(let ((option ’symbol))
(check-bnf ()
((option (or null symbol)))))
=> nil
“‘

“‘lisp
#?(let ((option "not-symbol"))
(check-bnf ()
((option (or null symbol)))))
:signals syntax-error
“‘

“‘lisp
#?(let ((function-name "not function-name"))
(check-bnf ()
((function-name (or name setf-name))
(name symbol)
(setf-name ((eql setf) name)))))
:signals syntax-error
“‘
to check optional value in list, you can write like below.

“‘lisp
#?(let ((args ’(option and others)))
(check-bnf ()
((args (option? other*))
(option? (eql option))
(other* symbol))))
=> nil
“‘

“‘lisp
#?(let ((args ’(and others)))
(check-bnf ()
((args (option? other*))
(option? (eql option))
(other* symbol))))
=> nil
“‘

“‘lisp
#?(let ((args ’("not option nor other*" and others)))
(check-bnf ()
((args (option? other*))
(option? (eql option))
(other* symbol))))
:signals syntax-error
“‘

## exceptional-situations:
every name should not conflicts cl symbol.

“‘lisp
#?(let ((list nil))
(check-bnf ()
((list list))))
=> unspecified
“‘

## example.

“‘lisp
#?(let ((var ’(symbol symbol)))
(check-bnf ()
((var (symbol symbol option*))
(option* keyword string))))
=> nil
“‘

“‘lisp
#?(let ((var ’(symbol symbol)))
(check-bnf ()
((var (symbol symbol option?))
(option? keyword))))
=> nil
“‘

“‘lisp
#?(let ((var ’(symbol symbol)))
(check-bnf ()
((var (symbol symbol required))
(required keyword))))
:signals syntax-error
“‘

#### right side xxx*

“‘lisp
#?(let ((var ’(symbol)))
(check-bnf ()
((var (or string name*))
(name symbol))))
=> nil
“‘

“‘lisp
#?(let ((var "string"))
(check-bnf ()
((var (or string name*))
(name symbol))))
=> nil
“‘

“‘lisp
#?(let ((var ()))
(check-bnf ()
((var (or string name*))
(name symbol))))
=> nil
“‘

“‘lisp
#?(let ((var :not-list))
(check-bnf ()
((var (or string name*))
(name symbol))))
:signals syntax-error
“‘

“‘lisp
#?(let ((var ’("string" "list")))
(check-bnf ()
((var (or string name*))
(name symbol))))
:signals syntax-error
“‘

#### right side xxx?

“‘lisp
#?(let ((ll nil))
(check-bnf ()
((ll (var?))
(var symbol))))
=> nil
“‘

“‘lisp
#?(let ((ll ’(var)))
(check-bnf ()
((ll (var?))
(var symbol))))
=> nil
“‘

“‘lisp
#?(let ((ll ’(var too much)))
(check-bnf ()
((ll (var?))
(var symbol))))
:signals syntax-error
“‘

“‘lisp
#?(let ((ll "not symbol"))
(check-bnf ()
((ll (var?))
(var symbol))))
:signals syntax-error
“‘

Package

check-bnf

Source

check-bnf.lisp (file)


Next: , Previous: , Up: Exported definitions   [Contents][Index]

5.1.2 Functions

Function: syntax-error NAME FORMAT-CONTROL &rest FORMAT-ARGUMENTS
Package

check-bnf

Source

check-bnf.lisp (file)


Next: , Previous: , Up: Exported definitions   [Contents][Index]

5.1.3 Conditions

Condition: syntax-error ()
Package

check-bnf

Source

check-bnf.lisp (file)

Direct superclasses
  • cell-error (condition)
  • simple-error (condition)
  • program-error (condition)
Direct methods
Direct slots
Slot: whole
Initargs

:whole

Initform

(quote nil)

Readers

whole-form<=syntax-error (generic function)

Slot: definitions
Initargs

:definitions

Initform

(quote nil)

Readers

bnf-definitions (generic function)

Direct Default Initargs
InitargValue
:format-control""

Previous: , Up: Exported definitions   [Contents][Index]

5.1.4 Types

Type: expression ()

# EXPRESSION

## description:

## compound type specifier kind:

## compound type specifier syntax:

## compound type specifier arguments:

## compound type specifier description:

Package

check-bnf

Source

check-bnf.lisp (file)


Previous: , Up: Definitions   [Contents][Index]

5.2 Internal definitions


Next: , Previous: , Up: Internal definitions   [Contents][Index]

5.2.1 Special variables

Special Variable: *bnf*
Package

check-bnf

Source

check-bnf.lisp (file)

Special Variable: *whole*
Package

check-bnf

Source

check-bnf.lisp (file)


Next: , Previous: , Up: Internal definitions   [Contents][Index]

5.2.2 Functions

Function: *-checker NAME CONT
Package

check-bnf

Source

check-bnf.lisp (file)

Function: +-checker NAME CONT
Package

check-bnf

Source

check-bnf.lisp (file)

Function: <*form-body> NAME SPEC+
Package

check-bnf

Source

check-bnf.lisp (file)

Function: <*form> NAME SPEC+
Package

check-bnf

Source

check-bnf.lisp (file)

Function: <+form> NAME SPEC+
Package

check-bnf

Source

check-bnf.lisp (file)

Function: <check-type-form> NAME VAR TYPE-SPECIFIER
Package

check-bnf

Source

check-bnf.lisp (file)

Function: <local-atom-check-form> NAME VAR SPEC
Package

check-bnf

Source

check-bnf.lisp (file)

Function: <local-check-form> NAME VAR SPEC
Package

check-bnf

Source

check-bnf.lisp (file)

Function: <local-cons-check-form> NAME VAR SPEC
Package

check-bnf

Source

check-bnf.lisp (file)

Function: <local-fun> CLAUSE
Package

check-bnf

Source

check-bnf.lisp (file)

Function: <local-or-check-form> NAME VAR SPEC
Package

check-bnf

Source

check-bnf.lisp (file)

Function: <local-type-check-form> NAME VAR SPEC
Package

check-bnf

Source

check-bnf.lisp (file)

Function: <require-form> NAME SPEC+
Package

check-bnf

Source

check-bnf.lisp (file)

Function: <spec-form> SPEC NAME
Package

check-bnf

Source

check-bnf.lisp (file)

Function: but-extended-marker THING
Package

check-bnf

Source

check-bnf.lisp (file)

Function: cons-equal LIST1 LIST2
Package

check-bnf

Source

check-bnf.lisp (file)

Function: definitions THING BNF
Package

check-bnf

Source

check-bnf.lisp (file)

Function: extended-marker NAME
Package

check-bnf

Source

check-bnf.lisp (file)

Function: format-definition DEFINITIONS
Package

check-bnf

Source

check-bnf.lisp (file)

Function: ignored ARG
Package

check-bnf

Source

check-bnf.lisp (file)

Function: local-check NAME SPEC
Package

check-bnf

Source

check-bnf.lisp (file)

Function: or-formatter FORM
Package

check-bnf

Source

check-bnf.lisp (file)

Function: pprint-check-bnf STREAM EXP

# PPRINT-CHECK-BNF

## description:

### syntax
(pprint-check-bnf stream exp)
=> result

## arguments and values:
stream :=
exp :=
result :=

## affected by:

## side-effects:

## notes:

## exceptional-situations:

## tests:

“‘lisp
#?(pprint-check-bnf nil ’(check-bnf))
:outputs "(CHECK-BNF)"
“‘

“‘lisp
#?(pprint-check-bnf nil ’(check-bnf nil))
:outputs "(CHECK-BNF ())"
“‘

“‘lisp
#?(pprint-check-bnf nil ’(check-bnf nil nil))
:outputs "(CHECK-BNF () ())"
“‘

“‘lisp
#?(pprint-check-bnf nil ’(check-bnf nil not-list))
=> unspecified
“‘
depending on implementation.

### [clisp say](https://clisp.sourceforge.io/impnotes.html#clpp)

### > the lisp pretty printer implementation is not perfect yet.

### so two tests below are ignored in clisp.

### fortunately this is just printing, not check-bnf feature itself.

Package

check-bnf

Source

check-bnf.lisp (file)

Function: t-p THING &optional *BNF*
Package

check-bnf

Source

check-bnf.lisp (file)


Next: , Previous: , Up: Internal definitions   [Contents][Index]

5.2.3 Generic functions

Generic Function: bnf-definitions CONDITION
Package

check-bnf

Methods
Method: bnf-definitions (CONDITION syntax-error)
Source

check-bnf.lisp (file)

Generic Function: whole-form<=syntax-error CONDITION
Package

check-bnf

Methods
Method: whole-form<=syntax-error (CONDITION syntax-error)
Source

check-bnf.lisp (file)


Previous: , Up: Internal definitions   [Contents][Index]

5.2.4 Types

Type: type-specifier ()
Package

check-bnf

Source

check-bnf.lisp (file)


Previous: , Up: Top   [Contents][Index]

Appendix A Indexes


Next: , Previous: , Up: Indexes   [Contents][Index]

A.1 Concepts

Jump to:   C   F   L  
Index Entry  Section

C
check-bnf.asd: The check-bnf․asd file
check-bnf/check-bnf.lisp: The check-bnf/check-bnf․lisp file

F
File, Lisp, check-bnf.asd: The check-bnf․asd file
File, Lisp, check-bnf/check-bnf.lisp: The check-bnf/check-bnf․lisp file

L
Lisp File, check-bnf.asd: The check-bnf․asd file
Lisp File, check-bnf/check-bnf.lisp: The check-bnf/check-bnf․lisp file

Jump to:   C   F   L  

Next: , Previous: , Up: Indexes   [Contents][Index]

A.2 Functions

Jump to:   *   +   <  
B   C   D   E   F   G   I   L   M   O   P   S   T   W  
Index Entry  Section

*
*-checker: Internal functions

+
+-checker: Internal functions

<
<*form-body>: Internal functions
<*form>: Internal functions
<+form>: Internal functions
<check-type-form>: Internal functions
<local-atom-check-form>: Internal functions
<local-check-form>: Internal functions
<local-cons-check-form>: Internal functions
<local-fun>: Internal functions
<local-or-check-form>: Internal functions
<local-type-check-form>: Internal functions
<require-form>: Internal functions
<spec-form>: Internal functions

B
bnf-definitions: Internal generic functions
bnf-definitions: Internal generic functions
but-extended-marker: Internal functions

C
check-bnf: Exported macros
cons-equal: Internal functions

D
definitions: Internal functions

E
extended-marker: Internal functions

F
format-definition: Internal functions
Function, *-checker: Internal functions
Function, +-checker: Internal functions
Function, <*form-body>: Internal functions
Function, <*form>: Internal functions
Function, <+form>: Internal functions
Function, <check-type-form>: Internal functions
Function, <local-atom-check-form>: Internal functions
Function, <local-check-form>: Internal functions
Function, <local-cons-check-form>: Internal functions
Function, <local-fun>: Internal functions
Function, <local-or-check-form>: Internal functions
Function, <local-type-check-form>: Internal functions
Function, <require-form>: Internal functions
Function, <spec-form>: Internal functions
Function, but-extended-marker: Internal functions
Function, cons-equal: Internal functions
Function, definitions: Internal functions
Function, extended-marker: Internal functions
Function, format-definition: Internal functions
Function, ignored: Internal functions
Function, local-check: Internal functions
Function, or-formatter: Internal functions
Function, pprint-check-bnf: Internal functions
Function, syntax-error: Exported functions
Function, t-p: Internal functions

G
Generic Function, bnf-definitions: Internal generic functions
Generic Function, whole-form<=syntax-error: Internal generic functions

I
ignored: Internal functions

L
local-check: Internal functions

M
Macro, check-bnf: Exported macros
Method, bnf-definitions: Internal generic functions
Method, whole-form<=syntax-error: Internal generic functions

O
or-formatter: Internal functions

P
pprint-check-bnf: Internal functions

S
syntax-error: Exported functions

T
t-p: Internal functions

W
whole-form<=syntax-error: Internal generic functions
whole-form<=syntax-error: Internal generic functions

Jump to:   *   +   <  
B   C   D   E   F   G   I   L   M   O   P   S   T   W  

Next: , Previous: , Up: Indexes   [Contents][Index]

A.3 Variables

Jump to:   *  
D   S   W  
Index Entry  Section

*
*bnf*: Internal special variables
*whole*: Internal special variables

D
definitions: Exported conditions

S
Slot, definitions: Exported conditions
Slot, whole: Exported conditions
Special Variable, *bnf*: Internal special variables
Special Variable, *whole*: Internal special variables

W
whole: Exported conditions

Jump to:   *  
D   S   W  

Previous: , Up: Indexes   [Contents][Index]

A.4 Data types

Jump to:   C   E   P   S   T  
Index Entry  Section

C
check-bnf: The check-bnf system
check-bnf: The check-bnf package
Condition, syntax-error: Exported conditions

E
expression: Exported types

P
Package, check-bnf: The check-bnf package

S
syntax-error: Exported conditions
System, check-bnf: The check-bnf system

T
Type, expression: Exported types
Type, type-specifier: Internal types
type-specifier: Internal types

Jump to:   C   E   P   S   T