Handle bond symbols in a ring closure

A ring closure label can be preceded with a  bond symbol
to specify the bond type to use to close the ring. When a
pair of ring closures is found we need to make sure the
bond symbols associated with each are matching...

a) if both ring closures in the pair specified no bond type
(i.e., Default is implied), then close the ring with a Default bond

b) if one has a bond specified and the other does not then
close the ring with the type of the bond specified

c) if both ring closures in the pair have a bond type
specified then they must be the same.

UserState throws an exception if it finds a pair of ring
closure with mis-matching bond types. The exception is
caught in top-level 'psmiles' parser and returned as a
parser error.

This meant going to the low level API for
this parser to catch the exception. A parser
(Parser<'TResult, 'TUserState>) is actually a function which
takes a CharStream<'TUserState> and returns a Reply<'TResult>.
In the low level API you create the parser as a function with this
signature.

Also, notice the use of the .>>.? operator in the ring closure parser
to combine the bond parser with the closure label parsers. Imagine
a bond symbol not preceding a ring closure, but between two atoms,
e.g., C=C. In the case the ring closure parser would successfully parse
the bond symbol but then fail as the following characters in the stream
aren't a ring closure label. When this happens the .>>.? operator
causes the ring closure label to backtrack so the bond symbol will
then be parsed as a normal bond between two atoms.