Allow symbols to be overwritten by the environment
This introduces a change to both the grammar and the parsing
environment that allows people to override start/end symbols in the
grammar through the environment. This finally brings the parser on
the same level as the old parser and lexer when it comes to handling
those customizations.
This means that the grammar must be compiled dynamically to account
for these customizations per environment. A module-level LRU cache
has been implemented to handle this fact, so grammars can be cached
instead of compiled every time. This should handle most cases other
than the unit tests, since most people aren't frequently changing up
their environment within their applications.
This also adds proper handling to the closing line block statement
so it waits for the end of a line or the end of the expression.