rewrite the tap parser

this parser is line based, which should make the top level logic easier
to understand (although it does push some hairy stuff down to the bottom
that i still need to clean up). it also should be able to be easily
modified to work as a streaming parser, although i haven't tried to do
that yet.