Removed calls to Utils.cast() from Tuples and replaced them with non-dynamic casts.

This was shown to improve performance when profiling running the LRGenerator on large grammars.
Removed the use of Utils.cast from Production.equals() for performance reasons and replaced it with a static cast.
Optimized NullableFirstFollow.first(SymbolType) so that it avoids creating new sets and instead reuses a stored first set for a symbol type when possible.
Optimized the LR1Generator's implementation of closure() by avoiding reiterating over Items more than once (since processing an item always leads to the same set of produced items).

This was done after determining that closure() was a very time-consuming part of the algorithm's inner loop.