Each entry in the
AbTab symbol table is an
AbSym instance. We use the term binding for the connection between a code and its
When a symbol table entry is initially created, it is said to be unbound. That is, we know the bird code but not what it stands for.
If we encounter a definition for an unbound symbol, we set its
.binding attribute to an instance of one of the
subclasses of the
AbBind class that represents
If the code is related to a scientific name, we use a
StdBind instance. See Section 27, “
class StdBind: Code bound to a
If the code is a direct equivalent of another code, we use
EqBind instance. See Section 28, “
class EqBind: Code equivalent to another
If the code is a collision form, it is bound to
the code as a
see Section 29, “
class CollBind: Cluster of colliding
So, what happens if we encounter a new definition of an existing code? For the first two cases above, it is an error: one cannot relate a code to two different taxa or relate it to two direct equivalents.
CollBind instance is a container for
all the different related disambiguated codes.
These three cases are handled by the
method of the concrete subclass of
This method will fail if the new binding is incompatible
with the old binding. In the case where a new collision
is added to an existing
.combine() method will succeed.
Here is the class interface:
# - - - - - c l a s s A b S y m class AbSym(object): '''Represents one entry in the code symbol table. Exports: AbSym ( abbr ): [ abbr is a stripped, uppercased bird code -> return a new AbSym instance for abbr with no binding ] .abbr: [ as passed to constructor, read-only ] .binding: [ if self has no binding -> None else -> self's current binding as an AbBind instance ] .bind ( abBind ): [ abBind is an instance of AbBind -> if self's binding can be combined with abBind -> self := self with abBind added to its binding else -> raise ValueError ] '''