Fold the tokens into a tree. Strict about nesting only where it can be: an end tag closes the nearest matching open element and is ignored when nothing matches, so a stray </b> cannot truncate the document.
The flat token stream: start tags with attributes, end tags, and text. Tag soup is salvaged, never rejected. Use parse for a tree; callers that need HTML's implied end tags fold the tokens themselves.