removed BUILD from parse stage
$fh->getpos not in use
captured_endpoint was not used
Changing to undef $lines

This removes the unneeded string compare for $lines ne ''
combining line split with the replace

This eliminates an unneeded match for \n since if you performed a
replace then a split is needed, otherwise it isn't.
Changing the way comment is parsed

This converts it from a regcomp/match to a pure match.
Filehandle now properly passed through recursion
Simpler parent and root

I've spent a while trying different alternatives and finally gotten to
the point where I just removed root and made it a part of the new()
methods.

You could simplify it to be

if ($self->parent->root) {
   return $self->parent->root;
} else {
   return $self;
}

but because _build_root is then recursively called, it seems to chew on
it a bunch.

It could still be better than it is now (2µs/call) but it's much better
than it was, and it's consistant across object types.  In theory this
saved us 5 seconds.  In reality, the runtime seems the same.. so it
looks like it was magical seconds that didn't matter .. or a place the
profiler was slow when the real code is a bit quicker.

It might get better if we removed the Moose bit and made it a sub root
{} instead, but I'm tired of hacking this bit tonight.