
Patterns (aka grammars) can be specified textually and then compiled with:

    pattern = esrapy.compile(textSpec)

[Note textSpec here is the definition of a pattern, not the text you
will eventually parse with that pattern.
To parse a Source text using a textual Pattern specification would be:
parsed = esrapy.compile(textSpec).match(sourceText)]

The text spec is a series of definitions of the form "name = pattern" where
name is any alphanumeric name (underscores ok), and pattern is any of
those defined below.  The name must be at the begining of the line -- no
indentation is allowed.  Indented lines are treated as continuations of
the previous definition (no '\' needed or allowed).  Blank lines are ignored
as is anything after a "#".  See examples/esrapy.pat for a sample Pattern
specification, which also happens to describe the syntax of Patterns (i.e.,
esrapy.pat parses itself).  See also calc.py and calc*.pat for a series of
progressively richer ways of defining the same pattern.

A pattern can be one of:

    - The name of another pattern, as in: foo, where somewhere in the
        pattern file foo is defined as in: "foo = pattern...".

    - A literal string enclosed in '' or "", as in: "foo" or 'foo'

    - A python regular expression (see the 're' module) enclosed in
        <> or ``, as in: <[a-z]+> or `[a-z]+`.  A group may be selected
        as the value of this pattern (during parsing) with the '@' operator
        as in: <un-([a-z]+)>@1 .  The default group (if no @ is given) is 0,
        i.e. returning the entire matched string.

    - A sequence of patterns, as in: foo bar baz, or 'foo' bar <[baz]>.
        As such, the returned value during parsing will be a simple array
        of the values of each pattern in the sequence.  One may optionally
        label one or more items in the sequence, as in: a:foo b:bar c:<[baz]>.
        If only a single item is labeled and that label is "_", the labeled
        item will be returned directly as the value of the sequence (passthrough),
        with all other items discarded.  If multiple items are labeled (or a
        single item is labeled with any name other than "_"), the return value
        will be a dictionary of those labeled items, with any unlabeled items
        being discarded.  NOTE the returned dict is actually a subclass of dict
        called MetaDict (see esrapyMisc.py) which expresses all its entries as
        attributes so that, for instance, foo["bar"] can also be accessed simply
        as foo.bar.  See minicalc.py for an example.

    - A set of alternate patterns separated by "|", as in: foo | bar | baz.
        As such, the returned value is just the value of whichever pattern
        succeeds.  (The patterns will be tried in the order given, so the
        first takes priority, but due to backtracking even if the first
        matches it may not be the one ultimately selected.)  One may
        optionally label one or more items using ";" as in: a;foo|bar|c;baz.
        If a labeled item is selected, the return value will be a 2-tuple
        containing the label and the pattern value, as in: ('c', <baz-value>)
        Additionally, one may specify an integer precedence, which will apply
        to all successive items in the list.  This precedence has no direct
        affect, but rather enables one to elsewhere select only a subset
        matching or exceeding a given precedence, as in:

        set = 1,a; foo | 2; bar | 3,c; baz | d; zorp
        subset = set@3    # Equivalent to:  c; baz | d; zorp
        inUse = "yo" set@2 <[a-z]+>    # Random example of a subset mid-expression.

        This is most useful in cases such as binary operator precedence. See
        the minicalc.py example.

    - A repetition of a pattern, specified either by *, +, ?, {n} or {n, m},
        where {n, m} is the general form meaning from n to m sequential copies,
        {n} means n or more, and *, +, and ? correspond to {0}, {1}, and {0,1}
        respectively, as in:  foo+, or foo{2,3}, or <[a-z]+[ ]+>+ (note in the
        last case the first two +'s are part of the regular expression, while
        only the last is a repetition of the sort discussed here.) The return
        value will always be an array of pattern values, possibly empty if n==0.
        Optionally, one may specify a separating pattern which must fall inbetween
        instances of the primary pattern.  This is specified after a "/" and
        before the repetition, as in:  foo/bar+ -- which would match the following
        sequences:  foo,  foo bar foo,  foo bar foo bar foo, and so on.  The
        return value omits the separating pattern, so only the list of foo values
        is returned.  This is useful for the common case of, for instance,
        comma-separated lists:   params = varName/","* -- which would match the
        empty string as well as, e.g., "a", "a,b", "a,b,c", ...

    - A keyword to be inserted into the return stream with no effect on the
        parsing, specified with a leading "\", as in:  \key.   This is useful
        in various ways; to give one example:

        time = hour:int ":" minute:int | "noon" hour:\12 minute:\00

        (ACTUALLY, this example won't work because right now a key has to
         be an alpha name, but it would be trivial to allow ints or arbitrary
         strings; just haven't done that yet.)

    - A block of equally-indented lines, specified as ">> pattern", where
        pattern should be a pattern that begins with non-whitespace and
        ends at the end of a line or the end of the file.  This is mostly
        useful for the top level (only) of indentation-sensitive syntaxes.
    - A header line followed by an indented block, specified as
        "head >> pattern".   Here head would be a pattern matching
        something like the head of an 'if' or 'while' block, and both
        head and pattern should follow the same rules as for block
        patterns.  NOTE that default white space (SPACE) is incompatible
        with block/indent because it causes pattern to start with whitespace
        which is disallowed.

    - Any of the above enclosed in () for grouping purposes, as in:
        foo (bar | baz) zorp

In summary, by examples:

    foo bar baz  - a sequence of patterns, returns a list
    foo|bar|baz  - a set of alternates, returns one item
    foo*         - zero or more in a sequence, returns a list
    foo+         - one or more in a sequence, returns a list
    foo?         - zero or one (i.e., optional), returns a list
    foo{2,5}     - 2 to 5 in a sequence, returns a list
    foo/bar+     - one or more foo's in a sequence separated by bars; returns foos.
    foo/bar{5}   - 5 or more foo's in a sequence separated by bars; returns foos.
    \foo         - matches the empty string, returns a literal ("foo")
    "foo"        - A literal, returns itself (a string).
    'foo'        - ditto
    <foo>        - A regular expression, returns a string.
    `foo`        - ditto
    <f(oo)>@1    - matches the regular expression foo, returns the string "oo"
    `f(oo)`@1    - ditto
    a:foo b:bar  - like sequence foo bar, but returns dict {a:foo, b:bar}
    _:foo bar    - like sequence foo bar, but returns only foo (passthrough).
    a;foo|b;bar  - like the set foo|bar, but returns ("a", foo) or ("b", bar)
    1;foo|2;bar  - like the set foo|bar, but annotated with precedence...
    foo@5        - equivalent to the subset of foo with precedence >= 5.
    (foo|bar)baz - equivalent to: foo baz | bar baz
    >> foo       - a sequence of equally indented lines matching pattern foo
    foo >> bar   - line matching foo followed by indented block of bar lines
