<!-- this is the description of the pattern grammar in gauche, which I used as a starting point -->

<pre class="example">pat : <var>patvar</var>                       ;; anything, and binds pattern var
    | <b>_</b>                            ;; anything
    | ()                           ;; the empty list
    | #t                           ;; #t
    | #f                           ;; #f
    | <var>string</var>                       ;; a string
    | <var>number</var>                       ;; a number
    | <var>character</var>                    ;; a character
    | '<var>sexp</var>                        ;; an s-expression
    | '<var>symbol</var>                      ;; a symbol (special case of s-expr)
    | (<var>pat1</var> ... <var>patN</var>)              ;; list of n elements
    | (<var>pat1</var> ... <var>patN</var> . <var>patN+1</var>)     ;; list of n or more
    | (<var>pat1</var> ... <var>patN</var> <var>patN+1</var> ooo)   ;; list of n or more, each element
                                   ;;   of remainder must match <var>patN+1</var>
    | #(<var>pat1</var> ... <var>patN</var>)             ;; vector of n elements
    | #(<var>pat1</var> ... <var>patN</var> <var>patN+1</var> ooo)  ;; vector of n or more, each element
                                   ;;   of remainder must match <var>patN+1</var>
    | (<b>$</b> <var>class</var> <var>pat1</var> ... <var>patN</var>)      ;; an object (<var>patK</var> matches in slot order)
    | (<b>struct</b> <var>class</var> <var>pat1</var> ... <var>patN</var>) ;; ditto (*)
    | (<b>@</b> <var>class</var> (<var>slot1</var> <var>pat1</var>) ...)   ;; an object (using slot names) (*)
    | (<b>object</b> <var>class</var> (<var>slot1</var> <var>pat1</var>) ...) ;; ditto (*)
    | (<b>=</b> <var>proc</var> <var>pat</var>)                 ;; apply proc, match the result to pat
    | (<b>and</b> <var>pat</var> ...)                ;; if all of pats match
    | (<b>or</b> <var>pat</var> ...)                 ;; if any of pats match
    | (<b>not</b> <var>pat</var> ...)                ;; if all pats don't match at all
    | (<b>?</b> <var>predicate</var> <var>pat</var> ...)        ;; if predicate true and all pats match
    | (<b>set!</b> <var>patvar</var>)                ;; anything, and binds setter
    | (<b>get!</b> <var>patvar</var>)                ;; anything, and binds getter
    | `qp                          ;; a quasi-pattern

patvar : a symbol except <b>_</b>, <b>quote</b>, <b>$</b>, <b>struct</b>, <b>@</b>, <b>object</b>, <b>=</b>, <b>and</b>, <b>or</b>,
         <b>not</b>, <b>?</b>, <b>set!</b>, <b>get!</b>, <b>quasiquote</b>, <b>...</b>, <b>___</b>, <b>..<i>k</i></b>, <b>__<i>k</i></b>.

ooo : <b>...</b>                          ;; zero or more
    | <b>___</b>                          ;; zero or more
    | <b>..<i>k</i></b>                          ;; <i>k</i> or more, where <i>k</i> is an integer.
                                   ;;   Example: <b>..1</b>, <b>..2</b> ...
    | <b>__<i>k</i></b>                          ;; <i>k</i> or more, where <i>k</i> is an integer.
                                   ;;   Example: <b>__1</b>, <b>__2</b> ...

</pre>
