Do not maintain an intermediate representation during parsing

Instead of an intermediate representation, we simply build up the DOM
structure immediately from the input text. This change improves both
speed and memory usage.

Previously, reading, parsing and outputting a 10MB file to /dev/null
would take 503 ms. With this change, it now takes 390 ms (77.7% of the
previous time). For reference, xmllint takes 306 ms (we are 127.4% of
xmllint).

For the same test, memory usage was previously 141MB and is now 87MB
(62% of the previous usage). Xmllint takes 79MB (we are 110% of
xmllint). Using a 100MB file instead, memory usage was previously
1331MB and is now 772MB (58% of the previous usage). Xmllint takes
750MB (we are 103% of xmllint).