Attached Files |
-
libhubbub-test.diff (293,757 bytes) 2014-03-09 14:48
-
rewrite.diff (301,032 bytes) 2014-03-11 16:29
-
0001-Rewriting-whole-tokenizer-and-updating-its-tests.patch (255,232 bytes) 2014-03-11 17:00
From 668aa257611e13522f85e1527c495a75a5061f10 Mon Sep 17 00:00:00 2001
From: Achal-Aggarwal <theachalaggarwal@gmail.com>
Date: Mon, 10 Mar 2014 21:49:38 +0530
Subject: [PATCH 1/4] Rewriting whole tokenizer and updating its tests.
---
src/tokeniser/tokeniser.c | 598 +++---
test/data/tokeniser2/numericEntities.test | 188 +-
test/data/tokeniser2/regression.test | 4 +-
test/data/tokeniser2/test1.test | 28 +-
test/data/tokeniser2/test2.test | 24 +-
test/data/tokeniser2/test3.test | 3060 +++++++++++++++--------------
test/data/tokeniser2/test4.test | 79 +-
test/data/tokeniser2/unicodeChars.test | 8 -
test/testutils.h | 19 +
test/tokeniser2.c | 5 +-
10 files changed, 2096 insertions(+), 1917 deletions(-)
diff --git a/src/tokeniser/tokeniser.c b/src/tokeniser/tokeniser.c
index a7e67a1..3eab8a7 100644
--- a/src/tokeniser/tokeniser.c
+++ b/src/tokeniser/tokeniser.c
@@ -24,10 +24,10 @@
* Table of mappings between Windows-1252 codepoints 128-159 and UCS4
*/
static const uint32_t cp1252Table[32] = {
- 0x20AC, 0xFFFD, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
- 0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0xFFFD, 0x017D, 0xFFFD,
- 0xFFFD, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
- 0x02DC, 0x2122, 0x0161, 0x203A, 0x0153, 0xFFFD, 0x017E, 0x0178
+ 0x20AC, 0x0081, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
+ 0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0x008F, 0x017D, 0x0090,
+ 0x0090, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
+ 0x02DC, 0x2122, 0x0161, 0x203A, 0x0153, 0x009D, 0x017E, 0x0178
};
/**
@@ -71,6 +71,7 @@ typedef enum hubbub_tokeniser_state {
STATE_COMMENT,
STATE_COMMENT_END_DASH,
STATE_COMMENT_END,
+ STATE_COMMENT_END_BANG,
STATE_MATCH_DOCTYPE,
STATE_DOCTYPE,
STATE_BEFORE_DOCTYPE_NAME,
@@ -78,6 +79,7 @@ typedef enum hubbub_tokeniser_state {
STATE_AFTER_DOCTYPE_NAME,
STATE_MATCH_PUBLIC,
STATE_BEFORE_DOCTYPE_PUBLIC,
+ STATE_BEFORE_DOCTYPE_PUBLIC_IDENTIFIER,
STATE_DOCTYPE_PUBLIC_DQ,
STATE_DOCTYPE_PUBLIC_SQ,
STATE_AFTER_DOCTYPE_PUBLIC,
@@ -232,6 +234,8 @@ static hubbub_error hubbub_tokeniser_handle_after_doctype_name(
hubbub_tokeniser *tokeniser);
static hubbub_error hubbub_tokeniser_handle_match_public(
hubbub_tokeniser *tokeniser);
+static hubbub_error hubbub_tokeniser_handle_doctype_public_identifier(
+ hubbub_tokeniser *tokeniser);
static hubbub_error hubbub_tokeniser_handle_before_doctype_public(
hubbub_tokeniser *tokeniser);
static hubbub_error hubbub_tokeniser_handle_doctype_public_dq(
@@ -443,7 +447,7 @@ hubbub_error hubbub_tokeniser_run(hubbub_tokeniser *tokeniser)
if (tokeniser->paused == true)
return HUBBUB_PAUSED;
-#if 0
+#if 1
#define state(x) \
case x: \
printf( #x "\n");
@@ -528,6 +532,7 @@ hubbub_error hubbub_tokeniser_run(hubbub_tokeniser *tokeniser)
case STATE_COMMENT:
case STATE_COMMENT_END_DASH:
case STATE_COMMENT_END:
+ case STATE_COMMENT_END_BANG:
cont = hubbub_tokeniser_handle_comment(tokeniser);
break;
state(STATE_MATCH_DOCTYPE)
@@ -549,7 +554,6 @@ hubbub_error hubbub_tokeniser_run(hubbub_tokeniser *tokeniser)
cont = hubbub_tokeniser_handle_after_doctype_name(
tokeniser);
break;
-
state(STATE_MATCH_PUBLIC)
cont = hubbub_tokeniser_handle_match_public(
tokeniser);
@@ -558,6 +562,10 @@ hubbub_error hubbub_tokeniser_run(hubbub_tokeniser *tokeniser)
cont = hubbub_tokeniser_handle_before_doctype_public(
tokeniser);
break;
+ state(STATE_BEFORE_DOCTYPE_PUBLIC_IDENTIFIER)
+ cont = hubbub_tokeniser_handle_doctype_public_identifier(
+ tokeniser);
+ break;
state(STATE_DOCTYPE_PUBLIC_DQ)
cont = hubbub_tokeniser_handle_doctype_public_dq(
tokeniser);
@@ -655,7 +663,6 @@ hubbub_error hubbub_tokeniser_run(hubbub_tokeniser *tokeniser)
(str).len += (length); \
} while (0)
-
/* this should always be called with an empty "chars" buffer */
hubbub_error hubbub_tokeniser_handle_data(hubbub_tokeniser *tokeniser)
{
@@ -669,44 +676,12 @@ hubbub_error hubbub_tokeniser_handle_data(hubbub_tokeniser *tokeniser)
PARSERUTILS_OK) {
const uint8_t c = *cptr;
- if (c == '&' &&
- (tokeniser->content_model == HUBBUB_CONTENT_MODEL_PCDATA ||
- tokeniser->content_model == HUBBUB_CONTENT_MODEL_RCDATA) &&
- tokeniser->escape_flag == false) {
- tokeniser->state =
- STATE_CHARACTER_REFERENCE_DATA;
+ if (c == '&') {
+ tokeniser->state = STATE_CHARACTER_REFERENCE_DATA;
/* Don't eat the '&'; it'll be handled by entity
* consumption */
break;
- } else if (c == '-' &&
- tokeniser->escape_flag == false &&
- (tokeniser->content_model ==
- HUBBUB_CONTENT_MODEL_RCDATA ||
- tokeniser->content_model ==
- HUBBUB_CONTENT_MODEL_CDATA) &&
- tokeniser->context.pending >= 3) {
- size_t ignore;
- error = parserutils_inputstream_peek(
- tokeniser->input,
- tokeniser->context.pending - 3,
- &cptr,
- &ignore);
-
- assert(error == PARSERUTILS_OK);
-
- if (strncmp((char *)cptr,
- "<!--", SLEN("<!--")) == 0) {
- tokeniser->escape_flag = true;
- }
-
- tokeniser->context.pending += len;
- } else if (c == '<' && (tokeniser->content_model ==
- HUBBUB_CONTENT_MODEL_PCDATA ||
- ((tokeniser->content_model ==
- HUBBUB_CONTENT_MODEL_RCDATA ||
- tokeniser->content_model ==
- HUBBUB_CONTENT_MODEL_CDATA) &&
- tokeniser->escape_flag == false))) {
+ } else if (c == '<') {
if (tokeniser->context.pending > 0) {
/* Emit any pending characters */
emit_current_chars(tokeniser);
@@ -716,39 +691,6 @@ hubbub_error hubbub_tokeniser_handle_data(hubbub_tokeniser *tokeniser)
tokeniser->context.pending = len;
tokeniser->state = STATE_TAG_OPEN;
break;
- } else if (c == '>' && tokeniser->escape_flag == true &&
- (tokeniser->content_model ==
- HUBBUB_CONTENT_MODEL_RCDATA ||
- tokeniser->content_model ==
- HUBBUB_CONTENT_MODEL_CDATA)) {
- /* no need to check that there are enough characters,
- * since you can only run into this if the flag is
- * true in the first place, which requires four
- * characters. */
- error = parserutils_inputstream_peek(
- tokeniser->input,
- tokeniser->context.pending - 2,
- &cptr,
- &len);
-
- assert(error == PARSERUTILS_OK);
-
- if (strncmp((char *) cptr, "-->", SLEN("-->")) == 0) {
- tokeniser->escape_flag = false;
- }
-
- tokeniser->context.pending += len;
- } else if (c == '\0') {
- if (tokeniser->context.pending > 0) {
- /* Emit any pending characters */
- emit_current_chars(tokeniser);
- }
-
- /* Emit a replacement character */
- emit_character_token(tokeniser, &u_fffd_str);
-
- /* Advance past NUL */
- parserutils_inputstream_advance(tokeniser->input, 1);
} else if (c == '\r') {
error = parserutils_inputstream_peek(
tokeniser->input,
@@ -774,11 +716,14 @@ hubbub_error hubbub_tokeniser_handle_data(hubbub_tokeniser *tokeniser)
/* Advance over */
parserutils_inputstream_advance(tokeniser->input, 1);
} else {
+ if (c == '\0') {
+ /** \todo parse error */
+ }
+
/* Just collect into buffer */
tokeniser->context.pending += len;
}
}
-
if (tokeniser->state != STATE_TAG_OPEN &&
(tokeniser->state != STATE_DATA || error == PARSERUTILS_EOF) &&
tokeniser->context.pending > 0) {
@@ -879,7 +824,9 @@ hubbub_error hubbub_tokeniser_handle_tag_open(hubbub_tokeniser *tokeniser)
if (error != PARSERUTILS_OK) {
if (error == PARSERUTILS_EOF) {
- /* Return to data state with '<' still in "chars" */
+ /** \todo parse error */
+ /* Emit single '<' char */
+ emit_current_chars(tokeniser);
tokeniser->state = STATE_DATA;
return HUBBUB_OK;
} else {
@@ -889,65 +836,54 @@ hubbub_error hubbub_tokeniser_handle_tag_open(hubbub_tokeniser *tokeniser)
c = *cptr;
- if (c == '/') {
+ if (c == '!') {
+ parserutils_inputstream_advance(tokeniser->input, SLEN("<!"));
+
+ tokeniser->context.pending = 0;
+ tokeniser->state = STATE_MARKUP_DECLARATION_OPEN;
+ } else if (c == '/'){
tokeniser->context.pending += len;
tokeniser->context.close_tag_match.match = false;
tokeniser->context.close_tag_match.count = 0;
tokeniser->state = STATE_CLOSE_TAG_OPEN;
- } else if (tokeniser->content_model == HUBBUB_CONTENT_MODEL_RCDATA ||
- tokeniser->content_model ==
- HUBBUB_CONTENT_MODEL_CDATA) {
- /* Return to data state with '<' still in "chars" */
- tokeniser->state = STATE_DATA;
- } else if (tokeniser->content_model == HUBBUB_CONTENT_MODEL_PCDATA) {
- if (c == '!') {
- parserutils_inputstream_advance(tokeniser->input,
- SLEN("<!"));
-
- tokeniser->context.pending = 0;
- tokeniser->state = STATE_MARKUP_DECLARATION_OPEN;
- } else if ('A' <= c && c <= 'Z') {
- uint8_t lc = (c + 0x20);
-
- START_BUF(ctag->name, &lc, len);
- ctag->n_attributes = 0;
- tokeniser->context.current_tag_type =
- HUBBUB_TOKEN_START_TAG;
-
- tokeniser->context.pending += len;
+ } else if ('A' <= c && c <= 'Z') {
+ uint8_t lc = (c + 0x20);
- tokeniser->state = STATE_TAG_NAME;
- } else if ('a' <= c && c <= 'z') {
- START_BUF(ctag->name, cptr, len);
- ctag->n_attributes = 0;
- tokeniser->context.current_tag_type =
- HUBBUB_TOKEN_START_TAG;
+ START_BUF(ctag->name, &lc, len);
+ ctag->n_attributes = 0;
+ tokeniser->context.current_tag_type =
+ HUBBUB_TOKEN_START_TAG;
- tokeniser->context.pending += len;
+ tokeniser->context.pending += len;
- tokeniser->state = STATE_TAG_NAME;
- } else if (c == '>') {
- /** \todo parse error */
+ tokeniser->state = STATE_TAG_NAME;
+ } else if ('a' <= c && c <= 'z') {
+ START_BUF(ctag->name, cptr, len);
+ ctag->n_attributes = 0;
+ tokeniser->context.current_tag_type =
+ HUBBUB_TOKEN_START_TAG;
- tokeniser->context.pending += len;
- tokeniser->state = STATE_DATA;
- } else if (c == '?') {
- /** \todo parse error */
+ tokeniser->context.pending += len;
- /* Cursor still at "<", need to advance past it */
+ tokeniser->state = STATE_TAG_NAME;
+ } else if (c == '?'){
+ /** \todo parse error */
+ /* Cursor still at "<", need to advance past it */
parserutils_inputstream_advance(
tokeniser->input, SLEN("<"));
tokeniser->context.pending = 0;
tokeniser->state = STATE_BOGUS_COMMENT;
- } else {
- /* Return to data state with '<' still in "chars" */
- tokeniser->state = STATE_DATA;
- }
+ } else {
+ /** \todo parse error */
+ /* Emit single '<' char */
+ emit_current_chars(tokeniser);
+ tokeniser->state = STATE_DATA;
}
+
return HUBBUB_OK;
}
@@ -955,8 +891,6 @@ hubbub_error hubbub_tokeniser_handle_tag_open(hubbub_tokeniser *tokeniser)
/* this state never stays in this state for more than one character */
hubbub_error hubbub_tokeniser_handle_close_tag_open(hubbub_tokeniser *tokeniser)
{
- hubbub_tokeniser_context *ctx = &tokeniser->context;
-
size_t len;
const uint8_t *cptr;
parserutils_error error;
@@ -966,131 +900,65 @@ hubbub_error hubbub_tokeniser_handle_close_tag_open(hubbub_tokeniser *tokeniser)
/* assert(tokeniser->context.chars.ptr[0] == '<'); */
/* assert(tokeniser->context.chars.ptr[1] == '/'); */
- /**\todo fragment case */
-
- if (tokeniser->content_model == HUBBUB_CONTENT_MODEL_RCDATA ||
- tokeniser->content_model ==
- HUBBUB_CONTENT_MODEL_CDATA) {
- uint8_t *start_tag_name =
- tokeniser->context.last_start_tag_name;
- size_t start_tag_len =
- tokeniser->context.last_start_tag_len;
-
- while ((error = parserutils_inputstream_peek(tokeniser->input,
- ctx->pending +
- ctx->close_tag_match.count,
- &cptr,
- &len)) == PARSERUTILS_OK) {
- c = *cptr;
-
- if ((start_tag_name[ctx->close_tag_match.count] & ~0x20)
- != (c & ~0x20)) {
- break;
- }
-
- ctx->close_tag_match.count += len;
-
- if (ctx->close_tag_match.count == start_tag_len) {
- ctx->close_tag_match.match = true;
- break;
- }
- }
-
- if (error != PARSERUTILS_OK && error != PARSERUTILS_EOF) {
- return hubbub_error_from_parserutils_error(error);
- }
-
- if (ctx->close_tag_match.match == true) {
- error = parserutils_inputstream_peek(
- tokeniser->input,
- ctx->pending +
- ctx->close_tag_match.count,
- &cptr,
- &len);
-
- if (error != PARSERUTILS_OK &&
- error != PARSERUTILS_EOF) {
- return hubbub_error_from_parserutils_error(
- error);
- } else if (error != PARSERUTILS_EOF) {
- c = *cptr;
-
- if (c != '\t' && c != '\n' && c != '\f' &&
- c != ' ' && c != '>' &&
- c != '/') {
- ctx->close_tag_match.match = false;
- }
- }
- }
- }
-
- if (ctx->close_tag_match.match == false &&
- tokeniser->content_model !=
- HUBBUB_CONTENT_MODEL_PCDATA) {
- /* We should emit "</" here, but instead we leave it in the
- * buffer so the data state emits it with any characters
- * following it */
- tokeniser->state = STATE_DATA;
- } else {
- error = parserutils_inputstream_peek(tokeniser->input,
- tokeniser->context.pending, &cptr, &len);
+ error = parserutils_inputstream_peek(tokeniser->input,
+ tokeniser->context.pending, &cptr, &len);
+ if (error != PARSERUTILS_OK) {
if (error == PARSERUTILS_EOF) {
/** \todo parse error */
-
- /* Return to data state with "</" pending */
+ /* Emit '</' chars */
+ emit_current_chars(tokeniser);
tokeniser->state = STATE_DATA;
return HUBBUB_OK;
- } else if (error != PARSERUTILS_OK) {
+ } else {
return hubbub_error_from_parserutils_error(error);
}
+ }
- c = *cptr;
+ c = *cptr;
- if ('A' <= c && c <= 'Z') {
- uint8_t lc = (c + 0x20);
- START_BUF(tokeniser->context.current_tag.name,
- &lc, len);
- tokeniser->context.current_tag.n_attributes = 0;
+ if ('A' <= c && c <= 'Z') {
+ uint8_t lc = (c + 0x20);
+ START_BUF(tokeniser->context.current_tag.name,
+ &lc, len);
+ tokeniser->context.current_tag.n_attributes = 0;
- tokeniser->context.current_tag_type =
- HUBBUB_TOKEN_END_TAG;
+ tokeniser->context.current_tag_type = HUBBUB_TOKEN_END_TAG;
- tokeniser->context.pending += len;
+ tokeniser->context.pending += len;
- tokeniser->state = STATE_TAG_NAME;
- } else if ('a' <= c && c <= 'z') {
- START_BUF(tokeniser->context.current_tag.name,
- cptr, len);
- tokeniser->context.current_tag.n_attributes = 0;
+ tokeniser->state = STATE_TAG_NAME;
+ } else if ('a' <= c && c <= 'z') {
+ START_BUF(tokeniser->context.current_tag.name,
+ cptr, len);
+ tokeniser->context.current_tag.n_attributes = 0;
- tokeniser->context.current_tag_type =
- HUBBUB_TOKEN_END_TAG;
+ tokeniser->context.current_tag_type = HUBBUB_TOKEN_END_TAG;
- tokeniser->context.pending += len;
+ tokeniser->context.pending += len;
- tokeniser->state = STATE_TAG_NAME;
- } else if (c == '>') {
- /* Cursor still at "</", need to collect ">" */
- tokeniser->context.pending += len;
+ tokeniser->state = STATE_TAG_NAME;
+ } else if (c == '>') {
+ /** \todo parse error */
- /* Now need to advance past "</>" */
- parserutils_inputstream_advance(tokeniser->input,
- tokeniser->context.pending);
- tokeniser->context.pending = 0;
+ /* Cursor still at "</", need to collect ">" */
+ tokeniser->context.pending += len;
- /** \todo parse error */
- tokeniser->state = STATE_DATA;
- } else {
- /** \todo parse error */
+ /* Now need to advance past "</>" */
+ parserutils_inputstream_advance(tokeniser->input,
+ tokeniser->context.pending);
+ tokeniser->context.pending = 0;
- /* Cursor still at "</", need to advance past it */
- parserutils_inputstream_advance(tokeniser->input,
- tokeniser->context.pending);
- tokeniser->context.pending = 0;
+ tokeniser->state = STATE_DATA;
+ } else {
+ /** \todo parse error */
- tokeniser->state = STATE_BOGUS_COMMENT;
- }
+ /* Cursor still at "</", need to advance past it */
+ parserutils_inputstream_advance(tokeniser->input,
+ tokeniser->context.pending);
+ tokeniser->context.pending = 0;
+
+ tokeniser->state = STATE_BOGUS_COMMENT;
}
return HUBBUB_OK;
@@ -1117,8 +985,13 @@ hubbub_error hubbub_tokeniser_handle_tag_name(hubbub_tokeniser *tokeniser)
if (error != PARSERUTILS_OK) {
if (error == PARSERUTILS_EOF) {
+ /** \todo parse error */
tokeniser->state = STATE_DATA;
- return emit_current_tag(tokeniser);
+
+ // skips all pending charachters
+ parserutils_inputstream_advance(
+ tokeniser->input, tokeniser->context.pending);
+ return HUBBUB_OK;
} else {
return hubbub_error_from_parserutils_error(error);
}
@@ -1129,20 +1002,20 @@ hubbub_error hubbub_tokeniser_handle_tag_name(hubbub_tokeniser *tokeniser)
if (c == '\t' || c == '\n' || c == '\f' || c == ' ' || c == '\r') {
tokeniser->context.pending += len;
tokeniser->state = STATE_BEFORE_ATTRIBUTE_NAME;
+ } else if (c == '/') {
+ tokeniser->context.pending += len;
+ tokeniser->state = STATE_SELF_CLOSING_START_TAG;
} else if (c == '>') {
tokeniser->context.pending += len;
tokeniser->state = STATE_DATA;
return emit_current_tag(tokeniser);
- } else if (c == '\0') {
- COLLECT(ctag->name, u_fffd, sizeof(u_fffd));
- tokeniser->context.pending += len;
- } else if (c == '/') {
- tokeniser->context.pending += len;
- tokeniser->state = STATE_SELF_CLOSING_START_TAG;
} else if ('A' <= c && c <= 'Z') {
uint8_t lc = (c + 0x20);
COLLECT(ctag->name, &lc, len);
tokeniser->context.pending += len;
+ } else if (c == '\0') {
+ COLLECT(ctag->name, u_fffd, sizeof(u_fffd));
+ tokeniser->context.pending += len;
} else {
COLLECT(ctag->name, cptr, len);
tokeniser->context.pending += len;
@@ -1166,8 +1039,13 @@ hubbub_error hubbub_tokeniser_handle_before_attribute_name(
if (error != PARSERUTILS_OK) {
if (error == PARSERUTILS_EOF) {
+ /** \todo parse error */
tokeniser->state = STATE_DATA;
- return emit_current_tag(tokeniser);
+
+ // skips all pending charachters
+ parserutils_inputstream_advance(
+ tokeniser->input, tokeniser->context.pending);
+ return HUBBUB_OK;
} else {
return hubbub_error_from_parserutils_error(error);
}
@@ -1178,13 +1056,13 @@ hubbub_error hubbub_tokeniser_handle_before_attribute_name(
if (c == '\t' || c == '\n' || c == '\f' || c == ' ' || c == '\r') {
/* pass over in silence */
tokeniser->context.pending += len;
+ } else if (c == '/') {
+ tokeniser->context.pending += len;
+ tokeniser->state = STATE_SELF_CLOSING_START_TAG;
} else if (c == '>') {
tokeniser->context.pending += len;
tokeniser->state = STATE_DATA;
return emit_current_tag(tokeniser);
- } else if (c == '/') {
- tokeniser->context.pending += len;
- tokeniser->state = STATE_SELF_CLOSING_START_TAG;
} else {
hubbub_attribute *attr;
@@ -1239,8 +1117,13 @@ hubbub_error hubbub_tokeniser_handle_attribute_name(hubbub_tokeniser *tokeniser)
if (error != PARSERUTILS_OK) {
if (error == PARSERUTILS_EOF) {
+ /** \todo parse error */
tokeniser->state = STATE_DATA;
- return emit_current_tag(tokeniser);
+
+ // skips all pending charachters
+ parserutils_inputstream_advance(
+ tokeniser->input, tokeniser->context.pending);
+ return HUBBUB_OK;
} else {
return hubbub_error_from_parserutils_error(error);
}
@@ -1271,6 +1154,10 @@ hubbub_error hubbub_tokeniser_handle_attribute_name(hubbub_tokeniser *tokeniser)
&lc, len);
tokeniser->context.pending += len;
} else {
+ if (c == '"' || c == '\'' || c == '<') {
+ /** \todo parse error */
+ }
+
COLLECT(ctag->attributes[ctag->n_attributes - 1].name,
cptr, len);
tokeniser->context.pending += len;
@@ -1294,13 +1181,21 @@ hubbub_error hubbub_tokeniser_handle_after_attribute_name(
if (error != PARSERUTILS_OK) {
if (error == PARSERUTILS_EOF) {
+ /** \todo parse error */
tokeniser->state = STATE_DATA;
- return emit_current_tag(tokeniser);
+
+ // skips all pending charachters
+ parserutils_inputstream_advance(
+ tokeniser->input, tokeniser->context.pending);
+ return HUBBUB_OK;
} else {
return hubbub_error_from_parserutils_error(error);
}
}
+ /** \todo Check for the existence of attribute name in the attributes list,
+ * if there then igonre this one and its value if any */
+
c = *cptr;
if (c == '\t' || c == '\n' || c == '\f' || c == ' ' || c == '\r') {
@@ -1319,7 +1214,7 @@ hubbub_error hubbub_tokeniser_handle_after_attribute_name(
} else {
hubbub_attribute *attr;
- if (c == '"' || c == '\'') {
+ if (c == '"' || c == '\'' || c =='<') {
/** \todo parse error */
}
@@ -1335,6 +1230,7 @@ hubbub_error hubbub_tokeniser_handle_after_attribute_name(
uint8_t lc = (c + 0x20);
START_BUF(attr[ctag->n_attributes].name, &lc, len);
} else if (c == '\0') {
+ /** \todo parse error */
START_BUF(attr[ctag->n_attributes].name,
u_fffd, sizeof(u_fffd));
} else {
@@ -1372,7 +1268,11 @@ hubbub_error hubbub_tokeniser_handle_before_attribute_value(
if (error == PARSERUTILS_EOF) {
/** \todo parse error */
tokeniser->state = STATE_DATA;
- return emit_current_tag(tokeniser);
+
+ // skips all pending charachters
+ parserutils_inputstream_advance(
+ tokeniser->input, tokeniser->context.pending);
+ return HUBBUB_OK;
} else {
return hubbub_error_from_parserutils_error(error);
}
@@ -1398,12 +1298,14 @@ hubbub_error hubbub_tokeniser_handle_before_attribute_value(
tokeniser->state = STATE_DATA;
return emit_current_tag(tokeniser);
} else if (c == '\0') {
+ /** \todo parse error */
+
START_BUF(ctag->attributes[ctag->n_attributes - 1].value,
u_fffd, sizeof(u_fffd));
tokeniser->context.pending += len;
tokeniser->state = STATE_ATTRIBUTE_VALUE_UQ;
} else {
- if (c == '=') {
+ if (c == '=' || c == '=' || c == '`') {
/** \todo parse error */
}
@@ -1432,8 +1334,13 @@ hubbub_error hubbub_tokeniser_handle_attribute_value_dq(
if (error != PARSERUTILS_OK) {
if (error == PARSERUTILS_EOF) {
+ /** \todo parse error */
tokeniser->state = STATE_DATA;
- return emit_current_tag(tokeniser);
+
+ // skips all pending charachters
+ parserutils_inputstream_advance(
+ tokeniser->input, tokeniser->context.pending);
+ return HUBBUB_OK;
} else {
return hubbub_error_from_parserutils_error(error);
}
@@ -1450,6 +1357,7 @@ hubbub_error hubbub_tokeniser_handle_attribute_value_dq(
tokeniser->context.allowed_char = '"';
/* Don't eat the '&'; it'll be handled by entity consumption */
} else if (c == '\0') {
+ /** \todo parse error */
COLLECT_MS(ctag->attributes[ctag->n_attributes - 1].value,
u_fffd, sizeof(u_fffd));
tokeniser->context.pending += len;
@@ -1494,8 +1402,13 @@ hubbub_error hubbub_tokeniser_handle_attribute_value_sq(
if (error != PARSERUTILS_OK) {
if (error == PARSERUTILS_EOF) {
+ /** \todo parse error */
tokeniser->state = STATE_DATA;
- return emit_current_tag(tokeniser);
+
+ // skips all pending charachters
+ parserutils_inputstream_advance(
+ tokeniser->input, tokeniser->context.pending);
+ return HUBBUB_OK;
} else {
return hubbub_error_from_parserutils_error(error);
}
@@ -1556,8 +1469,13 @@ hubbub_error hubbub_tokeniser_handle_attribute_value_uq(
if (error != PARSERUTILS_OK) {
if (error == PARSERUTILS_EOF) {
+ /** \todo parse error */
tokeniser->state = STATE_DATA;
- return emit_current_tag(tokeniser);
+
+ // skips all pending charachters
+ parserutils_inputstream_advance(
+ tokeniser->input, tokeniser->context.pending);
+ return HUBBUB_OK;
} else {
return hubbub_error_from_parserutils_error(error);
}
@@ -1574,6 +1492,7 @@ hubbub_error hubbub_tokeniser_handle_attribute_value_uq(
} else if (c == '&') {
tokeniser->context.prev_state = tokeniser->state;
tokeniser->state = STATE_CHARACTER_REFERENCE_IN_ATTRIBUTE_VALUE;
+ tokeniser->context.allowed_char = '>';
/* Don't eat the '&'; it'll be handled by entity consumption */
} else if (c == '>') {
tokeniser->context.pending += len;
@@ -1584,7 +1503,7 @@ hubbub_error hubbub_tokeniser_handle_attribute_value_uq(
u_fffd, sizeof(u_fffd));
tokeniser->context.pending += len;
} else {
- if (c == '"' || c == '\'' || c == '=') {
+ if (c == '"' || c == '\'' || c == '=' || c == '<' || c == '`') {
/** \todo parse error */
}
@@ -1666,8 +1585,13 @@ hubbub_error hubbub_tokeniser_handle_after_attribute_value_q(
if (error != PARSERUTILS_OK) {
if (error == PARSERUTILS_EOF) {
+ /** \todo parse error */
tokeniser->state = STATE_DATA;
- return emit_current_tag(tokeniser);
+
+ // skips all pending charachters
+ parserutils_inputstream_advance(
+ tokeniser->input, tokeniser->context.pending);
+ return HUBBUB_OK;
} else {
return hubbub_error_from_parserutils_error(error);
}
@@ -1675,7 +1599,7 @@ hubbub_error hubbub_tokeniser_handle_after_attribute_value_q(
c = *cptr;
- if (c == '\t' || c == '\n' || c == '\f' || c == ' ' || c == '\r') {
+ if (c == '\t' || c == '\n' || c == '\f' || c == ' ') {
tokeniser->context.pending += len;
tokeniser->state = STATE_BEFORE_ATTRIBUTE_NAME;
} else if (c == '>') {
@@ -1708,8 +1632,13 @@ hubbub_error hubbub_tokeniser_handle_self_closing_start_tag(
if (error != PARSERUTILS_OK) {
if (error == PARSERUTILS_EOF) {
+ /** \todo parse error */
tokeniser->state = STATE_DATA;
- return emit_current_tag(tokeniser);
+
+ // skips all pending charachters
+ parserutils_inputstream_advance(
+ tokeniser->input, tokeniser->context.pending);
+ return HUBBUB_OK;
} else {
return hubbub_error_from_parserutils_error(error);
}
@@ -1724,6 +1653,7 @@ hubbub_error hubbub_tokeniser_handle_self_closing_start_tag(
tokeniser->context.current_tag.self_closing = true;
return emit_current_tag(tokeniser);
} else {
+ /** \todo parse error */
/* Reprocess character in before attribute name state */
tokeniser->state = STATE_BEFORE_ATTRIBUTE_NAME;
}
@@ -1809,6 +1739,7 @@ hubbub_error hubbub_tokeniser_handle_markup_declaration_open(
if (error != PARSERUTILS_OK) {
if (error == PARSERUTILS_EOF) {
+ /** \todo parse error */
tokeniser->state = STATE_BOGUS_COMMENT;
return HUBBUB_OK;
} else {
@@ -1826,6 +1757,7 @@ hubbub_error hubbub_tokeniser_handle_markup_declaration_open(
tokeniser->context.match_doctype.count = len;
tokeniser->state = STATE_MATCH_DOCTYPE;
} else if (tokeniser->process_cdata_section == true && c == '[') {
+ // ALSO CHECKS FOR adjusted current node AND element not in html namespace
tokeniser->context.pending = len;
tokeniser->context.match_cdata.count = len;
tokeniser->state = STATE_MATCH_CDATA;
@@ -1836,7 +1768,7 @@ hubbub_error hubbub_tokeniser_handle_markup_declaration_open(
return HUBBUB_OK;
}
-
+/* to match -- and start an empty comment */
hubbub_error hubbub_tokeniser_handle_match_comment(hubbub_tokeniser *tokeniser)
{
size_t len;
@@ -1882,8 +1814,9 @@ hubbub_error hubbub_tokeniser_handle_comment(hubbub_tokeniser *tokeniser)
if (error != PARSERUTILS_OK) {
if (error == PARSERUTILS_EOF) {
+ /** \todo parse error */
tokeniser->state = STATE_DATA;
- return emit_current_comment(tokeniser);
+ return emit_current_comment(tokeniser);;
} else {
return hubbub_error_from_parserutils_error(error);
}
@@ -1893,12 +1826,16 @@ hubbub_error hubbub_tokeniser_handle_comment(hubbub_tokeniser *tokeniser)
if (c == '>' && (tokeniser->state == STATE_COMMENT_START_DASH ||
tokeniser->state == STATE_COMMENT_START ||
- tokeniser->state == STATE_COMMENT_END)) {
+ tokeniser->state == STATE_COMMENT_END ||
+ tokeniser->state == STATE_COMMENT_END_BANG)) {
tokeniser->context.pending += len;
/** \todo parse error if state != COMMENT_END */
tokeniser->state = STATE_DATA;
return emit_current_comment(tokeniser);
+ } else if (c == '!' && tokeniser->state == STATE_COMMENT_END) {
+ tokeniser->context.pending += len;
+ tokeniser->state = STATE_COMMENT_END_BANG;
} else if (c == '-') {
if (tokeniser->state == STATE_COMMENT_START) {
tokeniser->state = STATE_COMMENT_START_DASH;
@@ -1909,12 +1846,23 @@ hubbub_error hubbub_tokeniser_handle_comment(hubbub_tokeniser *tokeniser)
} else if (tokeniser->state == STATE_COMMENT_END_DASH) {
tokeniser->state = STATE_COMMENT_END;
} else if (tokeniser->state == STATE_COMMENT_END) {
+ /** \todo parse error */
error = parserutils_buffer_append(tokeniser->buffer,
(uint8_t *) "-", SLEN("-"));
if (error != PARSERUTILS_OK) {
return hubbub_error_from_parserutils_error(
error);
}
+ } else if (tokeniser->state == STATE_COMMENT_END_BANG) {
+ /** \todo parse error */
+ error = parserutils_buffer_append(tokeniser->buffer,
+ (uint8_t *) "--!", SLEN("--!"));
+ if (error != PARSERUTILS_OK) {
+ return hubbub_error_from_parserutils_error(
+ error);
+ }
+
+ tokeniser->state = STATE_COMMENT_END_DASH;
}
tokeniser->context.pending += len;
@@ -1934,9 +1882,17 @@ hubbub_error hubbub_tokeniser_handle_comment(hubbub_tokeniser *tokeniser)
return hubbub_error_from_parserutils_error(
error);
}
+ } else if (tokeniser->state == STATE_COMMENT_END_BANG) {
+ error = parserutils_buffer_append(tokeniser->buffer,
+ (uint8_t *) "--!", SLEN("--!"));
+ if (error != PARSERUTILS_OK) {
+ return hubbub_error_from_parserutils_error(
+ error);
+ }
}
if (c == '\0') {
+ /** \todo parse error */
error = parserutils_buffer_append(tokeniser->buffer,
u_fffd, sizeof(u_fffd));
if (error != PARSERUTILS_OK) {
@@ -1984,7 +1940,7 @@ hubbub_error hubbub_tokeniser_handle_comment(hubbub_tokeniser *tokeniser)
#define DOCTYPE "DOCTYPE"
#define DOCTYPE_LEN (SLEN(DOCTYPE) - 1)
-
+/* checks for DOCTYPE in*/
hubbub_error hubbub_tokeniser_handle_match_doctype(hubbub_tokeniser *tokeniser)
{
size_t len;
@@ -2053,8 +2009,10 @@ hubbub_error hubbub_tokeniser_handle_doctype(hubbub_tokeniser *tokeniser)
if (error != PARSERUTILS_OK) {
if (error == PARSERUTILS_EOF) {
- tokeniser->state = STATE_BEFORE_DOCTYPE_NAME;
- return HUBBUB_OK;
+ /** \todo parse error */
+ /* Emit current doctype, force-quirks on */
+ tokeniser->state = STATE_DATA;
+ return emit_current_doctype(tokeniser, true);
} else {
return hubbub_error_from_parserutils_error(error);
}
@@ -2062,8 +2020,10 @@ hubbub_error hubbub_tokeniser_handle_doctype(hubbub_tokeniser *tokeniser)
c = *cptr;
- if (c == '\t' || c == '\n' || c == '\f' || c == ' ' || c == '\r') {
+ if (c == '\t' || c == '\n' || c == '\f' || c == ' ') {
tokeniser->context.pending += len;
+ } else {
+ /** \todo parse error */
}
tokeniser->state = STATE_BEFORE_DOCTYPE_NAME;
@@ -2106,6 +2066,7 @@ hubbub_error hubbub_tokeniser_handle_before_doctype_name(
return emit_current_doctype(tokeniser, true);
} else {
if (c == '\0') {
+ /** \todo parse error */
START_BUF(cdoc->name, u_fffd, sizeof(u_fffd));
} else if ('A' <= c && c <= 'Z') {
uint8_t lc = c + 0x20;
@@ -2135,6 +2096,7 @@ hubbub_error hubbub_tokeniser_handle_doctype_name(hubbub_tokeniser *tokeniser)
if (error != PARSERUTILS_OK) {
if (error == PARSERUTILS_EOF) {
+ /** \todo parse error */
tokeniser->state = STATE_DATA;
return emit_current_doctype(tokeniser, true);
} else {
@@ -2144,7 +2106,7 @@ hubbub_error hubbub_tokeniser_handle_doctype_name(hubbub_tokeniser *tokeniser)
c = *cptr;
- if (c == '\t' || c == '\n' || c == '\f' || c == ' ' || c == '\r') {
+ if (c == '\t' || c == '\n' || c == '\f' || c == ' ' || c =='\r') {
tokeniser->context.pending += len;
tokeniser->state = STATE_AFTER_DOCTYPE_NAME;
} else if (c == '>') {
@@ -2152,6 +2114,7 @@ hubbub_error hubbub_tokeniser_handle_doctype_name(hubbub_tokeniser *tokeniser)
tokeniser->state = STATE_DATA;
return emit_current_doctype(tokeniser, false);
} else if (c == '\0') {
+ /** \todo parse error */
COLLECT(cdoc->name, u_fffd, sizeof(u_fffd));
tokeniser->context.pending += len;
} else if ('A' <= c && c <= 'Z') {
@@ -2179,6 +2142,7 @@ hubbub_error hubbub_tokeniser_handle_after_doctype_name(
if (error != PARSERUTILS_OK) {
if (error == PARSERUTILS_EOF) {
+ /** \todo parse error */
tokeniser->state = STATE_DATA;
return emit_current_doctype(tokeniser, true);
} else {
@@ -2189,7 +2153,7 @@ hubbub_error hubbub_tokeniser_handle_after_doctype_name(
c = *cptr;
tokeniser->context.pending += len;
- if (c == '\t' || c == '\n' || c == '\f' || c == ' ' || c == '\r') {
+ if (c == '\t' || c == '\n' || c == '\f' || c == ' ') {
/* pass over in silence */
} else if (c == '>') {
tokeniser->state = STATE_DATA;
@@ -2201,6 +2165,7 @@ hubbub_error hubbub_tokeniser_handle_after_doctype_name(
tokeniser->context.match_doctype.count = 1;
tokeniser->state = STATE_MATCH_SYSTEM;
} else {
+ /** \todo parse error */
tokeniser->state = STATE_BOGUS_DOCTYPE;
tokeniser->context.current_doctype.force_quirks = true;
}
@@ -2255,6 +2220,7 @@ hubbub_error hubbub_tokeniser_handle_match_public(hubbub_tokeniser *tokeniser)
#undef PUBLIC
#undef PUBLIC_LEN
+// same as after public keyword state
hubbub_error hubbub_tokeniser_handle_before_doctype_public(
hubbub_tokeniser *tokeniser)
{
@@ -2269,6 +2235,7 @@ hubbub_error hubbub_tokeniser_handle_before_doctype_public(
if (error != PARSERUTILS_OK) {
if (error == PARSERUTILS_EOF) {
+ /** \todo parse error */
tokeniser->state = STATE_DATA;
return emit_current_doctype(tokeniser, true);
} else {
@@ -2279,20 +2246,74 @@ hubbub_error hubbub_tokeniser_handle_before_doctype_public(
c = *cptr;
tokeniser->context.pending += len;
- if (c == '\t' || c == '\n' || c == '\f' || c == ' ' || c == '\r') {
- /* pass over in silence */
+ if (c == '\t' || c == '\n' || c == '\f' || c == ' ') {
+ tokeniser->state = STATE_BEFORE_DOCTYPE_PUBLIC_IDENTIFIER;
+ } else if (c == '"') {
+ /** \todo parse error */
+ cdoc->public_missing = false;
+ cdoc->public_id.len = 0;
+ tokeniser->state = STATE_DOCTYPE_PUBLIC_DQ;
+ } else if (c == '\'') {
+ /** \todo parse error */
+ cdoc->public_missing = false;
+ cdoc->public_id.len = 0;
+ tokeniser->state = STATE_DOCTYPE_PUBLIC_SQ;
+ } else if (c == '>') {
+ /** \todo parse error */
+ tokeniser->state = STATE_DATA;
+ return emit_current_doctype(tokeniser, true);
+ } else {
+ /** \todo parse error */
+ cdoc->force_quirks = true;
+ tokeniser->state = STATE_BOGUS_DOCTYPE;
+ }
+
+ return HUBBUB_OK;
+}
+
+hubbub_error hubbub_tokeniser_handle_doctype_public_identifier(
+ hubbub_tokeniser *tokeniser)
+{
+ hubbub_doctype *cdoc = &tokeniser->context.current_doctype;
+ size_t len;
+ const uint8_t *cptr;
+ parserutils_error error;
+ uint8_t c;
+
+ error = parserutils_inputstream_peek(tokeniser->input,
+ tokeniser->context.pending, &cptr, &len);
+
+ if (error != PARSERUTILS_OK) {
+ if (error == PARSERUTILS_EOF) {
+ /** \todo parse error */
+ tokeniser->state = STATE_DATA;
+ return emit_current_doctype(tokeniser, true);
+ } else {
+ return hubbub_error_from_parserutils_error(error);
+ }
+ }
+
+ c = *cptr;
+ tokeniser->context.pending += len;
+
+ if (c == '\t' || c == '\n' || c == '\f' || c == ' ') {
+ /** ignore the charachter */
} else if (c == '"') {
+ /** \todo parse error */
cdoc->public_missing = false;
cdoc->public_id.len = 0;
tokeniser->state = STATE_DOCTYPE_PUBLIC_DQ;
} else if (c == '\'') {
+ /** \todo parse error */
cdoc->public_missing = false;
cdoc->public_id.len = 0;
tokeniser->state = STATE_DOCTYPE_PUBLIC_SQ;
} else if (c == '>') {
+ /** \todo parse error */
tokeniser->state = STATE_DATA;
return emit_current_doctype(tokeniser, true);
} else {
+ /** \todo parse error */
cdoc->force_quirks = true;
tokeniser->state = STATE_BOGUS_DOCTYPE;
}
@@ -2314,6 +2335,7 @@ hubbub_error hubbub_tokeniser_handle_doctype_public_dq(
if (error != PARSERUTILS_OK) {
if (error == PARSERUTILS_EOF) {
+ /** \todo parse error */
tokeniser->state = STATE_DATA;
return emit_current_doctype(tokeniser, true);
} else {
@@ -2327,10 +2349,12 @@ hubbub_error hubbub_tokeniser_handle_doctype_public_dq(
tokeniser->context.pending += len;
tokeniser->state = STATE_AFTER_DOCTYPE_PUBLIC;
} else if (c == '>') {
+ /** \todo parse error */
tokeniser->context.pending += len;
tokeniser->state = STATE_DATA;
return emit_current_doctype(tokeniser, true);
} else if (c == '\0') {
+ /** \todo parse error */
COLLECT_MS(cdoc->public_id, u_fffd, sizeof(u_fffd));
tokeniser->context.pending += len;
} else if (c == '\r') {
@@ -2371,6 +2395,7 @@ hubbub_error hubbub_tokeniser_handle_doctype_public_sq(
if (error != PARSERUTILS_OK) {
if (error == PARSERUTILS_EOF) {
+ /** \todo parse error */
tokeniser->state = STATE_DATA;
return emit_current_doctype(tokeniser, true);
} else {
@@ -2384,10 +2409,12 @@ hubbub_error hubbub_tokeniser_handle_doctype_public_sq(
tokeniser->context.pending += len;
tokeniser->state = STATE_AFTER_DOCTYPE_PUBLIC;
} else if (c == '>') {
+ /** \todo parse error */
tokeniser->context.pending += len;
tokeniser->state = STATE_DATA;
return emit_current_doctype(tokeniser, true);
} else if (c == '\0') {
+ /** \todo parse error */
COLLECT_MS(cdoc->public_id, u_fffd, sizeof(u_fffd));
tokeniser->context.pending += len;
} else if (c == '\r') {
@@ -2413,7 +2440,7 @@ hubbub_error hubbub_tokeniser_handle_doctype_public_sq(
return HUBBUB_OK;
}
-
+// after doctype public state and between doctype public & sysyem date are overlapping
hubbub_error hubbub_tokeniser_handle_after_doctype_public(
hubbub_tokeniser *tokeniser)
{
@@ -2428,6 +2455,7 @@ hubbub_error hubbub_tokeniser_handle_after_doctype_public(
if (error != PARSERUTILS_OK) {
if (error == PARSERUTILS_EOF) {
+ /** \todo parse error */
tokeniser->state = STATE_DATA;
return emit_current_doctype(tokeniser, true);
} else {
@@ -2438,7 +2466,7 @@ hubbub_error hubbub_tokeniser_handle_after_doctype_public(
c = *cptr;
tokeniser->context.pending += len;
- if (c == '\t' || c == '\n' || c == '\f' || c == ' ' || c == '\r') {
+ if (c == '\t' || c == '\n' || c == '\f' || c == ' ') {
/* pass over in silence */
} else if (c == '"') {
cdoc->system_missing = false;
@@ -2510,6 +2538,8 @@ hubbub_error hubbub_tokeniser_handle_match_system(hubbub_tokeniser *tokeniser)
#undef SYSTEM
#undef SYSTEM_LEN
+// same as after doctype system keyword state
+// overlapping with before DOCTYPE system identifier state
hubbub_error hubbub_tokeniser_handle_before_doctype_system(
hubbub_tokeniser *tokeniser)
{
@@ -2524,6 +2554,7 @@ hubbub_error hubbub_tokeniser_handle_before_doctype_system(
if (error != PARSERUTILS_OK) {
if (error == PARSERUTILS_EOF) {
+ /** \todo parse error */
tokeniser->state = STATE_DATA;
return emit_current_doctype(tokeniser, true);
} else {
@@ -2534,22 +2565,26 @@ hubbub_error hubbub_tokeniser_handle_before_doctype_system(
c = *cptr;
tokeniser->context.pending += len;
- if (c == '\t' || c == '\n' || c == '\f' || c == ' ' || c == '\r') {
+ if (c == '\t' || c == '\n' || c == '\f' || c == ' ') {
/* pass over */
} else if (c == '"') {
+ /** \todo parse error if this is not the second call for this state */
cdoc->system_missing = false;
cdoc->system_id.len = 0;
tokeniser->state = STATE_DOCTYPE_SYSTEM_DQ;
} else if (c == '\'') {
+ /** \todo parse error if this is not the second call for this state */
cdoc->system_missing = false;
cdoc->system_id.len = 0;
tokeniser->state = STATE_DOCTYPE_SYSTEM_SQ;
} else if (c == '>') {
+ /** \todo parse error */
tokeniser->state = STATE_DATA;
return emit_current_doctype(tokeniser, true);
} else {
+ /** \todo parse error */
cdoc->force_quirks = true;
tokeniser->state = STATE_BOGUS_DOCTYPE;
}
@@ -2571,6 +2606,7 @@ hubbub_error hubbub_tokeniser_handle_doctype_system_dq(
if (error != PARSERUTILS_OK) {
if (error == PARSERUTILS_EOF) {
+ /** \todo parse error */
tokeniser->state = STATE_DATA;
return emit_current_doctype(tokeniser, true);
} else {
@@ -2584,10 +2620,12 @@ hubbub_error hubbub_tokeniser_handle_doctype_system_dq(
tokeniser->context.pending += len;
tokeniser->state = STATE_AFTER_DOCTYPE_SYSTEM;
} else if (c == '>') {
+ /** \todo parse error */
tokeniser->context.pending += len;
tokeniser->state = STATE_DATA;
return emit_current_doctype(tokeniser, true);
} else if (c == '\0') {
+ /** \todo parse error */
COLLECT_MS(cdoc->system_id, u_fffd, sizeof(u_fffd));
tokeniser->context.pending += len;
} else if (c == '\r') {
@@ -2627,6 +2665,7 @@ hubbub_error hubbub_tokeniser_handle_doctype_system_sq(
if (error != PARSERUTILS_OK) {
if (error == PARSERUTILS_EOF) {
+ /** \todo parse error */
tokeniser->state = STATE_DATA;
return emit_current_doctype(tokeniser, true);
} else {
@@ -2640,10 +2679,12 @@ hubbub_error hubbub_tokeniser_handle_doctype_system_sq(
tokeniser->context.pending += len;
tokeniser->state = STATE_AFTER_DOCTYPE_SYSTEM;
} else if (c == '>') {
+ /** \todo parse error */
tokeniser->context.pending += len;
tokeniser->state = STATE_DATA;
return emit_current_doctype(tokeniser, true);
} else if (c == '\0') {
+ /** \todo parse error */
COLLECT_MS(cdoc->system_id, u_fffd, sizeof(u_fffd));
tokeniser->context.pending += len;
} else if (c == '\r') {
@@ -2682,6 +2723,7 @@ hubbub_error hubbub_tokeniser_handle_after_doctype_system(
if (error != PARSERUTILS_OK) {
if (error == PARSERUTILS_EOF) {
+ /** \todo parse error */
tokeniser->state = STATE_DATA;
return emit_current_doctype(tokeniser, true);
} else {
@@ -2692,12 +2734,13 @@ hubbub_error hubbub_tokeniser_handle_after_doctype_system(
c = *cptr;
tokeniser->context.pending += len;
- if (c == '\t' || c == '\n' || c == '\f' || c == ' ' || c == '\r') {
+ if (c == '\t' || c == '\n' || c == '\f' || c == ' ' || c =='\r') {
/* pass over in silence */
} else if (c == '>') {
tokeniser->state = STATE_DATA;
return emit_current_doctype(tokeniser, false);
} else {
+ /** \todo parse error */
tokeniser->state = STATE_BOGUS_DOCTYPE;
}
@@ -2998,7 +3041,7 @@ hubbub_error hubbub_tokeniser_handle_numbered_entity(
break;
}
- if (ctx->match_entity.codepoint >= 0x10FFFF) {
+ if (ctx->match_entity.codepoint > 0x10FFFF) {
ctx->match_entity.overflow = true;
}
}
@@ -3011,27 +3054,34 @@ hubbub_error hubbub_tokeniser_handle_numbered_entity(
if (error != PARSERUTILS_EOF && *cptr == ';') {
ctx->match_entity.length += len;
}
+ else{
+ /** \todo parse error */
+ }
/* Had data, so calculate final codepoint */
if (ctx->match_entity.had_data) {
uint32_t cp = ctx->match_entity.codepoint;
- if (0x80 <= cp && cp <= 0x9F) {
+ if (cp == 0x00) {
+ cp = 0xFFFD;
+ } else if (0x80 <= cp && cp <= 0x9F) {
cp = cp1252Table[cp - 0x80];
- } else if (cp == 0x0D) {
- cp = 0x000A;
} else if (ctx->match_entity.overflow ||
- cp <= 0x0008 || cp == 0x000B ||
- (0x000E <= cp && cp <= 0x001F) ||
- (0x007F <= cp && cp <= 0x009F) ||
- (0xD800 <= cp && cp <= 0xDFFF) ||
- (0xFDD0 <= cp && cp <= 0xFDEF) ||
- (cp & 0xFFFE) == 0xFFFE) {
+ (0xD800 <= cp && cp <= 0xDFFF)) {
/* the check for cp > 0x10FFFF per spec is performed
* in the loop above to avoid overflow */
cp = 0xFFFD;
}
+ if ((0x0001 <= cp && cp <= 0x0008) ||
+ (0x000D <= cp && cp <= 0x001F) ||
+ (0x007F <= cp && cp <= 0x009F) ||
+ (0xFDD0 <= cp && cp <= 0xFDEF) ||
+ cp == 0x000B || (cp & 0xFFFE) == 0xFFFE ||
+ (cp & 0xFFFF) == 0xFFFF) {
+ /** \todo parse error */
+ }
+
ctx->match_entity.codepoint = cp;
}
diff --git a/test/data/tokeniser2/numericEntities.test b/test/data/tokeniser2/numericEntities.test
index 78a8a13..db5f609 100644
--- a/test/data/tokeniser2/numericEntities.test
+++ b/test/data/tokeniser2/numericEntities.test
@@ -6,115 +6,115 @@
{"description": "Invalid numeric entity character U+0001",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\u0001"]]},
{"description": "Invalid numeric entity character U+0002",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\u0002"]]},
{"description": "Invalid numeric entity character U+0003",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\u0003"]]},
{"description": "Invalid numeric entity character U+0004",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\u0004"]]},
{"description": "Invalid numeric entity character U+0005",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\u0005"]]},
{"description": "Invalid numeric entity character U+0006",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\u0006"]]},
{"description": "Invalid numeric entity character U+0007",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\u0007"]]},
{"description": "Invalid numeric entity character U+0008",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\u0008"]]},
{"description": "Invalid numeric entity character U+000B",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\u000b"]]},
{"description": "Invalid numeric entity character U+000E",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\u000e"]]},
{"description": "Invalid numeric entity character U+000F",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\u000f"]]},
{"description": "Invalid numeric entity character U+0010",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\u0010"]]},
{"description": "Invalid numeric entity character U+0011",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\u0011"]]},
{"description": "Invalid numeric entity character U+0012",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\u0012"]]},
{"description": "Invalid numeric entity character U+0013",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\u0013"]]},
{"description": "Invalid numeric entity character U+0014",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\u0014"]]},
{"description": "Invalid numeric entity character U+0015",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\u0015"]]},
{"description": "Invalid numeric entity character U+0016",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\u0016"]]},
{"description": "Invalid numeric entity character U+0017",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\u0017"]]},
{"description": "Invalid numeric entity character U+0018",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\u0018"]]},
{"description": "Invalid numeric entity character U+0019",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\u0019"]]},
{"description": "Invalid numeric entity character U+001A",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\u001a"]]},
{"description": "Invalid numeric entity character U+001B",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\u001b"]]},
{"description": "Invalid numeric entity character U+001C",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\u001c"]]},
{"description": "Invalid numeric entity character U+001D",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\u001d"]]},
{"description": "Invalid numeric entity character U+001E",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\u001e"]]},
{"description": "Invalid numeric entity character U+001F",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\u001f"]]},
{"description": "Invalid numeric entity character U+007F",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\u007f"]]},
{"description": "Invalid numeric entity character U+D800",
"input": "�",
@@ -126,267 +126,267 @@
{"description": "Invalid numeric entity character U+FDD0",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\ufdd0"]]},
{"description": "Invalid numeric entity character U+FDD1",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\ufdd1"]]},
{"description": "Invalid numeric entity character U+FDD2",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\ufdd2"]]},
{"description": "Invalid numeric entity character U+FDD3",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\ufdd3"]]},
{"description": "Invalid numeric entity character U+FDD4",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\ufdd4"]]},
{"description": "Invalid numeric entity character U+FDD5",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\ufdd5"]]},
{"description": "Invalid numeric entity character U+FDD6",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\ufdd6"]]},
{"description": "Invalid numeric entity character U+FDD7",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\ufdd7"]]},
{"description": "Invalid numeric entity character U+FDD8",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\ufdd8"]]},
{"description": "Invalid numeric entity character U+FDD9",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\ufdd9"]]},
{"description": "Invalid numeric entity character U+FDDA",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\ufdda"]]},
{"description": "Invalid numeric entity character U+FDDB",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\ufddb"]]},
{"description": "Invalid numeric entity character U+FDDC",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\ufddc"]]},
{"description": "Invalid numeric entity character U+FDDD",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\ufddd"]]},
{"description": "Invalid numeric entity character U+FDDE",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\ufdde"]]},
{"description": "Invalid numeric entity character U+FDDF",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\ufddf"]]},
{"description": "Invalid numeric entity character U+FDE0",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\ufde0"]]},
{"description": "Invalid numeric entity character U+FDE1",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\ufde1"]]},
{"description": "Invalid numeric entity character U+FDE2",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\ufde2"]]},
{"description": "Invalid numeric entity character U+FDE3",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\ufde3"]]},
{"description": "Invalid numeric entity character U+FDE4",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\ufde4"]]},
{"description": "Invalid numeric entity character U+FDE5",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\ufde5"]]},
{"description": "Invalid numeric entity character U+FDE6",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\ufde6"]]},
{"description": "Invalid numeric entity character U+FDE7",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\ufde7"]]},
{"description": "Invalid numeric entity character U+FDE8",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\ufde8"]]},
{"description": "Invalid numeric entity character U+FDE9",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\ufde9"]]},
{"description": "Invalid numeric entity character U+FDEA",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\ufdea"]]},
{"description": "Invalid numeric entity character U+FDEB",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\ufdeb"]]},
{"description": "Invalid numeric entity character U+FDEC",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\ufdec"]]},
{"description": "Invalid numeric entity character U+FDED",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\ufded"]]},
{"description": "Invalid numeric entity character U+FDEE",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\ufdee"]]},
{"description": "Invalid numeric entity character U+FDEF",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\ufdef"]]},
{"description": "Invalid numeric entity character U+FFFE",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\ufffe"]]},
{"description": "Invalid numeric entity character U+FFFF",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\uffff"]]},
{"description": "Invalid numeric entity character U+1FFFE",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\uD83F\uDFFE"]]},
{"description": "Invalid numeric entity character U+1FFFF",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\uD83F\uDFFF"]]},
{"description": "Invalid numeric entity character U+2FFFE",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\uD87F\uDFFE"]]},
{"description": "Invalid numeric entity character U+2FFFF",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\uD87F\uDFFF"]]},
{"description": "Invalid numeric entity character U+3FFFE",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\uD8BF\uDFFE"]]},
{"description": "Invalid numeric entity character U+3FFFF",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\uD8BF\uDFFF"]]},
{"description": "Invalid numeric entity character U+4FFFE",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\uD8FF\uDFFE"]]},
{"description": "Invalid numeric entity character U+4FFFF",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\uD8FF\uDFFF"]]},
{"description": "Invalid numeric entity character U+5FFFE",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\uD93F\uDFFE"]]},
{"description": "Invalid numeric entity character U+5FFFF",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\uD93F\uDFFF"]]},
{"description": "Invalid numeric entity character U+6FFFE",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\uD97F\uDFFE"]]},
{"description": "Invalid numeric entity character U+6FFFF",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\uD97F\uDFFF"]]},
{"description": "Invalid numeric entity character U+7FFFE",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\uD9BF\uDFFE"]]},
{"description": "Invalid numeric entity character U+7FFFF",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\uD9BF\uDFFF"]]},
{"description": "Invalid numeric entity character U+8FFFE",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\uD9FF\uDFFE"]]},
{"description": "Invalid numeric entity character U+8FFFF",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\uD9FF\uDFFF"]]},
{"description": "Invalid numeric entity character U+9FFFE",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\uDA3F\uDFFE"]]},
{"description": "Invalid numeric entity character U+9FFFF",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\uDA3F\uDFFF"]]},
{"description": "Invalid numeric entity character U+AFFFE",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\uDA7F\uDFFE"]]},
{"description": "Invalid numeric entity character U+AFFFF",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\uDA7F\uDFFF"]]},
{"description": "Invalid numeric entity character U+BFFFE",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\uDABF\uDFFE"]]},
{"description": "Invalid numeric entity character U+BFFFF",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\uDABF\uDFFF"]]},
{"description": "Invalid numeric entity character U+CFFFE",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\uDAFF\uDFFE"]]},
{"description": "Invalid numeric entity character U+CFFFF",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\uDAFF\uDFFF"]]},
{"description": "Invalid numeric entity character U+DFFFE",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\uDB3F\uDFFE"]]},
{"description": "Invalid numeric entity character U+DFFFF",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\uDB3F\uDFFF"]]},
{"description": "Invalid numeric entity character U+EFFFE",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\uDB7F\uDFFE"]]},
{"description": "Invalid numeric entity character U+EFFFF",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\uDB7F\uDFFF"]]},
{"description": "Invalid numeric entity character U+FFFFE",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\uDBBF\uDFFE"]]},
{"description": "Invalid numeric entity character U+FFFFF",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\uDBBF\uDFFF"]]},
{"description": "Invalid numeric entity character U+10FFFE",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\uDBFF\uDFFE"]]},
{"description": "Invalid numeric entity character U+10FFFF",
"input": "",
-"output": ["ParseError", ["Character", "\uFFFD"]]},
+"output": ["ParseError", ["Character", "\uDBFF\uDFFF"]]},
{"description": "Valid numeric entity character U+0009",
"input": "	",
diff --git a/test/data/tokeniser2/regression.test b/test/data/tokeniser2/regression.test
index ae3e66a..5bffa74 100644
--- a/test/data/tokeniser2/regression.test
+++ b/test/data/tokeniser2/regression.test
@@ -2,11 +2,11 @@
{"description":"CR in double-quoted attribute value",
"input":"<foo bar=\"\r\u2022xyz\"",
-"output":[["StartTag", "foo", {"bar":"\n\u2022xyz"}]]},
+"output":["ParseError"]},
{"description":"CR in single-quoted attribute value",
"input":"<foo bar='\r\u2022xyz'",
-"output":[["StartTag", "foo", {"bar":"\n\u2022xyz"}]]},
+"output":["ParseError"]},
{"description":"CR in comment",
"input":"<!--\r\u2022xyz-->",
diff --git a/test/data/tokeniser2/test1.test b/test/data/tokeniser2/test1.test
index 9431863..b97b2cb 100644
--- a/test/data/tokeniser2/test1.test
+++ b/test/data/tokeniser2/test1.test
@@ -115,7 +115,7 @@
{"description":"Unfinished entity",
"input":"&f",
-"output":["ParseError", ["Character", "&f"]]},
+"output":[["Character", "&f"]]},
{"description":"Ampersand, number sign",
"input":"&#",
@@ -143,11 +143,11 @@
{"description":"Partial entity match at end of file",
"input":"I'm &no",
-"output":[["Character","I'm "], "ParseError", ["Character", "&no"]]},
+"output":[["Character","I'm &no"]]},
{"description":"Non-ASCII character reference name",
"input":"&\u00AC;",
-"output":["ParseError", ["Character", "&\u00AC;"]]},
+"output":[["Character", "&\u00AC;"]]},
{"description":"ASCII decimal entity",
"input":"$",
@@ -163,22 +163,34 @@
{"description":"Entity in attribute without semicolon ending in x",
"input":"<h a='¬x'>",
-"output":["ParseError", ["StartTag", "h", {"a":"¬x"}]]},
+"output":[["StartTag", "h", {"a":"¬x"}]]},
{"description":"Entity in attribute without semicolon ending in 1",
"input":"<h a='¬1'>",
-"output":["ParseError", ["StartTag", "h", {"a":"¬1"}]]},
+"output":[["StartTag", "h", {"a":"¬1"}]]},
{"description":"Entity in attribute without semicolon ending in i",
"input":"<h a='¬i'>",
-"output":["ParseError", ["StartTag", "h", {"a":"¬i"}]]},
+"output":[["StartTag", "h", {"a":"¬i"}]]},
{"description":"Entity in attribute without semicolon",
"input":"<h a='©'>",
"output":["ParseError", ["StartTag", "h", {"a":"\u00A9"}]]},
{"description":"Unquoted attribute ending in ampersand",
- "input":"<s o=& t",
- "output":["ParseError",["StartTag","s",{"o":"&","t":""}]]}
+"input":"<s o=& t>",
+"output":[["StartTag","s",{"o":"&","t":""}]]},
+
+{"description":"Unquoted attribute at end of tag with final character of &, with tag followed by characters",
+"input":"<a a=a&>foo",
+"output":[["StartTag", "a", {"a":"a&"}], ["Character", "foo"]]},
+
+{"description":"plaintext element",
+ "input":"<plaintext>foobar",
+ "output":[["StartTag","plaintext",{}], ["Character","foobar"]]},
+
+{"description":"Open angled bracket in unquoted attribute value state",
+ "input":"<a a=f<>",
+ "output":["ParseError", ["StartTag", "a", {"a":"f<"}]]}
]}
diff --git a/test/data/tokeniser2/test2.test b/test/data/tokeniser2/test2.test
index 6d6f6ff..87a8eba 100644
--- a/test/data/tokeniser2/test2.test
+++ b/test/data/tokeniser2/test2.test
@@ -2,7 +2,7 @@
{"description":"DOCTYPE without name",
"input":"<!DOCTYPE>",
-"output":["ParseError", "ParseError", ["DOCTYPE", "", null, null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", null, null, null, false]]},
{"description":"DOCTYPE without space before name",
"input":"<!DOCTYPEhtml>",
@@ -82,7 +82,7 @@
{"description":"Entity without a name",
"input":"&;",
-"output":["ParseError", ["Character", "&;"]]},
+"output":[["Character", "&;"]]},
{"description":"Unescaped ampersand in attribute value",
"input":"<h a='&'>",
@@ -134,7 +134,7 @@
{"description":"Null Byte Replacement",
"input":"\u0000",
-"output":["ParseError", ["Character", "\ufffd"]]},
+"output":["ParseError", ["Character", "\u0000"]]},
{"description":"Comment with dash",
"input":"<!---x",
@@ -158,6 +158,22 @@
{"description":"Single-quote after attribute name",
"input":"<h a '>",
-"output":["ParseError", ["StartTag", "h", {"a":"", "'":""}]]}
+"output":["ParseError", ["StartTag", "h", {"a":"", "'":""}]]},
+
+{"description":"Empty end tag with following characters",
+"input":"a</>bc",
+"output":[["Character", "a"], "ParseError", ["Character", "bc"]]},
+
+{"description":"Empty end tag with following tag",
+"input":"a</><b>c",
+"output":[["Character", "a"], "ParseError", ["StartTag", "b", {}], ["Character", "c"]]},
+
+{"description":"Empty end tag with following comment",
+"input":"a</><!--b-->c",
+"output":[["Character", "a"], "ParseError", ["Comment", "b"], ["Character", "c"]]},
+
+{"description":"Empty end tag with following end tag",
+"input":"a</></b>c",
+"output":[["Character", "a"], "ParseError", ["EndTag", "b"], ["Character", "c"]]}
]}
diff --git a/test/data/tokeniser2/test3.test b/test/data/tokeniser2/test3.test
index 593fc93..8fc529a 100644
--- a/test/data/tokeniser2/test3.test
+++ b/test/data/tokeniser2/test3.test
@@ -4,10 +4,6 @@
"input":"",
"output":[]},
-{"description":"\\u0000",
-"input":"\u0000",
-"output":["ParseError", ["Character", "\uFFFD"]]},
-
{"description":"\\u0009",
"input":"\u0009",
"output":[["Character", "\u0009"]]},
@@ -86,7 +82,7 @@
{"description":"<\\u0000",
"input":"<\u0000",
-"output":["ParseError", "ParseError", ["Character", "<\uFFFD"]]},
+"output":["ParseError", ["Character", "<"], "ParseError", ["Character", "\u0000"]]},
{"description":"<\\u0009",
"input":"<\u0009",
@@ -114,7 +110,7 @@
{"description":"<!\\u0000",
"input":"<!\u0000",
-"output":["ParseError", "ParseError", ["Comment", "\uFFFD"]]},
+"output":["ParseError", ["Comment", "\uFFFD"]]},
{"description":"<!\\u0009",
"input":"<!\u0009",
@@ -522,7 +518,7 @@
{"description":"<!----\\u0000",
"input":"<!----\u0000",
-"output":["ParseError", "ParseError", "ParseError", ["Comment", "--\uFFFD"]]},
+"output":["ParseError", "ParseError", ["Comment", "--\uFFFD"]]},
{"description":"<!----\\u0009",
"input":"<!----\u0009",
@@ -544,10 +540,62 @@
"input":"<!---- ",
"output":["ParseError", "ParseError", ["Comment", "-- "]]},
+{"description":"<!---- -",
+"input":"<!---- -",
+"output":["ParseError", "ParseError", ["Comment", "-- "]]},
+
+{"description":"<!---- --",
+"input":"<!---- --",
+"output":["ParseError", "ParseError", ["Comment", "-- "]]},
+
+{"description":"<!---- -->",
+"input":"<!---- -->",
+"output":["ParseError", ["Comment", "-- "]]},
+
+{"description":"<!---- -->",
+"input":"<!---- -->",
+"output":["ParseError", ["Comment", "-- "]]},
+
+{"description":"<!---- a-->",
+"input":"<!---- a-->",
+"output":["ParseError", ["Comment", "-- a"]]},
+
{"description":"<!----!",
"input":"<!----!",
+"output":["ParseError", "ParseError", ["Comment", ""]]},
+
+{"description":"<!----!>",
+"input":"<!----!>",
+"output":["ParseError", ["Comment", ""]]},
+
+{"description":"<!----!a",
+"input":"<!----!a",
+"output":["ParseError", "ParseError", ["Comment", "--!a"]]},
+
+{"description":"<!----!a-",
+"input":"<!----!a-",
+"output":["ParseError", "ParseError", ["Comment", "--!a"]]},
+
+{"description":"<!----!a--",
+"input":"<!----!a--",
+"output":["ParseError", "ParseError", ["Comment", "--!a"]]},
+
+{"description":"<!----!a-->",
+"input":"<!----!a-->",
+"output":["ParseError", ["Comment", "--!a"]]},
+
+{"description":"<!----!-",
+"input":"<!----!-",
"output":["ParseError", "ParseError", ["Comment", "--!"]]},
+{"description":"<!----!--",
+"input":"<!----!--",
+"output":["ParseError", "ParseError", ["Comment", "--!"]]},
+
+{"description":"<!----!-->",
+"input":"<!----!-->",
+"output":["ParseError", ["Comment", "--!"]]},
+
{"description":"<!----\"",
"input":"<!----\"",
"output":["ParseError", "ParseError", ["Comment", "--\""]]},
@@ -866,7 +914,7 @@
{"description":"<!DOCTYPE",
"input":"<!DOCTYPE",
-"output":["ParseError", "ParseError", ["DOCTYPE", "", null, null, false]]},
+"output":["ParseError", ["DOCTYPE", null, null, null, false]]},
{"description":"<!DOCTYPE\\u0000",
"input":"<!DOCTYPE\u0000",
@@ -878,11 +926,11 @@
{"description":"<!DOCTYPE\\u0009",
"input":"<!DOCTYPE\u0009",
-"output":["ParseError", ["DOCTYPE", "", null, null, false]]},
+"output":["ParseError", ["DOCTYPE", null, null, null, false]]},
{"description":"<!DOCTYPE\\u000A",
"input":"<!DOCTYPE\u000A",
-"output":["ParseError", ["DOCTYPE", "", null, null, false]]},
+"output":["ParseError", ["DOCTYPE", null, null, null, false]]},
{"description":"<!DOCTYPE\\u000B",
"input":"<!DOCTYPE\u000B",
@@ -890,11 +938,11 @@
{"description":"<!DOCTYPE\\u000C",
"input":"<!DOCTYPE\u000C",
-"output":["ParseError", ["DOCTYPE", "", null, null, false]]},
+"output":["ParseError", ["DOCTYPE", null, null, null, false]]},
{"description":"<!DOCTYPE\\u000D",
"input":"<!DOCTYPE\u000D",
-"output":["ParseError", ["DOCTYPE", "", null, null, false]]},
+"output":["ParseError", ["DOCTYPE", null, null, null, false]]},
{"description":"<!DOCTYPE\\u001F",
"input":"<!DOCTYPE\u001F",
@@ -902,7 +950,7 @@
{"description":"<!DOCTYPE ",
"input":"<!DOCTYPE ",
-"output":["ParseError", ["DOCTYPE", "", null, null, false]]},
+"output":["ParseError", ["DOCTYPE", null, null, null, false]]},
{"description":"<!DOCTYPE \\u0000",
"input":"<!DOCTYPE \u0000",
@@ -914,11 +962,11 @@
{"description":"<!DOCTYPE \\u0009",
"input":"<!DOCTYPE \u0009",
-"output":["ParseError", ["DOCTYPE", "", null, null, false]]},
+"output":["ParseError", ["DOCTYPE", null, null, null, false]]},
{"description":"<!DOCTYPE \\u000A",
"input":"<!DOCTYPE \u000A",
-"output":["ParseError", ["DOCTYPE", "", null, null, false]]},
+"output":["ParseError", ["DOCTYPE", null, null, null, false]]},
{"description":"<!DOCTYPE \\u000B",
"input":"<!DOCTYPE \u000B",
@@ -926,11 +974,11 @@
{"description":"<!DOCTYPE \\u000C",
"input":"<!DOCTYPE \u000C",
-"output":["ParseError", ["DOCTYPE", "", null, null, false]]},
+"output":["ParseError", ["DOCTYPE", null, null, null, false]]},
{"description":"<!DOCTYPE \\u000D",
"input":"<!DOCTYPE \u000D",
-"output":["ParseError", ["DOCTYPE", "", null, null, false]]},
+"output":["ParseError", ["DOCTYPE", null, null, null, false]]},
{"description":"<!DOCTYPE \\u001F",
"input":"<!DOCTYPE \u001F",
@@ -938,7 +986,7 @@
{"description":"<!DOCTYPE ",
"input":"<!DOCTYPE ",
-"output":["ParseError", ["DOCTYPE", "", null, null, false]]},
+"output":["ParseError", ["DOCTYPE", null, null, null, false]]},
{"description":"<!DOCTYPE !",
"input":"<!DOCTYPE !",
@@ -986,7 +1034,7 @@
{"description":"<!DOCTYPE >",
"input":"<!DOCTYPE >",
-"output":["ParseError", ["DOCTYPE", "", null, null, false]]},
+"output":["ParseError", ["DOCTYPE", null, null, null, false]]},
{"description":"<!DOCTYPE ?",
"input":"<!DOCTYPE ?",
@@ -1062,7 +1110,7 @@
{"description":"<!DOCTYPE a \\u0000",
"input":"<!DOCTYPE a \u0000",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
{"description":"<!DOCTYPE a \\u0008",
"input":"<!DOCTYPE a \u0008",
@@ -1166,7 +1214,7 @@
{"description":"<!DOCTYPE a PUBLIC\\u0000",
"input":"<!DOCTYPE a PUBLIC\u0000",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
{"description":"<!DOCTYPE a PUBLIC\\u0008",
"input":"<!DOCTYPE a PUBLIC\u0008",
@@ -1206,135 +1254,135 @@
{"description":"<!DOCTYPE a PUBLIC\"",
"input":"<!DOCTYPE a PUBLIC\"",
-"output":["ParseError", ["DOCTYPE", "a", "", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
{"description":"<!DOCTYPE a PUBLIC\"\\u0000",
"input":"<!DOCTYPE a PUBLIC\"\u0000",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "\uFFFD", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "\uFFFD", null, false]]},
{"description":"<!DOCTYPE a PUBLIC\"\\u0009",
"input":"<!DOCTYPE a PUBLIC\"\u0009",
-"output":["ParseError", ["DOCTYPE", "a", "\u0009", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "\u0009", null, false]]},
{"description":"<!DOCTYPE a PUBLIC\"\\u000A",
"input":"<!DOCTYPE a PUBLIC\"\u000A",
-"output":["ParseError", ["DOCTYPE", "a", "\u000A", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "\u000A", null, false]]},
{"description":"<!DOCTYPE a PUBLIC\"\\u000B",
"input":"<!DOCTYPE a PUBLIC\"\u000B",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "\u000B", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "\u000B", null, false]]},
{"description":"<!DOCTYPE a PUBLIC\"\\u000C",
"input":"<!DOCTYPE a PUBLIC\"\u000C",
-"output":["ParseError", ["DOCTYPE", "a", "\u000C", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "\u000C", null, false]]},
{"description":"<!DOCTYPE a PUBLIC\" ",
"input":"<!DOCTYPE a PUBLIC\" ",
-"output":["ParseError", ["DOCTYPE", "a", " ", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", " ", null, false]]},
{"description":"<!DOCTYPE a PUBLIC\"!",
"input":"<!DOCTYPE a PUBLIC\"!",
-"output":["ParseError", ["DOCTYPE", "a", "!", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "!", null, false]]},
{"description":"<!DOCTYPE a PUBLIC\"\"",
"input":"<!DOCTYPE a PUBLIC\"\"",
-"output":["ParseError", ["DOCTYPE", "a", "", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
{"description":"<!DOCTYPE a PUBLIC\"#",
"input":"<!DOCTYPE a PUBLIC\"#",
-"output":["ParseError", ["DOCTYPE", "a", "#", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "#", null, false]]},
{"description":"<!DOCTYPE a PUBLIC\"&",
"input":"<!DOCTYPE a PUBLIC\"&",
-"output":["ParseError", ["DOCTYPE", "a", "&", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "&", null, false]]},
{"description":"<!DOCTYPE a PUBLIC\"'",
"input":"<!DOCTYPE a PUBLIC\"'",
-"output":["ParseError", ["DOCTYPE", "a", "'", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "'", null, false]]},
{"description":"<!DOCTYPE a PUBLIC\"-",
"input":"<!DOCTYPE a PUBLIC\"-",
-"output":["ParseError", ["DOCTYPE", "a", "-", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "-", null, false]]},
{"description":"<!DOCTYPE a PUBLIC\"/",
"input":"<!DOCTYPE a PUBLIC\"/",
-"output":["ParseError", ["DOCTYPE", "a", "/", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "/", null, false]]},
{"description":"<!DOCTYPE a PUBLIC\"0",
"input":"<!DOCTYPE a PUBLIC\"0",
-"output":["ParseError", ["DOCTYPE", "a", "0", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "0", null, false]]},
{"description":"<!DOCTYPE a PUBLIC\"1",
"input":"<!DOCTYPE a PUBLIC\"1",
-"output":["ParseError", ["DOCTYPE", "a", "1", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "1", null, false]]},
{"description":"<!DOCTYPE a PUBLIC\"9",
"input":"<!DOCTYPE a PUBLIC\"9",
-"output":["ParseError", ["DOCTYPE", "a", "9", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "9", null, false]]},
{"description":"<!DOCTYPE a PUBLIC\"<",
"input":"<!DOCTYPE a PUBLIC\"<",
-"output":["ParseError", ["DOCTYPE", "a", "<", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "<", null, false]]},
{"description":"<!DOCTYPE a PUBLIC\"=",
"input":"<!DOCTYPE a PUBLIC\"=",
-"output":["ParseError", ["DOCTYPE", "a", "=", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "=", null, false]]},
{"description":"<!DOCTYPE a PUBLIC\">",
"input":"<!DOCTYPE a PUBLIC\">",
-"output":["ParseError", ["DOCTYPE", "a", "", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
{"description":"<!DOCTYPE a PUBLIC\"?",
"input":"<!DOCTYPE a PUBLIC\"?",
-"output":["ParseError", ["DOCTYPE", "a", "?", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "?", null, false]]},
{"description":"<!DOCTYPE a PUBLIC\"@",
"input":"<!DOCTYPE a PUBLIC\"@",
-"output":["ParseError", ["DOCTYPE", "a", "@", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "@", null, false]]},
{"description":"<!DOCTYPE a PUBLIC\"A",
"input":"<!DOCTYPE a PUBLIC\"A",
-"output":["ParseError", ["DOCTYPE", "a", "A", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "A", null, false]]},
{"description":"<!DOCTYPE a PUBLIC\"B",
"input":"<!DOCTYPE a PUBLIC\"B",
-"output":["ParseError", ["DOCTYPE", "a", "B", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "B", null, false]]},
{"description":"<!DOCTYPE a PUBLIC\"Y",
"input":"<!DOCTYPE a PUBLIC\"Y",
-"output":["ParseError", ["DOCTYPE", "a", "Y", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "Y", null, false]]},
{"description":"<!DOCTYPE a PUBLIC\"Z",
"input":"<!DOCTYPE a PUBLIC\"Z",
-"output":["ParseError", ["DOCTYPE", "a", "Z", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "Z", null, false]]},
{"description":"<!DOCTYPE a PUBLIC\"`",
"input":"<!DOCTYPE a PUBLIC\"`",
-"output":["ParseError", ["DOCTYPE", "a", "`", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "`", null, false]]},
{"description":"<!DOCTYPE a PUBLIC\"a",
"input":"<!DOCTYPE a PUBLIC\"a",
-"output":["ParseError", ["DOCTYPE", "a", "a", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "a", null, false]]},
{"description":"<!DOCTYPE a PUBLIC\"b",
"input":"<!DOCTYPE a PUBLIC\"b",
-"output":["ParseError", ["DOCTYPE", "a", "b", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "b", null, false]]},
{"description":"<!DOCTYPE a PUBLIC\"y",
"input":"<!DOCTYPE a PUBLIC\"y",
-"output":["ParseError", ["DOCTYPE", "a", "y", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "y", null, false]]},
{"description":"<!DOCTYPE a PUBLIC\"z",
"input":"<!DOCTYPE a PUBLIC\"z",
-"output":["ParseError", ["DOCTYPE", "a", "z", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "z", null, false]]},
{"description":"<!DOCTYPE a PUBLIC\"{",
"input":"<!DOCTYPE a PUBLIC\"{",
-"output":["ParseError", ["DOCTYPE", "a", "{", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "{", null, false]]},
{"description":"<!DOCTYPE a PUBLIC\"\\uDBC0\\uDC00",
"input":"<!DOCTYPE a PUBLIC\"\uDBC0\uDC00",
-"output":["ParseError", ["DOCTYPE", "a", "\uDBC0\uDC00", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "\uDBC0\uDC00", null, false]]},
{"description":"<!DOCTYPE a PUBLIC#",
"input":"<!DOCTYPE a PUBLIC#",
@@ -1346,47 +1394,47 @@
{"description":"<!DOCTYPE a PUBLIC'",
"input":"<!DOCTYPE a PUBLIC'",
-"output":["ParseError", ["DOCTYPE", "a", "", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
{"description":"<!DOCTYPE a PUBLIC'\\u0000",
"input":"<!DOCTYPE a PUBLIC'\u0000",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "\uFFFD", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "\uFFFD", null, false]]},
{"description":"<!DOCTYPE a PUBLIC'\\u0009",
"input":"<!DOCTYPE a PUBLIC'\u0009",
-"output":["ParseError", ["DOCTYPE", "a", "\u0009", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "\u0009", null, false]]},
{"description":"<!DOCTYPE a PUBLIC'\\u000A",
"input":"<!DOCTYPE a PUBLIC'\u000A",
-"output":["ParseError", ["DOCTYPE", "a", "\u000A", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "\u000A", null, false]]},
{"description":"<!DOCTYPE a PUBLIC'\\u000B",
"input":"<!DOCTYPE a PUBLIC'\u000B",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "\u000B", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "\u000B", null, false]]},
{"description":"<!DOCTYPE a PUBLIC'\\u000C",
"input":"<!DOCTYPE a PUBLIC'\u000C",
-"output":["ParseError", ["DOCTYPE", "a", "\u000C", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "\u000C", null, false]]},
{"description":"<!DOCTYPE a PUBLIC' ",
"input":"<!DOCTYPE a PUBLIC' ",
-"output":["ParseError", ["DOCTYPE", "a", " ", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", " ", null, false]]},
{"description":"<!DOCTYPE a PUBLIC'!",
"input":"<!DOCTYPE a PUBLIC'!",
-"output":["ParseError", ["DOCTYPE", "a", "!", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "!", null, false]]},
{"description":"<!DOCTYPE a PUBLIC'\"",
"input":"<!DOCTYPE a PUBLIC'\"",
-"output":["ParseError", ["DOCTYPE", "a", "\"", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "\"", null, false]]},
{"description":"<!DOCTYPE a PUBLIC'&",
"input":"<!DOCTYPE a PUBLIC'&",
-"output":["ParseError", ["DOCTYPE", "a", "&", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "&", null, false]]},
{"description":"<!DOCTYPE a PUBLIC''",
"input":"<!DOCTYPE a PUBLIC''",
-"output":["ParseError", ["DOCTYPE", "a", "", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
{"description":"<!DOCTYPE a PUBLIC''\\u0000",
"input":"<!DOCTYPE a PUBLIC''\u0000",
@@ -1394,231 +1442,231 @@
{"description":"<!DOCTYPE a PUBLIC''\\u0008",
"input":"<!DOCTYPE a PUBLIC''\u0008",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
{"description":"<!DOCTYPE a PUBLIC''\\u0009",
"input":"<!DOCTYPE a PUBLIC''\u0009",
-"output":["ParseError", ["DOCTYPE", "a", "", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
{"description":"<!DOCTYPE a PUBLIC''\\u000A",
"input":"<!DOCTYPE a PUBLIC''\u000A",
-"output":["ParseError", ["DOCTYPE", "a", "", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
{"description":"<!DOCTYPE a PUBLIC''\\u000B",
"input":"<!DOCTYPE a PUBLIC''\u000B",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
{"description":"<!DOCTYPE a PUBLIC''\\u000C",
"input":"<!DOCTYPE a PUBLIC''\u000C",
-"output":["ParseError", ["DOCTYPE", "a", "", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
{"description":"<!DOCTYPE a PUBLIC''\\u000D",
"input":"<!DOCTYPE a PUBLIC''\u000D",
-"output":["ParseError", ["DOCTYPE", "a", "", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
{"description":"<!DOCTYPE a PUBLIC''\\u001F",
"input":"<!DOCTYPE a PUBLIC''\u001F",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
{"description":"<!DOCTYPE a PUBLIC'' ",
"input":"<!DOCTYPE a PUBLIC'' ",
-"output":["ParseError", ["DOCTYPE", "a", "", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
{"description":"<!DOCTYPE a PUBLIC''!",
"input":"<!DOCTYPE a PUBLIC''!",
-"output":["ParseError", ["DOCTYPE", "a", "", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
{"description":"<!DOCTYPE a PUBLIC''\"",
"input":"<!DOCTYPE a PUBLIC''\"",
-"output":["ParseError", ["DOCTYPE", "a", "", "", false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", "", false]]},
{"description":"<!DOCTYPE a PUBLIC''#",
"input":"<!DOCTYPE a PUBLIC''#",
-"output":["ParseError", ["DOCTYPE", "a", "", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
{"description":"<!DOCTYPE a PUBLIC''&",
"input":"<!DOCTYPE a PUBLIC''&",
-"output":["ParseError", ["DOCTYPE", "a", "", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
{"description":"<!DOCTYPE a PUBLIC'''",
"input":"<!DOCTYPE a PUBLIC'''",
-"output":["ParseError", ["DOCTYPE", "a", "", "", false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", "", false]]},
{"description":"<!DOCTYPE a PUBLIC''(",
"input":"<!DOCTYPE a PUBLIC''(",
-"output":["ParseError", ["DOCTYPE", "a", "", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
{"description":"<!DOCTYPE a PUBLIC''-",
"input":"<!DOCTYPE a PUBLIC''-",
-"output":["ParseError", ["DOCTYPE", "a", "", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
{"description":"<!DOCTYPE a PUBLIC''/",
"input":"<!DOCTYPE a PUBLIC''/",
-"output":["ParseError", ["DOCTYPE", "a", "", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
{"description":"<!DOCTYPE a PUBLIC''0",
"input":"<!DOCTYPE a PUBLIC''0",
-"output":["ParseError", ["DOCTYPE", "a", "", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
{"description":"<!DOCTYPE a PUBLIC''1",
"input":"<!DOCTYPE a PUBLIC''1",
-"output":["ParseError", ["DOCTYPE", "a", "", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
{"description":"<!DOCTYPE a PUBLIC''9",
"input":"<!DOCTYPE a PUBLIC''9",
-"output":["ParseError", ["DOCTYPE", "a", "", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
{"description":"<!DOCTYPE a PUBLIC''<",
"input":"<!DOCTYPE a PUBLIC''<",
-"output":["ParseError", ["DOCTYPE", "a", "", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
{"description":"<!DOCTYPE a PUBLIC''=",
"input":"<!DOCTYPE a PUBLIC''=",
-"output":["ParseError", ["DOCTYPE", "a", "", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
{"description":"<!DOCTYPE a PUBLIC''>",
"input":"<!DOCTYPE a PUBLIC''>",
-"output":[["DOCTYPE", "a", "", null, true]]},
+"output":["ParseError", ["DOCTYPE", "a", "", null, true]]},
{"description":"<!DOCTYPE a PUBLIC''?",
"input":"<!DOCTYPE a PUBLIC''?",
-"output":["ParseError", ["DOCTYPE", "a", "", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
{"description":"<!DOCTYPE a PUBLIC''@",
"input":"<!DOCTYPE a PUBLIC''@",
-"output":["ParseError", ["DOCTYPE", "a", "", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
{"description":"<!DOCTYPE a PUBLIC''A",
"input":"<!DOCTYPE a PUBLIC''A",
-"output":["ParseError", ["DOCTYPE", "a", "", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
{"description":"<!DOCTYPE a PUBLIC''B",
"input":"<!DOCTYPE a PUBLIC''B",
-"output":["ParseError", ["DOCTYPE", "a", "", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
{"description":"<!DOCTYPE a PUBLIC''Y",
"input":"<!DOCTYPE a PUBLIC''Y",
-"output":["ParseError", ["DOCTYPE", "a", "", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
{"description":"<!DOCTYPE a PUBLIC''Z",
"input":"<!DOCTYPE a PUBLIC''Z",
-"output":["ParseError", ["DOCTYPE", "a", "", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
{"description":"<!DOCTYPE a PUBLIC''`",
"input":"<!DOCTYPE a PUBLIC''`",
-"output":["ParseError", ["DOCTYPE", "a", "", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
{"description":"<!DOCTYPE a PUBLIC''a",
"input":"<!DOCTYPE a PUBLIC''a",
-"output":["ParseError", ["DOCTYPE", "a", "", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
{"description":"<!DOCTYPE a PUBLIC''b",
"input":"<!DOCTYPE a PUBLIC''b",
-"output":["ParseError", ["DOCTYPE", "a", "", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
{"description":"<!DOCTYPE a PUBLIC''y",
"input":"<!DOCTYPE a PUBLIC''y",
-"output":["ParseError", ["DOCTYPE", "a", "", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
{"description":"<!DOCTYPE a PUBLIC''z",
"input":"<!DOCTYPE a PUBLIC''z",
-"output":["ParseError", ["DOCTYPE", "a", "", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
{"description":"<!DOCTYPE a PUBLIC''{",
"input":"<!DOCTYPE a PUBLIC''{",
-"output":["ParseError", ["DOCTYPE", "a", "", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
{"description":"<!DOCTYPE a PUBLIC''\\uDBC0\\uDC00",
"input":"<!DOCTYPE a PUBLIC''\uDBC0\uDC00",
-"output":["ParseError", ["DOCTYPE", "a", "", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
{"description":"<!DOCTYPE a PUBLIC'(",
"input":"<!DOCTYPE a PUBLIC'(",
-"output":["ParseError", ["DOCTYPE", "a", "(", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "(", null, false]]},
{"description":"<!DOCTYPE a PUBLIC'-",
"input":"<!DOCTYPE a PUBLIC'-",
-"output":["ParseError", ["DOCTYPE", "a", "-", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "-", null, false]]},
{"description":"<!DOCTYPE a PUBLIC'/",
"input":"<!DOCTYPE a PUBLIC'/",
-"output":["ParseError", ["DOCTYPE", "a", "/", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "/", null, false]]},
{"description":"<!DOCTYPE a PUBLIC'0",
"input":"<!DOCTYPE a PUBLIC'0",
-"output":["ParseError", ["DOCTYPE", "a", "0", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "0", null, false]]},
{"description":"<!DOCTYPE a PUBLIC'1",
"input":"<!DOCTYPE a PUBLIC'1",
-"output":["ParseError", ["DOCTYPE", "a", "1", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "1", null, false]]},
{"description":"<!DOCTYPE a PUBLIC'9",
"input":"<!DOCTYPE a PUBLIC'9",
-"output":["ParseError", ["DOCTYPE", "a", "9", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "9", null, false]]},
{"description":"<!DOCTYPE a PUBLIC'<",
"input":"<!DOCTYPE a PUBLIC'<",
-"output":["ParseError", ["DOCTYPE", "a", "<", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "<", null, false]]},
{"description":"<!DOCTYPE a PUBLIC'=",
"input":"<!DOCTYPE a PUBLIC'=",
-"output":["ParseError", ["DOCTYPE", "a", "=", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "=", null, false]]},
{"description":"<!DOCTYPE a PUBLIC'>",
"input":"<!DOCTYPE a PUBLIC'>",
-"output":["ParseError", ["DOCTYPE", "a", "", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
{"description":"<!DOCTYPE a PUBLIC'?",
"input":"<!DOCTYPE a PUBLIC'?",
-"output":["ParseError", ["DOCTYPE", "a", "?", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "?", null, false]]},
{"description":"<!DOCTYPE a PUBLIC'@",
"input":"<!DOCTYPE a PUBLIC'@",
-"output":["ParseError", ["DOCTYPE", "a", "@", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "@", null, false]]},
{"description":"<!DOCTYPE a PUBLIC'A",
"input":"<!DOCTYPE a PUBLIC'A",
-"output":["ParseError", ["DOCTYPE", "a", "A", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "A", null, false]]},
{"description":"<!DOCTYPE a PUBLIC'B",
"input":"<!DOCTYPE a PUBLIC'B",
-"output":["ParseError", ["DOCTYPE", "a", "B", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "B", null, false]]},
{"description":"<!DOCTYPE a PUBLIC'Y",
"input":"<!DOCTYPE a PUBLIC'Y",
-"output":["ParseError", ["DOCTYPE", "a", "Y", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "Y", null, false]]},
{"description":"<!DOCTYPE a PUBLIC'Z",
"input":"<!DOCTYPE a PUBLIC'Z",
-"output":["ParseError", ["DOCTYPE", "a", "Z", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "Z", null, false]]},
{"description":"<!DOCTYPE a PUBLIC'`",
"input":"<!DOCTYPE a PUBLIC'`",
-"output":["ParseError", ["DOCTYPE", "a", "`", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "`", null, false]]},
{"description":"<!DOCTYPE a PUBLIC'a",
"input":"<!DOCTYPE a PUBLIC'a",
-"output":["ParseError", ["DOCTYPE", "a", "a", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "a", null, false]]},
{"description":"<!DOCTYPE a PUBLIC'b",
"input":"<!DOCTYPE a PUBLIC'b",
-"output":["ParseError", ["DOCTYPE", "a", "b", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "b", null, false]]},
{"description":"<!DOCTYPE a PUBLIC'y",
"input":"<!DOCTYPE a PUBLIC'y",
-"output":["ParseError", ["DOCTYPE", "a", "y", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "y", null, false]]},
{"description":"<!DOCTYPE a PUBLIC'z",
"input":"<!DOCTYPE a PUBLIC'z",
-"output":["ParseError", ["DOCTYPE", "a", "z", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "z", null, false]]},
{"description":"<!DOCTYPE a PUBLIC'{",
"input":"<!DOCTYPE a PUBLIC'{",
-"output":["ParseError", ["DOCTYPE", "a", "{", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "{", null, false]]},
{"description":"<!DOCTYPE a PUBLIC'\\uDBC0\\uDC00",
"input":"<!DOCTYPE a PUBLIC'\uDBC0\uDC00",
-"output":["ParseError", ["DOCTYPE", "a", "\uDBC0\uDC00", null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "\uDBC0\uDC00", null, false]]},
{"description":"<!DOCTYPE a PUBLIC(",
"input":"<!DOCTYPE a PUBLIC(",
@@ -1714,7 +1762,7 @@
{"description":"<!DOCTYPE a SYSTEM\\u0000",
"input":"<!DOCTYPE a SYSTEM\u0000",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
{"description":"<!DOCTYPE a SYSTEM\\u0008",
"input":"<!DOCTYPE a SYSTEM\u0008",
@@ -1754,135 +1802,135 @@
{"description":"<!DOCTYPE a SYSTEM\"",
"input":"<!DOCTYPE a SYSTEM\"",
-"output":["ParseError", ["DOCTYPE", "a", null, "", false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", false]]},
{"description":"<!DOCTYPE a SYSTEM\"\\u0000",
"input":"<!DOCTYPE a SYSTEM\"\u0000",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "\uFFFD", false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "\uFFFD", false]]},
{"description":"<!DOCTYPE a SYSTEM\"\\u0009",
"input":"<!DOCTYPE a SYSTEM\"\u0009",
-"output":["ParseError", ["DOCTYPE", "a", null, "\u0009", false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "\u0009", false]]},
{"description":"<!DOCTYPE a SYSTEM\"\\u000A",
"input":"<!DOCTYPE a SYSTEM\"\u000A",
-"output":["ParseError", ["DOCTYPE", "a", null, "\u000A", false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "\u000A", false]]},
{"description":"<!DOCTYPE a SYSTEM\"\\u000B",
"input":"<!DOCTYPE a SYSTEM\"\u000B",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "\u000B", false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "\u000B", false]]},
{"description":"<!DOCTYPE a SYSTEM\"\\u000C",
"input":"<!DOCTYPE a SYSTEM\"\u000C",
-"output":["ParseError", ["DOCTYPE", "a", null, "\u000C", false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "\u000C", false]]},
{"description":"<!DOCTYPE a SYSTEM\" ",
"input":"<!DOCTYPE a SYSTEM\" ",
-"output":["ParseError", ["DOCTYPE", "a", null, " ", false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, " ", false]]},
{"description":"<!DOCTYPE a SYSTEM\"!",
"input":"<!DOCTYPE a SYSTEM\"!",
-"output":["ParseError", ["DOCTYPE", "a", null, "!", false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "!", false]]},
{"description":"<!DOCTYPE a SYSTEM\"\"",
"input":"<!DOCTYPE a SYSTEM\"\"",
-"output":["ParseError", ["DOCTYPE", "a", null, "", false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", false]]},
{"description":"<!DOCTYPE a SYSTEM\"#",
"input":"<!DOCTYPE a SYSTEM\"#",
-"output":["ParseError", ["DOCTYPE", "a", null, "#", false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "#", false]]},
{"description":"<!DOCTYPE a SYSTEM\"&",
"input":"<!DOCTYPE a SYSTEM\"&",
-"output":["ParseError", ["DOCTYPE", "a", null, "&", false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "&", false]]},
{"description":"<!DOCTYPE a SYSTEM\"'",
"input":"<!DOCTYPE a SYSTEM\"'",
-"output":["ParseError", ["DOCTYPE", "a", null, "'", false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "'", false]]},
{"description":"<!DOCTYPE a SYSTEM\"-",
"input":"<!DOCTYPE a SYSTEM\"-",
-"output":["ParseError", ["DOCTYPE", "a", null, "-", false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "-", false]]},
{"description":"<!DOCTYPE a SYSTEM\"/",
"input":"<!DOCTYPE a SYSTEM\"/",
-"output":["ParseError", ["DOCTYPE", "a", null, "/", false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "/", false]]},
{"description":"<!DOCTYPE a SYSTEM\"0",
"input":"<!DOCTYPE a SYSTEM\"0",
-"output":["ParseError", ["DOCTYPE", "a", null, "0", false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "0", false]]},
{"description":"<!DOCTYPE a SYSTEM\"1",
"input":"<!DOCTYPE a SYSTEM\"1",
-"output":["ParseError", ["DOCTYPE", "a", null, "1", false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "1", false]]},
{"description":"<!DOCTYPE a SYSTEM\"9",
"input":"<!DOCTYPE a SYSTEM\"9",
-"output":["ParseError", ["DOCTYPE", "a", null, "9", false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "9", false]]},
{"description":"<!DOCTYPE a SYSTEM\"<",
"input":"<!DOCTYPE a SYSTEM\"<",
-"output":["ParseError", ["DOCTYPE", "a", null, "<", false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "<", false]]},
{"description":"<!DOCTYPE a SYSTEM\"=",
"input":"<!DOCTYPE a SYSTEM\"=",
-"output":["ParseError", ["DOCTYPE", "a", null, "=", false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "=", false]]},
{"description":"<!DOCTYPE a SYSTEM\">",
"input":"<!DOCTYPE a SYSTEM\">",
-"output":["ParseError", ["DOCTYPE", "a", null, "", false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", false]]},
{"description":"<!DOCTYPE a SYSTEM\"?",
"input":"<!DOCTYPE a SYSTEM\"?",
-"output":["ParseError", ["DOCTYPE", "a", null, "?", false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "?", false]]},
{"description":"<!DOCTYPE a SYSTEM\"@",
"input":"<!DOCTYPE a SYSTEM\"@",
-"output":["ParseError", ["DOCTYPE", "a", null, "@", false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "@", false]]},
{"description":"<!DOCTYPE a SYSTEM\"A",
"input":"<!DOCTYPE a SYSTEM\"A",
-"output":["ParseError", ["DOCTYPE", "a", null, "A", false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "A", false]]},
{"description":"<!DOCTYPE a SYSTEM\"B",
"input":"<!DOCTYPE a SYSTEM\"B",
-"output":["ParseError", ["DOCTYPE", "a", null, "B", false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "B", false]]},
{"description":"<!DOCTYPE a SYSTEM\"Y",
"input":"<!DOCTYPE a SYSTEM\"Y",
-"output":["ParseError", ["DOCTYPE", "a", null, "Y", false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "Y", false]]},
{"description":"<!DOCTYPE a SYSTEM\"Z",
"input":"<!DOCTYPE a SYSTEM\"Z",
-"output":["ParseError", ["DOCTYPE", "a", null, "Z", false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "Z", false]]},
{"description":"<!DOCTYPE a SYSTEM\"`",
"input":"<!DOCTYPE a SYSTEM\"`",
-"output":["ParseError", ["DOCTYPE", "a", null, "`", false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "`", false]]},
{"description":"<!DOCTYPE a SYSTEM\"a",
"input":"<!DOCTYPE a SYSTEM\"a",
-"output":["ParseError", ["DOCTYPE", "a", null, "a", false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "a", false]]},
{"description":"<!DOCTYPE a SYSTEM\"b",
"input":"<!DOCTYPE a SYSTEM\"b",
-"output":["ParseError", ["DOCTYPE", "a", null, "b", false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "b", false]]},
{"description":"<!DOCTYPE a SYSTEM\"y",
"input":"<!DOCTYPE a SYSTEM\"y",
-"output":["ParseError", ["DOCTYPE", "a", null, "y", false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "y", false]]},
{"description":"<!DOCTYPE a SYSTEM\"z",
"input":"<!DOCTYPE a SYSTEM\"z",
-"output":["ParseError", ["DOCTYPE", "a", null, "z", false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "z", false]]},
{"description":"<!DOCTYPE a SYSTEM\"{",
"input":"<!DOCTYPE a SYSTEM\"{",
-"output":["ParseError", ["DOCTYPE", "a", null, "{", false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "{", false]]},
{"description":"<!DOCTYPE a SYSTEM\"\\uDBC0\\uDC00",
"input":"<!DOCTYPE a SYSTEM\"\uDBC0\uDC00",
-"output":["ParseError", ["DOCTYPE", "a", null, "\uDBC0\uDC00", false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "\uDBC0\uDC00", false]]},
{"description":"<!DOCTYPE a SYSTEM#",
"input":"<!DOCTYPE a SYSTEM#",
@@ -1894,47 +1942,47 @@
{"description":"<!DOCTYPE a SYSTEM'",
"input":"<!DOCTYPE a SYSTEM'",
-"output":["ParseError", ["DOCTYPE", "a", null, "", false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", false]]},
{"description":"<!DOCTYPE a SYSTEM'\\u0000",
"input":"<!DOCTYPE a SYSTEM'\u0000",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "\uFFFD", false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "\uFFFD", false]]},
{"description":"<!DOCTYPE a SYSTEM'\\u0009",
"input":"<!DOCTYPE a SYSTEM'\u0009",
-"output":["ParseError", ["DOCTYPE", "a", null, "\u0009", false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "\u0009", false]]},
{"description":"<!DOCTYPE a SYSTEM'\\u000A",
"input":"<!DOCTYPE a SYSTEM'\u000A",
-"output":["ParseError", ["DOCTYPE", "a", null, "\u000A", false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "\u000A", false]]},
{"description":"<!DOCTYPE a SYSTEM'\\u000B",
"input":"<!DOCTYPE a SYSTEM'\u000B",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "\u000B", false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "\u000B", false]]},
{"description":"<!DOCTYPE a SYSTEM'\\u000C",
"input":"<!DOCTYPE a SYSTEM'\u000C",
-"output":["ParseError", ["DOCTYPE", "a", null, "\u000C", false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "\u000C", false]]},
{"description":"<!DOCTYPE a SYSTEM' ",
"input":"<!DOCTYPE a SYSTEM' ",
-"output":["ParseError", ["DOCTYPE", "a", null, " ", false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, " ", false]]},
{"description":"<!DOCTYPE a SYSTEM'!",
"input":"<!DOCTYPE a SYSTEM'!",
-"output":["ParseError", ["DOCTYPE", "a", null, "!", false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "!", false]]},
{"description":"<!DOCTYPE a SYSTEM'\"",
"input":"<!DOCTYPE a SYSTEM'\"",
-"output":["ParseError", ["DOCTYPE", "a", null, "\"", false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "\"", false]]},
{"description":"<!DOCTYPE a SYSTEM'&",
"input":"<!DOCTYPE a SYSTEM'&",
-"output":["ParseError", ["DOCTYPE", "a", null, "&", false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "&", false]]},
{"description":"<!DOCTYPE a SYSTEM''",
"input":"<!DOCTYPE a SYSTEM''",
-"output":["ParseError", ["DOCTYPE", "a", null, "", false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", false]]},
{"description":"<!DOCTYPE a SYSTEM''\\u0000",
"input":"<!DOCTYPE a SYSTEM''\u0000",
@@ -1942,223 +1990,223 @@
{"description":"<!DOCTYPE a SYSTEM''\\u0008",
"input":"<!DOCTYPE a SYSTEM''\u0008",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
{"description":"<!DOCTYPE a SYSTEM''\\u0009",
"input":"<!DOCTYPE a SYSTEM''\u0009",
-"output":["ParseError", ["DOCTYPE", "a", null, "", false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", false]]},
{"description":"<!DOCTYPE a SYSTEM''\\u000A",
"input":"<!DOCTYPE a SYSTEM''\u000A",
-"output":["ParseError", ["DOCTYPE", "a", null, "", false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", false]]},
{"description":"<!DOCTYPE a SYSTEM''\\u000B",
"input":"<!DOCTYPE a SYSTEM''\u000B",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
{"description":"<!DOCTYPE a SYSTEM''\\u000C",
"input":"<!DOCTYPE a SYSTEM''\u000C",
-"output":["ParseError", ["DOCTYPE", "a", null, "", false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", false]]},
{"description":"<!DOCTYPE a SYSTEM''\\u000D",
"input":"<!DOCTYPE a SYSTEM''\u000D",
-"output":["ParseError", ["DOCTYPE", "a", null, "", false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", false]]},
{"description":"<!DOCTYPE a SYSTEM''\\u001F",
"input":"<!DOCTYPE a SYSTEM''\u001F",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
{"description":"<!DOCTYPE a SYSTEM'' ",
"input":"<!DOCTYPE a SYSTEM'' ",
-"output":["ParseError", ["DOCTYPE", "a", null, "", false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", false]]},
{"description":"<!DOCTYPE a SYSTEM''!",
"input":"<!DOCTYPE a SYSTEM''!",
-"output":["ParseError", ["DOCTYPE", "a", null, "", true]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
{"description":"<!DOCTYPE a SYSTEM''\"",
"input":"<!DOCTYPE a SYSTEM''\"",
-"output":["ParseError", ["DOCTYPE", "a", null, "", true]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
{"description":"<!DOCTYPE a SYSTEM''&",
"input":"<!DOCTYPE a SYSTEM''&",
-"output":["ParseError", ["DOCTYPE", "a", null, "", true]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
{"description":"<!DOCTYPE a SYSTEM'''",
"input":"<!DOCTYPE a SYSTEM'''",
-"output":["ParseError", ["DOCTYPE", "a", null, "", true]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
{"description":"<!DOCTYPE a SYSTEM''-",
"input":"<!DOCTYPE a SYSTEM''-",
-"output":["ParseError", ["DOCTYPE", "a", null, "", true]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
{"description":"<!DOCTYPE a SYSTEM''/",
"input":"<!DOCTYPE a SYSTEM''/",
-"output":["ParseError", ["DOCTYPE", "a", null, "", true]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
{"description":"<!DOCTYPE a SYSTEM''0",
"input":"<!DOCTYPE a SYSTEM''0",
-"output":["ParseError", ["DOCTYPE", "a", null, "", true]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
{"description":"<!DOCTYPE a SYSTEM''1",
"input":"<!DOCTYPE a SYSTEM''1",
-"output":["ParseError", ["DOCTYPE", "a", null, "", true]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
{"description":"<!DOCTYPE a SYSTEM''9",
"input":"<!DOCTYPE a SYSTEM''9",
-"output":["ParseError", ["DOCTYPE", "a", null, "", true]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
{"description":"<!DOCTYPE a SYSTEM''<",
"input":"<!DOCTYPE a SYSTEM''<",
-"output":["ParseError", ["DOCTYPE", "a", null, "", true]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
{"description":"<!DOCTYPE a SYSTEM''=",
"input":"<!DOCTYPE a SYSTEM''=",
-"output":["ParseError", ["DOCTYPE", "a", null, "", true]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
{"description":"<!DOCTYPE a SYSTEM''>",
"input":"<!DOCTYPE a SYSTEM''>",
-"output":[["DOCTYPE", "a", null, "", true]]},
+"output":["ParseError", ["DOCTYPE", "a", null, "", true]]},
{"description":"<!DOCTYPE a SYSTEM''?",
"input":"<!DOCTYPE a SYSTEM''?",
-"output":["ParseError", ["DOCTYPE", "a", null, "", true]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
{"description":"<!DOCTYPE a SYSTEM''@",
"input":"<!DOCTYPE a SYSTEM''@",
-"output":["ParseError", ["DOCTYPE", "a", null, "", true]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
{"description":"<!DOCTYPE a SYSTEM''A",
"input":"<!DOCTYPE a SYSTEM''A",
-"output":["ParseError", ["DOCTYPE", "a", null, "", true]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
{"description":"<!DOCTYPE a SYSTEM''B",
"input":"<!DOCTYPE a SYSTEM''B",
-"output":["ParseError", ["DOCTYPE", "a", null, "", true]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
{"description":"<!DOCTYPE a SYSTEM''Y",
"input":"<!DOCTYPE a SYSTEM''Y",
-"output":["ParseError", ["DOCTYPE", "a", null, "", true]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
{"description":"<!DOCTYPE a SYSTEM''Z",
"input":"<!DOCTYPE a SYSTEM''Z",
-"output":["ParseError", ["DOCTYPE", "a", null, "", true]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
{"description":"<!DOCTYPE a SYSTEM''`",
"input":"<!DOCTYPE a SYSTEM''`",
-"output":["ParseError", ["DOCTYPE", "a", null, "", true]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
{"description":"<!DOCTYPE a SYSTEM''a",
"input":"<!DOCTYPE a SYSTEM''a",
-"output":["ParseError", ["DOCTYPE", "a", null, "", true]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
{"description":"<!DOCTYPE a SYSTEM''b",
"input":"<!DOCTYPE a SYSTEM''b",
-"output":["ParseError", ["DOCTYPE", "a", null, "", true]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
{"description":"<!DOCTYPE a SYSTEM''y",
"input":"<!DOCTYPE a SYSTEM''y",
-"output":["ParseError", ["DOCTYPE", "a", null, "", true]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
{"description":"<!DOCTYPE a SYSTEM''z",
"input":"<!DOCTYPE a SYSTEM''z",
-"output":["ParseError", ["DOCTYPE", "a", null, "", true]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
{"description":"<!DOCTYPE a SYSTEM''{",
"input":"<!DOCTYPE a SYSTEM''{",
-"output":["ParseError", ["DOCTYPE", "a", null, "", true]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
{"description":"<!DOCTYPE a SYSTEM''\\uDBC0\\uDC00",
"input":"<!DOCTYPE a SYSTEM''\uDBC0\uDC00",
-"output":["ParseError", ["DOCTYPE", "a", null, "", true]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
{"description":"<!DOCTYPE a SYSTEM'(",
"input":"<!DOCTYPE a SYSTEM'(",
-"output":["ParseError", ["DOCTYPE", "a", null, "(", false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "(", false]]},
{"description":"<!DOCTYPE a SYSTEM'-",
"input":"<!DOCTYPE a SYSTEM'-",
-"output":["ParseError", ["DOCTYPE", "a", null, "-", false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "-", false]]},
{"description":"<!DOCTYPE a SYSTEM'/",
"input":"<!DOCTYPE a SYSTEM'/",
-"output":["ParseError", ["DOCTYPE", "a", null, "/", false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "/", false]]},
{"description":"<!DOCTYPE a SYSTEM'0",
"input":"<!DOCTYPE a SYSTEM'0",
-"output":["ParseError", ["DOCTYPE", "a", null, "0", false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "0", false]]},
{"description":"<!DOCTYPE a SYSTEM'1",
"input":"<!DOCTYPE a SYSTEM'1",
-"output":["ParseError", ["DOCTYPE", "a", null, "1", false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "1", false]]},
{"description":"<!DOCTYPE a SYSTEM'9",
"input":"<!DOCTYPE a SYSTEM'9",
-"output":["ParseError", ["DOCTYPE", "a", null, "9", false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "9", false]]},
{"description":"<!DOCTYPE a SYSTEM'<",
"input":"<!DOCTYPE a SYSTEM'<",
-"output":["ParseError", ["DOCTYPE", "a", null, "<", false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "<", false]]},
{"description":"<!DOCTYPE a SYSTEM'=",
"input":"<!DOCTYPE a SYSTEM'=",
-"output":["ParseError", ["DOCTYPE", "a", null, "=", false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "=", false]]},
{"description":"<!DOCTYPE a SYSTEM'>",
"input":"<!DOCTYPE a SYSTEM'>",
-"output":["ParseError", ["DOCTYPE", "a", null, "", false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", false]]},
{"description":"<!DOCTYPE a SYSTEM'?",
"input":"<!DOCTYPE a SYSTEM'?",
-"output":["ParseError", ["DOCTYPE", "a", null, "?", false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "?", false]]},
{"description":"<!DOCTYPE a SYSTEM'@",
"input":"<!DOCTYPE a SYSTEM'@",
-"output":["ParseError", ["DOCTYPE", "a", null, "@", false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "@", false]]},
{"description":"<!DOCTYPE a SYSTEM'A",
"input":"<!DOCTYPE a SYSTEM'A",
-"output":["ParseError", ["DOCTYPE", "a", null, "A", false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "A", false]]},
{"description":"<!DOCTYPE a SYSTEM'B",
"input":"<!DOCTYPE a SYSTEM'B",
-"output":["ParseError", ["DOCTYPE", "a", null, "B", false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "B", false]]},
{"description":"<!DOCTYPE a SYSTEM'Y",
"input":"<!DOCTYPE a SYSTEM'Y",
-"output":["ParseError", ["DOCTYPE", "a", null, "Y", false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "Y", false]]},
{"description":"<!DOCTYPE a SYSTEM'Z",
"input":"<!DOCTYPE a SYSTEM'Z",
-"output":["ParseError", ["DOCTYPE", "a", null, "Z", false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "Z", false]]},
{"description":"<!DOCTYPE a SYSTEM'`",
"input":"<!DOCTYPE a SYSTEM'`",
-"output":["ParseError", ["DOCTYPE", "a", null, "`", false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "`", false]]},
{"description":"<!DOCTYPE a SYSTEM'a",
"input":"<!DOCTYPE a SYSTEM'a",
-"output":["ParseError", ["DOCTYPE", "a", null, "a", false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "a", false]]},
{"description":"<!DOCTYPE a SYSTEM'b",
"input":"<!DOCTYPE a SYSTEM'b",
-"output":["ParseError", ["DOCTYPE", "a", null, "b", false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "b", false]]},
{"description":"<!DOCTYPE a SYSTEM'y",
"input":"<!DOCTYPE a SYSTEM'y",
-"output":["ParseError", ["DOCTYPE", "a", null, "y", false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "y", false]]},
{"description":"<!DOCTYPE a SYSTEM'z",
"input":"<!DOCTYPE a SYSTEM'z",
-"output":["ParseError", ["DOCTYPE", "a", null, "z", false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "z", false]]},
{"description":"<!DOCTYPE a SYSTEM'{",
"input":"<!DOCTYPE a SYSTEM'{",
-"output":["ParseError", ["DOCTYPE", "a", null, "{", false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "{", false]]},
{"description":"<!DOCTYPE a SYSTEM'\\uDBC0\\uDC00",
"input":"<!DOCTYPE a SYSTEM'\uDBC0\uDC00",
-"output":["ParseError", ["DOCTYPE", "a", null, "\uDBC0\uDC00", false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "\uDBC0\uDC00", false]]},
{"description":"<!DOCTYPE a SYSTEM(",
"input":"<!DOCTYPE a SYSTEM(",
@@ -2266,7 +2314,7 @@
{"description":"<!DOCTYPE a a\\u0000",
"input":"<!DOCTYPE a a\u0000",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+"output":["ParseError", ["DOCTYPE", "a", null, null, false]]},
{"description":"<!DOCTYPE a a\\u0009",
"input":"<!DOCTYPE a a\u0009",
@@ -2578,7 +2626,7 @@
{"description":"<!DOCTYPE>",
"input":"<!DOCTYPE>",
-"output":["ParseError", "ParseError", ["DOCTYPE", "", null, null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", null, null, null, false]]},
{"description":"<!DOCTYPE?",
"input":"<!DOCTYPE?",
@@ -2650,7 +2698,7 @@
{"description":"<!DOCTYPEa \\u0000",
"input":"<!DOCTYPEa \u0000",
-"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
{"description":"<!DOCTYPEa \\u0008",
"input":"<!DOCTYPEa \u0008",
@@ -2754,7 +2802,7 @@
{"description":"<!DOCTYPEa PUBLIC\\u0000",
"input":"<!DOCTYPEa PUBLIC\u0000",
-"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
{"description":"<!DOCTYPEa PUBLIC\\u0008",
"input":"<!DOCTYPEa PUBLIC\u0008",
@@ -2794,135 +2842,135 @@
{"description":"<!DOCTYPEa PUBLIC\"",
"input":"<!DOCTYPEa PUBLIC\"",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
{"description":"<!DOCTYPEa PUBLIC\"\\u0000",
"input":"<!DOCTYPEa PUBLIC\"\u0000",
-"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "\uFFFD", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "\uFFFD", null, false]]},
{"description":"<!DOCTYPEa PUBLIC\"\\u0009",
"input":"<!DOCTYPEa PUBLIC\"\u0009",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "\u0009", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "\u0009", null, false]]},
{"description":"<!DOCTYPEa PUBLIC\"\\u000A",
"input":"<!DOCTYPEa PUBLIC\"\u000A",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "\u000A", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "\u000A", null, false]]},
{"description":"<!DOCTYPEa PUBLIC\"\\u000B",
"input":"<!DOCTYPEa PUBLIC\"\u000B",
-"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "\u000B", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "\u000B", null, false]]},
{"description":"<!DOCTYPEa PUBLIC\"\\u000C",
"input":"<!DOCTYPEa PUBLIC\"\u000C",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "\u000C", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "\u000C", null, false]]},
{"description":"<!DOCTYPEa PUBLIC\" ",
"input":"<!DOCTYPEa PUBLIC\" ",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", " ", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", " ", null, false]]},
{"description":"<!DOCTYPEa PUBLIC\"!",
"input":"<!DOCTYPEa PUBLIC\"!",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "!", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "!", null, false]]},
{"description":"<!DOCTYPEa PUBLIC\"\"",
"input":"<!DOCTYPEa PUBLIC\"\"",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
{"description":"<!DOCTYPEa PUBLIC\"#",
"input":"<!DOCTYPEa PUBLIC\"#",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "#", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "#", null, false]]},
{"description":"<!DOCTYPEa PUBLIC\"&",
"input":"<!DOCTYPEa PUBLIC\"&",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "&", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "&", null, false]]},
{"description":"<!DOCTYPEa PUBLIC\"'",
"input":"<!DOCTYPEa PUBLIC\"'",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "'", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "'", null, false]]},
{"description":"<!DOCTYPEa PUBLIC\"-",
"input":"<!DOCTYPEa PUBLIC\"-",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "-", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "-", null, false]]},
{"description":"<!DOCTYPEa PUBLIC\"/",
"input":"<!DOCTYPEa PUBLIC\"/",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "/", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "/", null, false]]},
{"description":"<!DOCTYPEa PUBLIC\"0",
"input":"<!DOCTYPEa PUBLIC\"0",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "0", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "0", null, false]]},
{"description":"<!DOCTYPEa PUBLIC\"1",
"input":"<!DOCTYPEa PUBLIC\"1",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "1", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "1", null, false]]},
{"description":"<!DOCTYPEa PUBLIC\"9",
"input":"<!DOCTYPEa PUBLIC\"9",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "9", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "9", null, false]]},
{"description":"<!DOCTYPEa PUBLIC\"<",
"input":"<!DOCTYPEa PUBLIC\"<",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "<", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "<", null, false]]},
{"description":"<!DOCTYPEa PUBLIC\"=",
"input":"<!DOCTYPEa PUBLIC\"=",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "=", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "=", null, false]]},
{"description":"<!DOCTYPEa PUBLIC\">",
"input":"<!DOCTYPEa PUBLIC\">",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
{"description":"<!DOCTYPEa PUBLIC\"?",
"input":"<!DOCTYPEa PUBLIC\"?",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "?", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "?", null, false]]},
{"description":"<!DOCTYPEa PUBLIC\"@",
"input":"<!DOCTYPEa PUBLIC\"@",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "@", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "@", null, false]]},
{"description":"<!DOCTYPEa PUBLIC\"A",
"input":"<!DOCTYPEa PUBLIC\"A",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "A", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "A", null, false]]},
{"description":"<!DOCTYPEa PUBLIC\"B",
"input":"<!DOCTYPEa PUBLIC\"B",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "B", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "B", null, false]]},
{"description":"<!DOCTYPEa PUBLIC\"Y",
"input":"<!DOCTYPEa PUBLIC\"Y",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "Y", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "Y", null, false]]},
{"description":"<!DOCTYPEa PUBLIC\"Z",
"input":"<!DOCTYPEa PUBLIC\"Z",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "Z", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "Z", null, false]]},
{"description":"<!DOCTYPEa PUBLIC\"`",
"input":"<!DOCTYPEa PUBLIC\"`",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "`", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "`", null, false]]},
{"description":"<!DOCTYPEa PUBLIC\"a",
"input":"<!DOCTYPEa PUBLIC\"a",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "a", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "a", null, false]]},
{"description":"<!DOCTYPEa PUBLIC\"b",
"input":"<!DOCTYPEa PUBLIC\"b",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "b", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "b", null, false]]},
{"description":"<!DOCTYPEa PUBLIC\"y",
"input":"<!DOCTYPEa PUBLIC\"y",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "y", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "y", null, false]]},
{"description":"<!DOCTYPEa PUBLIC\"z",
"input":"<!DOCTYPEa PUBLIC\"z",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "z", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "z", null, false]]},
{"description":"<!DOCTYPEa PUBLIC\"{",
"input":"<!DOCTYPEa PUBLIC\"{",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "{", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "{", null, false]]},
{"description":"<!DOCTYPEa PUBLIC\"\\uDBC0\\uDC00",
"input":"<!DOCTYPEa PUBLIC\"\uDBC0\uDC00",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "\uDBC0\uDC00", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "\uDBC0\uDC00", null, false]]},
{"description":"<!DOCTYPEa PUBLIC#",
"input":"<!DOCTYPEa PUBLIC#",
@@ -2934,47 +2982,47 @@
{"description":"<!DOCTYPEa PUBLIC'",
"input":"<!DOCTYPEa PUBLIC'",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
{"description":"<!DOCTYPEa PUBLIC'\\u0000",
"input":"<!DOCTYPEa PUBLIC'\u0000",
-"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "\uFFFD", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "\uFFFD", null, false]]},
{"description":"<!DOCTYPEa PUBLIC'\\u0009",
"input":"<!DOCTYPEa PUBLIC'\u0009",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "\u0009", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "\u0009", null, false]]},
{"description":"<!DOCTYPEa PUBLIC'\\u000A",
"input":"<!DOCTYPEa PUBLIC'\u000A",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "\u000A", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "\u000A", null, false]]},
{"description":"<!DOCTYPEa PUBLIC'\\u000B",
"input":"<!DOCTYPEa PUBLIC'\u000B",
-"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "\u000B", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "\u000B", null, false]]},
{"description":"<!DOCTYPEa PUBLIC'\\u000C",
"input":"<!DOCTYPEa PUBLIC'\u000C",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "\u000C", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "\u000C", null, false]]},
{"description":"<!DOCTYPEa PUBLIC' ",
"input":"<!DOCTYPEa PUBLIC' ",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", " ", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", " ", null, false]]},
{"description":"<!DOCTYPEa PUBLIC'!",
"input":"<!DOCTYPEa PUBLIC'!",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "!", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "!", null, false]]},
{"description":"<!DOCTYPEa PUBLIC'\"",
"input":"<!DOCTYPEa PUBLIC'\"",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "\"", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "\"", null, false]]},
{"description":"<!DOCTYPEa PUBLIC'&",
"input":"<!DOCTYPEa PUBLIC'&",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "&", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "&", null, false]]},
{"description":"<!DOCTYPEa PUBLIC''",
"input":"<!DOCTYPEa PUBLIC''",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
{"description":"<!DOCTYPEa PUBLIC''\\u0000",
"input":"<!DOCTYPEa PUBLIC''\u0000",
@@ -2982,231 +3030,231 @@
{"description":"<!DOCTYPEa PUBLIC''\\u0008",
"input":"<!DOCTYPEa PUBLIC''\u0008",
-"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
{"description":"<!DOCTYPEa PUBLIC''\\u0009",
"input":"<!DOCTYPEa PUBLIC''\u0009",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
{"description":"<!DOCTYPEa PUBLIC''\\u000A",
"input":"<!DOCTYPEa PUBLIC''\u000A",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
{"description":"<!DOCTYPEa PUBLIC''\\u000B",
"input":"<!DOCTYPEa PUBLIC''\u000B",
-"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
{"description":"<!DOCTYPEa PUBLIC''\\u000C",
"input":"<!DOCTYPEa PUBLIC''\u000C",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
{"description":"<!DOCTYPEa PUBLIC''\\u000D",
"input":"<!DOCTYPEa PUBLIC''\u000D",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
{"description":"<!DOCTYPEa PUBLIC''\\u001F",
"input":"<!DOCTYPEa PUBLIC''\u001F",
-"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
{"description":"<!DOCTYPEa PUBLIC'' ",
"input":"<!DOCTYPEa PUBLIC'' ",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
{"description":"<!DOCTYPEa PUBLIC''!",
"input":"<!DOCTYPEa PUBLIC''!",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
{"description":"<!DOCTYPEa PUBLIC''\"",
"input":"<!DOCTYPEa PUBLIC''\"",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", "", false]]},
+"output":["ParseError", "ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", "", false]]},
{"description":"<!DOCTYPEa PUBLIC''#",
"input":"<!DOCTYPEa PUBLIC''#",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
{"description":"<!DOCTYPEa PUBLIC''&",
"input":"<!DOCTYPEa PUBLIC''&",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
{"description":"<!DOCTYPEa PUBLIC'''",
"input":"<!DOCTYPEa PUBLIC'''",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", "", false]]},
+"output":["ParseError", "ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", "", false]]},
{"description":"<!DOCTYPEa PUBLIC''(",
"input":"<!DOCTYPEa PUBLIC''(",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
{"description":"<!DOCTYPEa PUBLIC''-",
"input":"<!DOCTYPEa PUBLIC''-",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
{"description":"<!DOCTYPEa PUBLIC''/",
"input":"<!DOCTYPEa PUBLIC''/",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
{"description":"<!DOCTYPEa PUBLIC''0",
"input":"<!DOCTYPEa PUBLIC''0",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
{"description":"<!DOCTYPEa PUBLIC''1",
"input":"<!DOCTYPEa PUBLIC''1",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
{"description":"<!DOCTYPEa PUBLIC''9",
"input":"<!DOCTYPEa PUBLIC''9",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
{"description":"<!DOCTYPEa PUBLIC''<",
"input":"<!DOCTYPEa PUBLIC''<",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
{"description":"<!DOCTYPEa PUBLIC''=",
"input":"<!DOCTYPEa PUBLIC''=",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
{"description":"<!DOCTYPEa PUBLIC''>",
"input":"<!DOCTYPEa PUBLIC''>",
-"output":["ParseError", ["DOCTYPE", "a", "", null, true]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, true]]},
{"description":"<!DOCTYPEa PUBLIC''?",
"input":"<!DOCTYPEa PUBLIC''?",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
{"description":"<!DOCTYPEa PUBLIC''@",
"input":"<!DOCTYPEa PUBLIC''@",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
{"description":"<!DOCTYPEa PUBLIC''A",
"input":"<!DOCTYPEa PUBLIC''A",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
{"description":"<!DOCTYPEa PUBLIC''B",
"input":"<!DOCTYPEa PUBLIC''B",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
{"description":"<!DOCTYPEa PUBLIC''Y",
"input":"<!DOCTYPEa PUBLIC''Y",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
{"description":"<!DOCTYPEa PUBLIC''Z",
"input":"<!DOCTYPEa PUBLIC''Z",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
{"description":"<!DOCTYPEa PUBLIC''`",
"input":"<!DOCTYPEa PUBLIC''`",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
{"description":"<!DOCTYPEa PUBLIC''a",
"input":"<!DOCTYPEa PUBLIC''a",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
{"description":"<!DOCTYPEa PUBLIC''b",
"input":"<!DOCTYPEa PUBLIC''b",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
{"description":"<!DOCTYPEa PUBLIC''y",
"input":"<!DOCTYPEa PUBLIC''y",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
{"description":"<!DOCTYPEa PUBLIC''z",
"input":"<!DOCTYPEa PUBLIC''z",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
{"description":"<!DOCTYPEa PUBLIC''{",
"input":"<!DOCTYPEa PUBLIC''{",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
{"description":"<!DOCTYPEa PUBLIC''\\uDBC0\\uDC00",
"input":"<!DOCTYPEa PUBLIC''\uDBC0\uDC00",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
{"description":"<!DOCTYPEa PUBLIC'(",
"input":"<!DOCTYPEa PUBLIC'(",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "(", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "(", null, false]]},
{"description":"<!DOCTYPEa PUBLIC'-",
"input":"<!DOCTYPEa PUBLIC'-",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "-", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "-", null, false]]},
{"description":"<!DOCTYPEa PUBLIC'/",
"input":"<!DOCTYPEa PUBLIC'/",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "/", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "/", null, false]]},
{"description":"<!DOCTYPEa PUBLIC'0",
"input":"<!DOCTYPEa PUBLIC'0",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "0", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "0", null, false]]},
{"description":"<!DOCTYPEa PUBLIC'1",
"input":"<!DOCTYPEa PUBLIC'1",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "1", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "1", null, false]]},
{"description":"<!DOCTYPEa PUBLIC'9",
"input":"<!DOCTYPEa PUBLIC'9",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "9", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "9", null, false]]},
{"description":"<!DOCTYPEa PUBLIC'<",
"input":"<!DOCTYPEa PUBLIC'<",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "<", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "<", null, false]]},
{"description":"<!DOCTYPEa PUBLIC'=",
"input":"<!DOCTYPEa PUBLIC'=",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "=", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "=", null, false]]},
{"description":"<!DOCTYPEa PUBLIC'>",
"input":"<!DOCTYPEa PUBLIC'>",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "", null, false]]},
{"description":"<!DOCTYPEa PUBLIC'?",
"input":"<!DOCTYPEa PUBLIC'?",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "?", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "?", null, false]]},
{"description":"<!DOCTYPEa PUBLIC'@",
"input":"<!DOCTYPEa PUBLIC'@",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "@", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "@", null, false]]},
{"description":"<!DOCTYPEa PUBLIC'A",
"input":"<!DOCTYPEa PUBLIC'A",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "A", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "A", null, false]]},
{"description":"<!DOCTYPEa PUBLIC'B",
"input":"<!DOCTYPEa PUBLIC'B",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "B", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "B", null, false]]},
{"description":"<!DOCTYPEa PUBLIC'Y",
"input":"<!DOCTYPEa PUBLIC'Y",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "Y", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "Y", null, false]]},
{"description":"<!DOCTYPEa PUBLIC'Z",
"input":"<!DOCTYPEa PUBLIC'Z",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "Z", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "Z", null, false]]},
{"description":"<!DOCTYPEa PUBLIC'`",
"input":"<!DOCTYPEa PUBLIC'`",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "`", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "`", null, false]]},
{"description":"<!DOCTYPEa PUBLIC'a",
"input":"<!DOCTYPEa PUBLIC'a",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "a", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "a", null, false]]},
{"description":"<!DOCTYPEa PUBLIC'b",
"input":"<!DOCTYPEa PUBLIC'b",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "b", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "b", null, false]]},
{"description":"<!DOCTYPEa PUBLIC'y",
"input":"<!DOCTYPEa PUBLIC'y",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "y", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "y", null, false]]},
{"description":"<!DOCTYPEa PUBLIC'z",
"input":"<!DOCTYPEa PUBLIC'z",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "z", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "z", null, false]]},
{"description":"<!DOCTYPEa PUBLIC'{",
"input":"<!DOCTYPEa PUBLIC'{",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "{", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "{", null, false]]},
{"description":"<!DOCTYPEa PUBLIC'\\uDBC0\\uDC00",
"input":"<!DOCTYPEa PUBLIC'\uDBC0\uDC00",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", "\uDBC0\uDC00", null, false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", "\uDBC0\uDC00", null, false]]},
{"description":"<!DOCTYPEa PUBLIC(",
"input":"<!DOCTYPEa PUBLIC(",
@@ -3302,7 +3350,7 @@
{"description":"<!DOCTYPEa SYSTEM\\u0000",
"input":"<!DOCTYPEa SYSTEM\u0000",
-"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
{"description":"<!DOCTYPEa SYSTEM\\u0008",
"input":"<!DOCTYPEa SYSTEM\u0008",
@@ -3342,135 +3390,135 @@
{"description":"<!DOCTYPEa SYSTEM\"",
"input":"<!DOCTYPEa SYSTEM\"",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", false]]},
{"description":"<!DOCTYPEa SYSTEM\"\\u0000",
"input":"<!DOCTYPEa SYSTEM\"\u0000",
-"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "\uFFFD", false]]},
+"output":["ParseError", "ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "\uFFFD", false]]},
{"description":"<!DOCTYPEa SYSTEM\"\\u0009",
"input":"<!DOCTYPEa SYSTEM\"\u0009",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "\u0009", false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "\u0009", false]]},
{"description":"<!DOCTYPEa SYSTEM\"\\u000A",
"input":"<!DOCTYPEa SYSTEM\"\u000A",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "\u000A", false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "\u000A", false]]},
{"description":"<!DOCTYPEa SYSTEM\"\\u000B",
"input":"<!DOCTYPEa SYSTEM\"\u000B",
-"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "\u000B", false]]},
+"output":["ParseError", "ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "\u000B", false]]},
{"description":"<!DOCTYPEa SYSTEM\"\\u000C",
"input":"<!DOCTYPEa SYSTEM\"\u000C",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "\u000C", false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "\u000C", false]]},
{"description":"<!DOCTYPEa SYSTEM\" ",
"input":"<!DOCTYPEa SYSTEM\" ",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, " ", false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, " ", false]]},
{"description":"<!DOCTYPEa SYSTEM\"!",
"input":"<!DOCTYPEa SYSTEM\"!",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "!", false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "!", false]]},
{"description":"<!DOCTYPEa SYSTEM\"\"",
"input":"<!DOCTYPEa SYSTEM\"\"",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", false]]},
{"description":"<!DOCTYPEa SYSTEM\"#",
"input":"<!DOCTYPEa SYSTEM\"#",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "#", false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "#", false]]},
{"description":"<!DOCTYPEa SYSTEM\"&",
"input":"<!DOCTYPEa SYSTEM\"&",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "&", false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "&", false]]},
{"description":"<!DOCTYPEa SYSTEM\"'",
"input":"<!DOCTYPEa SYSTEM\"'",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "'", false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "'", false]]},
{"description":"<!DOCTYPEa SYSTEM\"-",
"input":"<!DOCTYPEa SYSTEM\"-",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "-", false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "-", false]]},
{"description":"<!DOCTYPEa SYSTEM\"/",
"input":"<!DOCTYPEa SYSTEM\"/",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "/", false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "/", false]]},
{"description":"<!DOCTYPEa SYSTEM\"0",
"input":"<!DOCTYPEa SYSTEM\"0",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "0", false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "0", false]]},
{"description":"<!DOCTYPEa SYSTEM\"1",
"input":"<!DOCTYPEa SYSTEM\"1",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "1", false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "1", false]]},
{"description":"<!DOCTYPEa SYSTEM\"9",
"input":"<!DOCTYPEa SYSTEM\"9",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "9", false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "9", false]]},
{"description":"<!DOCTYPEa SYSTEM\"<",
"input":"<!DOCTYPEa SYSTEM\"<",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "<", false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "<", false]]},
{"description":"<!DOCTYPEa SYSTEM\"=",
"input":"<!DOCTYPEa SYSTEM\"=",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "=", false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "=", false]]},
{"description":"<!DOCTYPEa SYSTEM\">",
"input":"<!DOCTYPEa SYSTEM\">",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", false]]},
{"description":"<!DOCTYPEa SYSTEM\"?",
"input":"<!DOCTYPEa SYSTEM\"?",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "?", false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "?", false]]},
{"description":"<!DOCTYPEa SYSTEM\"@",
"input":"<!DOCTYPEa SYSTEM\"@",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "@", false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "@", false]]},
{"description":"<!DOCTYPEa SYSTEM\"A",
"input":"<!DOCTYPEa SYSTEM\"A",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "A", false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "A", false]]},
{"description":"<!DOCTYPEa SYSTEM\"B",
"input":"<!DOCTYPEa SYSTEM\"B",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "B", false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "B", false]]},
{"description":"<!DOCTYPEa SYSTEM\"Y",
"input":"<!DOCTYPEa SYSTEM\"Y",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "Y", false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "Y", false]]},
{"description":"<!DOCTYPEa SYSTEM\"Z",
"input":"<!DOCTYPEa SYSTEM\"Z",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "Z", false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "Z", false]]},
{"description":"<!DOCTYPEa SYSTEM\"`",
"input":"<!DOCTYPEa SYSTEM\"`",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "`", false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "`", false]]},
{"description":"<!DOCTYPEa SYSTEM\"a",
"input":"<!DOCTYPEa SYSTEM\"a",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "a", false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "a", false]]},
{"description":"<!DOCTYPEa SYSTEM\"b",
"input":"<!DOCTYPEa SYSTEM\"b",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "b", false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "b", false]]},
{"description":"<!DOCTYPEa SYSTEM\"y",
"input":"<!DOCTYPEa SYSTEM\"y",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "y", false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "y", false]]},
{"description":"<!DOCTYPEa SYSTEM\"z",
"input":"<!DOCTYPEa SYSTEM\"z",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "z", false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "z", false]]},
{"description":"<!DOCTYPEa SYSTEM\"{",
"input":"<!DOCTYPEa SYSTEM\"{",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "{", false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "{", false]]},
{"description":"<!DOCTYPEa SYSTEM\"\\uDBC0\\uDC00",
"input":"<!DOCTYPEa SYSTEM\"\uDBC0\uDC00",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "\uDBC0\uDC00", false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "\uDBC0\uDC00", false]]},
{"description":"<!DOCTYPEa SYSTEM#",
"input":"<!DOCTYPEa SYSTEM#",
@@ -3482,47 +3530,47 @@
{"description":"<!DOCTYPEa SYSTEM'",
"input":"<!DOCTYPEa SYSTEM'",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", false]]},
{"description":"<!DOCTYPEa SYSTEM'\\u0000",
"input":"<!DOCTYPEa SYSTEM'\u0000",
-"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "\uFFFD", false]]},
+"output":["ParseError", "ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "\uFFFD", false]]},
{"description":"<!DOCTYPEa SYSTEM'\\u0009",
"input":"<!DOCTYPEa SYSTEM'\u0009",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "\u0009", false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "\u0009", false]]},
{"description":"<!DOCTYPEa SYSTEM'\\u000A",
"input":"<!DOCTYPEa SYSTEM'\u000A",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "\u000A", false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "\u000A", false]]},
{"description":"<!DOCTYPEa SYSTEM'\\u000B",
"input":"<!DOCTYPEa SYSTEM'\u000B",
-"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "\u000B", false]]},
+"output":["ParseError", "ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "\u000B", false]]},
{"description":"<!DOCTYPEa SYSTEM'\\u000C",
"input":"<!DOCTYPEa SYSTEM'\u000C",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "\u000C", false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "\u000C", false]]},
{"description":"<!DOCTYPEa SYSTEM' ",
"input":"<!DOCTYPEa SYSTEM' ",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, " ", false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, " ", false]]},
{"description":"<!DOCTYPEa SYSTEM'!",
"input":"<!DOCTYPEa SYSTEM'!",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "!", false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "!", false]]},
{"description":"<!DOCTYPEa SYSTEM'\"",
"input":"<!DOCTYPEa SYSTEM'\"",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "\"", false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "\"", false]]},
{"description":"<!DOCTYPEa SYSTEM'&",
"input":"<!DOCTYPEa SYSTEM'&",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "&", false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "&", false]]},
{"description":"<!DOCTYPEa SYSTEM''",
"input":"<!DOCTYPEa SYSTEM''",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", false]]},
{"description":"<!DOCTYPEa SYSTEM''\\u0000",
"input":"<!DOCTYPEa SYSTEM''\u0000",
@@ -3530,223 +3578,223 @@
{"description":"<!DOCTYPEa SYSTEM''\\u0008",
"input":"<!DOCTYPEa SYSTEM''\u0008",
-"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+"output":["ParseError", "ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
{"description":"<!DOCTYPEa SYSTEM''\\u0009",
"input":"<!DOCTYPEa SYSTEM''\u0009",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", false]]},
{"description":"<!DOCTYPEa SYSTEM''\\u000A",
"input":"<!DOCTYPEa SYSTEM''\u000A",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", false]]},
{"description":"<!DOCTYPEa SYSTEM''\\u000B",
"input":"<!DOCTYPEa SYSTEM''\u000B",
-"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+"output":["ParseError", "ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
{"description":"<!DOCTYPEa SYSTEM''\\u000C",
"input":"<!DOCTYPEa SYSTEM''\u000C",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", false]]},
{"description":"<!DOCTYPEa SYSTEM''\\u000D",
"input":"<!DOCTYPEa SYSTEM''\u000D",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", false]]},
{"description":"<!DOCTYPEa SYSTEM''\\u001F",
"input":"<!DOCTYPEa SYSTEM''\u001F",
-"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+"output":["ParseError", "ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
{"description":"<!DOCTYPEa SYSTEM'' ",
"input":"<!DOCTYPEa SYSTEM'' ",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", false]]},
{"description":"<!DOCTYPEa SYSTEM''!",
"input":"<!DOCTYPEa SYSTEM''!",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
{"description":"<!DOCTYPEa SYSTEM''\"",
"input":"<!DOCTYPEa SYSTEM''\"",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
{"description":"<!DOCTYPEa SYSTEM''&",
"input":"<!DOCTYPEa SYSTEM''&",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
{"description":"<!DOCTYPEa SYSTEM'''",
"input":"<!DOCTYPEa SYSTEM'''",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
{"description":"<!DOCTYPEa SYSTEM''-",
"input":"<!DOCTYPEa SYSTEM''-",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
{"description":"<!DOCTYPEa SYSTEM''/",
"input":"<!DOCTYPEa SYSTEM''/",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
{"description":"<!DOCTYPEa SYSTEM''0",
"input":"<!DOCTYPEa SYSTEM''0",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
{"description":"<!DOCTYPEa SYSTEM''1",
"input":"<!DOCTYPEa SYSTEM''1",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
{"description":"<!DOCTYPEa SYSTEM''9",
"input":"<!DOCTYPEa SYSTEM''9",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
{"description":"<!DOCTYPEa SYSTEM''<",
"input":"<!DOCTYPEa SYSTEM''<",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
{"description":"<!DOCTYPEa SYSTEM''=",
"input":"<!DOCTYPEa SYSTEM''=",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
{"description":"<!DOCTYPEa SYSTEM''>",
"input":"<!DOCTYPEa SYSTEM''>",
-"output":["ParseError", ["DOCTYPE", "a", null, "", true]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
{"description":"<!DOCTYPEa SYSTEM''?",
"input":"<!DOCTYPEa SYSTEM''?",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
{"description":"<!DOCTYPEa SYSTEM''@",
"input":"<!DOCTYPEa SYSTEM''@",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
{"description":"<!DOCTYPEa SYSTEM''A",
"input":"<!DOCTYPEa SYSTEM''A",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
{"description":"<!DOCTYPEa SYSTEM''B",
"input":"<!DOCTYPEa SYSTEM''B",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
{"description":"<!DOCTYPEa SYSTEM''Y",
"input":"<!DOCTYPEa SYSTEM''Y",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
{"description":"<!DOCTYPEa SYSTEM''Z",
"input":"<!DOCTYPEa SYSTEM''Z",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
{"description":"<!DOCTYPEa SYSTEM''`",
"input":"<!DOCTYPEa SYSTEM''`",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
{"description":"<!DOCTYPEa SYSTEM''a",
"input":"<!DOCTYPEa SYSTEM''a",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
{"description":"<!DOCTYPEa SYSTEM''b",
"input":"<!DOCTYPEa SYSTEM''b",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
{"description":"<!DOCTYPEa SYSTEM''y",
"input":"<!DOCTYPEa SYSTEM''y",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
{"description":"<!DOCTYPEa SYSTEM''z",
"input":"<!DOCTYPEa SYSTEM''z",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
{"description":"<!DOCTYPEa SYSTEM''{",
"input":"<!DOCTYPEa SYSTEM''{",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
{"description":"<!DOCTYPEa SYSTEM''\\uDBC0\\uDC00",
"input":"<!DOCTYPEa SYSTEM''\uDBC0\uDC00",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", true]]},
{"description":"<!DOCTYPEa SYSTEM'(",
"input":"<!DOCTYPEa SYSTEM'(",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "(", false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "(", false]]},
{"description":"<!DOCTYPEa SYSTEM'-",
"input":"<!DOCTYPEa SYSTEM'-",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "-", false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "-", false]]},
{"description":"<!DOCTYPEa SYSTEM'/",
"input":"<!DOCTYPEa SYSTEM'/",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "/", false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "/", false]]},
{"description":"<!DOCTYPEa SYSTEM'0",
"input":"<!DOCTYPEa SYSTEM'0",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "0", false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "0", false]]},
{"description":"<!DOCTYPEa SYSTEM'1",
"input":"<!DOCTYPEa SYSTEM'1",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "1", false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "1", false]]},
{"description":"<!DOCTYPEa SYSTEM'9",
"input":"<!DOCTYPEa SYSTEM'9",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "9", false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "9", false]]},
{"description":"<!DOCTYPEa SYSTEM'<",
"input":"<!DOCTYPEa SYSTEM'<",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "<", false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "<", false]]},
{"description":"<!DOCTYPEa SYSTEM'=",
"input":"<!DOCTYPEa SYSTEM'=",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "=", false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "=", false]]},
{"description":"<!DOCTYPEa SYSTEM'>",
"input":"<!DOCTYPEa SYSTEM'>",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "", false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "", false]]},
{"description":"<!DOCTYPEa SYSTEM'?",
"input":"<!DOCTYPEa SYSTEM'?",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "?", false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "?", false]]},
{"description":"<!DOCTYPEa SYSTEM'@",
"input":"<!DOCTYPEa SYSTEM'@",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "@", false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "@", false]]},
{"description":"<!DOCTYPEa SYSTEM'A",
"input":"<!DOCTYPEa SYSTEM'A",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "A", false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "A", false]]},
{"description":"<!DOCTYPEa SYSTEM'B",
"input":"<!DOCTYPEa SYSTEM'B",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "B", false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "B", false]]},
{"description":"<!DOCTYPEa SYSTEM'Y",
"input":"<!DOCTYPEa SYSTEM'Y",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "Y", false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "Y", false]]},
{"description":"<!DOCTYPEa SYSTEM'Z",
"input":"<!DOCTYPEa SYSTEM'Z",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "Z", false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "Z", false]]},
{"description":"<!DOCTYPEa SYSTEM'`",
"input":"<!DOCTYPEa SYSTEM'`",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "`", false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "`", false]]},
{"description":"<!DOCTYPEa SYSTEM'a",
"input":"<!DOCTYPEa SYSTEM'a",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "a", false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "a", false]]},
{"description":"<!DOCTYPEa SYSTEM'b",
"input":"<!DOCTYPEa SYSTEM'b",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "b", false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "b", false]]},
{"description":"<!DOCTYPEa SYSTEM'y",
"input":"<!DOCTYPEa SYSTEM'y",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "y", false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "y", false]]},
{"description":"<!DOCTYPEa SYSTEM'z",
"input":"<!DOCTYPEa SYSTEM'z",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "z", false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "z", false]]},
{"description":"<!DOCTYPEa SYSTEM'{",
"input":"<!DOCTYPEa SYSTEM'{",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "{", false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "{", false]]},
{"description":"<!DOCTYPEa SYSTEM'\\uDBC0\\uDC00",
"input":"<!DOCTYPEa SYSTEM'\uDBC0\uDC00",
-"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, "\uDBC0\uDC00", false]]},
+"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, "\uDBC0\uDC00", false]]},
{"description":"<!DOCTYPEa SYSTEM(",
"input":"<!DOCTYPEa SYSTEM(",
@@ -3854,7 +3902,7 @@
{"description":"<!DOCTYPEa a\\u0000",
"input":"<!DOCTYPEa a\u0000",
-"output":["ParseError", "ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
+"output":["ParseError", "ParseError", ["DOCTYPE", "a", null, null, false]]},
{"description":"<!DOCTYPEa a\\u0009",
"input":"<!DOCTYPEa a\u0009",
@@ -4182,7 +4230,7 @@
{"description":"</\\u0000",
"input":"</\u0000",
-"output":["ParseError", "ParseError", ["Comment", "\uFFFD"]]},
+"output":["ParseError", ["Comment", "\uFFFD"]]},
{"description":"</\\u0009",
"input":"</\u0009",
@@ -4260,21 +4308,21 @@
"input":"</@",
"output":["ParseError", ["Comment", "@"]]},
-{"description":"</A",
-"input":"</A",
-"output":["ParseError", ["EndTag", "a"]]},
+{"description":"</A>",
+"input":"</A>",
+"output":[["EndTag", "a"]]},
-{"description":"</B",
-"input":"</B",
-"output":["ParseError", ["EndTag", "b"]]},
+{"description":"</B>",
+"input":"</B>",
+"output":[["EndTag", "b"]]},
-{"description":"</Y",
-"input":"</Y",
-"output":["ParseError", ["EndTag", "y"]]},
+{"description":"</Y>",
+"input":"</Y>",
+"output":[["EndTag", "y"]]},
-{"description":"</Z",
-"input":"</Z",
-"output":["ParseError", ["EndTag", "z"]]},
+{"description":"</Z>",
+"input":"</Z>",
+"output":[["EndTag", "z"]]},
{"description":"</[",
"input":"</[",
@@ -4284,21 +4332,21 @@
"input":"</`",
"output":["ParseError", ["Comment", "`"]]},
-{"description":"</a",
-"input":"</a",
-"output":["ParseError", ["EndTag", "a"]]},
+{"description":"</a>",
+"input":"</a>",
+"output":[["EndTag", "a"]]},
-{"description":"</b",
-"input":"</b",
-"output":["ParseError", ["EndTag", "b"]]},
+{"description":"</b>",
+"input":"</b>",
+"output":[["EndTag", "b"]]},
-{"description":"</y",
-"input":"</y",
-"output":["ParseError", ["EndTag", "y"]]},
+{"description":"</y>",
+"input":"</y>",
+"output":[["EndTag", "y"]]},
-{"description":"</z",
-"input":"</z",
-"output":["ParseError", ["EndTag", "z"]]},
+{"description":"</z>",
+"input":"</z>",
+"output":[["EndTag", "z"]]},
{"description":"</{",
"input":"</{",
@@ -4338,7 +4386,7 @@
{"description":"<?\\u0000",
"input":"<?\u0000",
-"output":["ParseError", "ParseError", ["Comment", "?\uFFFD"]]},
+"output":["ParseError", ["Comment", "?\uFFFD"]]},
{"description":"<?\\u0009",
"input":"<?\u0009",
@@ -4464,21 +4512,21 @@
"input":"<@",
"output":["ParseError", ["Character", "<@"]]},
-{"description":"<A",
-"input":"<A",
-"output":["ParseError", ["StartTag", "a", {}]]},
+{"description":"<A>",
+"input":"<A>",
+"output":[["StartTag", "a", {}]]},
-{"description":"<B",
-"input":"<B",
-"output":["ParseError", ["StartTag", "b", {}]]},
+{"description":"<B>",
+"input":"<B>",
+"output":[["StartTag", "b", {}]]},
-{"description":"<Y",
-"input":"<Y",
-"output":["ParseError", ["StartTag", "y", {}]]},
+{"description":"<Y>",
+"input":"<Y>",
+"output":[["StartTag", "y", {}]]},
-{"description":"<Z",
-"input":"<Z",
-"output":["ParseError", ["StartTag", "z", {}]]},
+{"description":"<Z>",
+"input":"<Z>",
+"output":[["StartTag", "z", {}]]},
{"description":"<[",
"input":"<[",
@@ -4488,1445 +4536,1445 @@
"input":"<`",
"output":["ParseError", ["Character", "<`"]]},
-{"description":"<a",
-"input":"<a",
-"output":["ParseError", ["StartTag", "a", {}]]},
+{"description":"<a>",
+"input":"<a>",
+"output":[["StartTag", "a", {}]]},
-{"description":"<a\\u0000",
-"input":"<a\u0000",
-"output":["ParseError", "ParseError", ["StartTag", "a\uFFFD", {}]]},
+{"description":"<a\\u0000>",
+"input":"<a\u0000>",
+"output":["ParseError", ["StartTag", "a\uFFFD", {}]]},
-{"description":"<a\\u0008",
-"input":"<a\u0008",
-"output":["ParseError", "ParseError", ["StartTag", "a\u0008", {}]]},
+{"description":"<a\\u0008>",
+"input":"<a\u0008>",
+"output":["ParseError", ["StartTag", "a\u0008", {}]]},
-{"description":"<a\\u0009",
-"input":"<a\u0009",
-"output":["ParseError", ["StartTag", "a", {}]]},
+{"description":"<a\\u0009>",
+"input":"<a\u0009>",
+"output":[["StartTag", "a", {}]]},
-{"description":"<a\\u000A",
-"input":"<a\u000A",
-"output":["ParseError", ["StartTag", "a", {}]]},
+{"description":"<a\\u000A>",
+"input":"<a\u000A>",
+"output":[["StartTag", "a", {}]]},
-{"description":"<a\\u000B",
-"input":"<a\u000B",
-"output":["ParseError", "ParseError", ["StartTag", "a\u000B", {}]]},
+{"description":"<a\\u000B>",
+"input":"<a\u000B>",
+"output":["ParseError", ["StartTag", "a\u000B", {}]]},
-{"description":"<a\\u000C",
-"input":"<a\u000C",
-"output":["ParseError", ["StartTag", "a", {}]]},
+{"description":"<a\\u000C>",
+"input":"<a\u000C>",
+"output":[["StartTag", "a", {}]]},
-{"description":"<a\\u000D",
-"input":"<a\u000D",
-"output":["ParseError", ["StartTag", "a", {}]]},
+{"description":"<a\\u000D>",
+"input":"<a\u000D>",
+"output":[["StartTag", "a", {}]]},
-{"description":"<a\\u001F",
-"input":"<a\u001F",
-"output":["ParseError", "ParseError", ["StartTag", "a\u001F", {}]]},
+{"description":"<a\\u001F>",
+"input":"<a\u001F>",
+"output":["ParseError", ["StartTag", "a\u001F", {}]]},
-{"description":"<a ",
-"input":"<a ",
-"output":["ParseError", ["StartTag", "a", {}]]},
+{"description":"<a >",
+"input":"<a >",
+"output":[["StartTag", "a", {}]]},
-{"description":"<a \\u0000",
-"input":"<a \u0000",
-"output":["ParseError", "ParseError", ["StartTag", "a", {"\uFFFD":""}]]},
+{"description":"<a \\u0000>",
+"input":"<a \u0000>",
+"output":["ParseError", ["StartTag", "a", {"\uFFFD":""}]]},
-{"description":"<a \\u0008",
-"input":"<a \u0008",
-"output":["ParseError", "ParseError", ["StartTag", "a", {"\u0008":""}]]},
+{"description":"<a \\u0008>",
+"input":"<a \u0008>",
+"output":["ParseError", ["StartTag", "a", {"\u0008":""}]]},
-{"description":"<a \\u0009",
-"input":"<a \u0009",
-"output":["ParseError", ["StartTag", "a", {}]]},
+{"description":"<a \\u0009>",
+"input":"<a \u0009>",
+"output":[["StartTag", "a", {}]]},
-{"description":"<a \\u000A",
-"input":"<a \u000A",
-"output":["ParseError", ["StartTag", "a", {}]]},
+{"description":"<a \\u000A>",
+"input":"<a \u000A>",
+"output":[["StartTag", "a", {}]]},
-{"description":"<a \\u000B",
-"input":"<a \u000B",
-"output":["ParseError", "ParseError", ["StartTag", "a", {"\u000B":""}]]},
+{"description":"<a \\u000B>",
+"input":"<a \u000B>",
+"output":["ParseError", ["StartTag", "a", {"\u000B":""}]]},
-{"description":"<a \\u000C",
-"input":"<a \u000C",
-"output":["ParseError", ["StartTag", "a", {}]]},
+{"description":"<a \\u000C>",
+"input":"<a \u000C>",
+"output":[["StartTag", "a", {}]]},
-{"description":"<a \\u000D",
-"input":"<a \u000D",
-"output":["ParseError", ["StartTag", "a", {}]]},
+{"description":"<a \\u000D>",
+"input":"<a \u000D>",
+"output":[["StartTag", "a", {}]]},
-{"description":"<a \\u001F",
-"input":"<a \u001F",
-"output":["ParseError", "ParseError", ["StartTag", "a", {"\u001F":""}]]},
+{"description":"<a \\u001F>",
+"input":"<a \u001F>",
+"output":["ParseError", ["StartTag", "a", {"\u001F":""}]]},
-{"description":"<a ",
-"input":"<a ",
-"output":["ParseError", ["StartTag", "a", {}]]},
+{"description":"<a >",
+"input":"<a >",
+"output":[["StartTag", "a", {}]]},
-{"description":"<a !",
-"input":"<a !",
-"output":["ParseError", ["StartTag", "a", {"!":""}]]},
+{"description":"<a !>",
+"input":"<a !>",
+"output":[["StartTag", "a", {"!":""}]]},
-{"description":"<a \"",
-"input":"<a \"",
-"output":["ParseError", "ParseError", ["StartTag", "a", {"\"":""}]]},
+{"description":"<a \">",
+"input":"<a \">",
+"output":["ParseError", ["StartTag", "a", {"\"":""}]]},
-{"description":"<a #",
-"input":"<a #",
-"output":["ParseError", ["StartTag", "a", {"#":""}]]},
+{"description":"<a #>",
+"input":"<a #>",
+"output":[["StartTag", "a", {"#":""}]]},
-{"description":"<a &",
-"input":"<a &",
-"output":["ParseError", ["StartTag", "a", {"&":""}]]},
+{"description":"<a &>",
+"input":"<a &>",
+"output":[["StartTag", "a", {"&":""}]]},
-{"description":"<a '",
-"input":"<a '",
-"output":["ParseError", "ParseError", ["StartTag", "a", {"'":""}]]},
+{"description":"<a '>",
+"input":"<a '>",
+"output":["ParseError", ["StartTag", "a", {"'":""}]]},
-{"description":"<a (",
-"input":"<a (",
-"output":["ParseError", ["StartTag", "a", {"(":""}]]},
+{"description":"<a (>",
+"input":"<a (>",
+"output":[["StartTag", "a", {"(":""}]]},
-{"description":"<a -",
-"input":"<a -",
-"output":["ParseError", ["StartTag", "a", {"-":""}]]},
+{"description":"<a ->",
+"input":"<a ->",
+"output":[["StartTag", "a", {"-":""}]]},
-{"description":"<a .",
-"input":"<a .",
-"output":["ParseError", ["StartTag", "a", {".":""}]]},
+{"description":"<a .>",
+"input":"<a .>",
+"output":[["StartTag", "a", {".":""}]]},
-{"description":"<a /",
-"input":"<a /",
-"output":["ParseError", ["StartTag", "a", {}]]},
+{"description":"<a />",
+"input":"<a />",
+"output":[["StartTag", "a", {}, true]]},
-{"description":"<a 0",
-"input":"<a 0",
-"output":["ParseError", ["StartTag", "a", {"0":""}]]},
+{"description":"<a 0>",
+"input":"<a 0>",
+"output":[["StartTag", "a", {"0":""}]]},
-{"description":"<a 1",
-"input":"<a 1",
-"output":["ParseError", ["StartTag", "a", {"1":""}]]},
+{"description":"<a 1>",
+"input":"<a 1>",
+"output":[["StartTag", "a", {"1":""}]]},
-{"description":"<a 9",
-"input":"<a 9",
-"output":["ParseError", ["StartTag", "a", {"9":""}]]},
+{"description":"<a 9>",
+"input":"<a 9>",
+"output":[["StartTag", "a", {"9":""}]]},
-{"description":"<a <",
-"input":"<a <",
+{"description":"<a <>",
+"input":"<a <>",
"output":["ParseError", ["StartTag", "a", {"<":""}]]},
-{"description":"<a =",
-"input":"<a =",
-"output":["ParseError", "ParseError", ["StartTag", "a", {"=":""}]]},
+{"description":"<a =>",
+"input":"<a =>",
+"output":["ParseError", ["StartTag", "a", {"=":""}]]},
{"description":"<a >",
"input":"<a >",
"output":[["StartTag", "a", {}]]},
-{"description":"<a ?",
-"input":"<a ?",
-"output":["ParseError", ["StartTag", "a", {"?":""}]]},
+{"description":"<a ?>",
+"input":"<a ?>",
+"output":[["StartTag", "a", {"?":""}]]},
-{"description":"<a @",
-"input":"<a @",
-"output":["ParseError", ["StartTag", "a", {"@":""}]]},
+{"description":"<a @>",
+"input":"<a @>",
+"output":[["StartTag", "a", {"@":""}]]},
-{"description":"<a A",
-"input":"<a A",
-"output":["ParseError", ["StartTag", "a", {"a":""}]]},
+{"description":"<a A>",
+"input":"<a A>",
+"output":[["StartTag", "a", {"a":""}]]},
-{"description":"<a B",
-"input":"<a B",
-"output":["ParseError", ["StartTag", "a", {"b":""}]]},
+{"description":"<a B>",
+"input":"<a B>",
+"output":[["StartTag", "a", {"b":""}]]},
-{"description":"<a Y",
-"input":"<a Y",
-"output":["ParseError", ["StartTag", "a", {"y":""}]]},
+{"description":"<a Y>",
+"input":"<a Y>",
+"output":[["StartTag", "a", {"y":""}]]},
-{"description":"<a Z",
-"input":"<a Z",
-"output":["ParseError", ["StartTag", "a", {"z":""}]]},
+{"description":"<a Z>",
+"input":"<a Z>",
+"output":[["StartTag", "a", {"z":""}]]},
-{"description":"<a [",
-"input":"<a [",
-"output":["ParseError", ["StartTag", "a", {"[":""}]]},
+{"description":"<a [>",
+"input":"<a [>",
+"output":[["StartTag", "a", {"[":""}]]},
-{"description":"<a `",
-"input":"<a `",
-"output":["ParseError", ["StartTag", "a", {"`":""}]]},
+{"description":"<a `>",
+"input":"<a `>",
+"output":[["StartTag", "a", {"`":""}]]},
-{"description":"<a a",
-"input":"<a a",
-"output":["ParseError", ["StartTag", "a", {"a":""}]]},
+{"description":"<a a>",
+"input":"<a a>",
+"output":[["StartTag", "a", {"a":""}]]},
-{"description":"<a a\\u0000",
-"input":"<a a\u0000",
-"output":["ParseError", "ParseError", ["StartTag", "a", {"a\uFFFD":""}]]},
+{"description":"<a a\\u0000>",
+"input":"<a a\u0000>",
+"output":["ParseError", ["StartTag", "a", {"a\uFFFD":""}]]},
-{"description":"<a a\\u0008",
-"input":"<a a\u0008",
-"output":["ParseError", "ParseError", ["StartTag", "a", {"a\u0008":""}]]},
+{"description":"<a a\\u0008>",
+"input":"<a a\u0008>",
+"output":["ParseError", ["StartTag", "a", {"a\u0008":""}]]},
-{"description":"<a a\\u0009",
-"input":"<a a\u0009",
-"output":["ParseError", ["StartTag", "a", {"a":""}]]},
+{"description":"<a a\\u0009>",
+"input":"<a a\u0009>",
+"output":[["StartTag", "a", {"a":""}]]},
-{"description":"<a a\\u000A",
-"input":"<a a\u000A",
-"output":["ParseError", ["StartTag", "a", {"a":""}]]},
+{"description":"<a a\\u000A>",
+"input":"<a a\u000A>",
+"output":[["StartTag", "a", {"a":""}]]},
-{"description":"<a a\\u000B",
-"input":"<a a\u000B",
-"output":["ParseError", "ParseError", ["StartTag", "a", {"a\u000B":""}]]},
+{"description":"<a a\\u000B>",
+"input":"<a a\u000B>",
+"output":["ParseError", ["StartTag", "a", {"a\u000B":""}]]},
-{"description":"<a a\\u000C",
-"input":"<a a\u000C",
-"output":["ParseError", ["StartTag", "a", {"a":""}]]},
+{"description":"<a a\\u000C>",
+"input":"<a a\u000C>",
+"output":[["StartTag", "a", {"a":""}]]},
-{"description":"<a a\\u000D",
-"input":"<a a\u000D",
-"output":["ParseError", ["StartTag", "a", {"a":""}]]},
+{"description":"<a a\\u000D>",
+"input":"<a a\u000D>",
+"output":[["StartTag", "a", {"a":""}]]},
-{"description":"<a a\\u001F",
-"input":"<a a\u001F",
-"output":["ParseError", "ParseError", ["StartTag", "a", {"a\u001F":""}]]},
+{"description":"<a a\\u001F>",
+"input":"<a a\u001F>",
+"output":["ParseError", ["StartTag", "a", {"a\u001F":""}]]},
-{"description":"<a a ",
-"input":"<a a ",
-"output":["ParseError", ["StartTag", "a", {"a":""}]]},
+{"description":"<a a >",
+"input":"<a a >",
+"output":[["StartTag", "a", {"a":""}]]},
-{"description":"<a a \\u0000",
-"input":"<a a \u0000",
-"output":["ParseError", "ParseError", ["StartTag", "a", {"a":"", "\uFFFD":""}]]},
+{"description":"<a a \\u0000>",
+"input":"<a a \u0000>",
+"output":["ParseError", ["StartTag", "a", {"a":"", "\uFFFD":""}]]},
-{"description":"<a a \\u0008",
-"input":"<a a \u0008",
-"output":["ParseError", "ParseError", ["StartTag", "a", {"a":"", "\u0008":""}]]},
+{"description":"<a a \\u0008>",
+"input":"<a a \u0008>",
+"output":["ParseError", ["StartTag", "a", {"a":"", "\u0008":""}]]},
-{"description":"<a a \\u0009",
-"input":"<a a \u0009",
-"output":["ParseError", ["StartTag", "a", {"a":""}]]},
+{"description":"<a a \\u0009>",
+"input":"<a a \u0009>",
+"output":[["StartTag", "a", {"a":""}]]},
-{"description":"<a a \\u000A",
-"input":"<a a \u000A",
-"output":["ParseError", ["StartTag", "a", {"a":""}]]},
+{"description":"<a a \\u000A>",
+"input":"<a a \u000A>",
+"output":[["StartTag", "a", {"a":""}]]},
-{"description":"<a a \\u000B",
-"input":"<a a \u000B",
-"output":["ParseError", "ParseError", ["StartTag", "a", {"a":"", "\u000B":""}]]},
+{"description":"<a a \\u000B>",
+"input":"<a a \u000B>",
+"output":["ParseError", ["StartTag", "a", {"a":"", "\u000B":""}]]},
-{"description":"<a a \\u000C",
-"input":"<a a \u000C",
-"output":["ParseError", ["StartTag", "a", {"a":""}]]},
+{"description":"<a a \\u000C>",
+"input":"<a a \u000C>",
+"output":[["StartTag", "a", {"a":""}]]},
-{"description":"<a a \\u000D",
-"input":"<a a \u000D",
-"output":["ParseError", ["StartTag", "a", {"a":""}]]},
+{"description":"<a a \\u000D>",
+"input":"<a a \u000D>",
+"output":[["StartTag", "a", {"a":""}]]},
-{"description":"<a a \\u001F",
-"input":"<a a \u001F",
-"output":["ParseError", "ParseError", ["StartTag", "a", {"a":"", "\u001F":""}]]},
+{"description":"<a a \\u001F>",
+"input":"<a a \u001F>",
+"output":["ParseError", ["StartTag", "a", {"a":"", "\u001F":""}]]},
-{"description":"<a a ",
-"input":"<a a ",
-"output":["ParseError", ["StartTag", "a", {"a":""}]]},
+{"description":"<a a >",
+"input":"<a a >",
+"output":[["StartTag", "a", {"a":""}]]},
-{"description":"<a a !",
-"input":"<a a !",
-"output":["ParseError", ["StartTag", "a", {"a":"", "!":""}]]},
+{"description":"<a a !>",
+"input":"<a a !>",
+"output":[["StartTag", "a", {"a":"", "!":""}]]},
-{"description":"<a a \"",
-"input":"<a a \"",
-"output":["ParseError", "ParseError", ["StartTag", "a", {"a":"", "\"":""}]]},
+{"description":"<a a \">",
+"input":"<a a \">",
+"output":["ParseError", ["StartTag", "a", {"a":"", "\"":""}]]},
-{"description":"<a a #",
-"input":"<a a #",
-"output":["ParseError", ["StartTag", "a", {"a":"", "#":""}]]},
+{"description":"<a a #>",
+"input":"<a a #>",
+"output":[["StartTag", "a", {"a":"", "#":""}]]},
-{"description":"<a a &",
-"input":"<a a &",
-"output":["ParseError", ["StartTag", "a", {"a":"", "&":""}]]},
+{"description":"<a a &>",
+"input":"<a a &>",
+"output":[["StartTag", "a", {"a":"", "&":""}]]},
-{"description":"<a a '",
-"input":"<a a '",
-"output":["ParseError", "ParseError", ["StartTag", "a", {"a":"", "'":""}]]},
+{"description":"<a a '>",
+"input":"<a a '>",
+"output":["ParseError", ["StartTag", "a", {"a":"", "'":""}]]},
-{"description":"<a a (",
-"input":"<a a (",
-"output":["ParseError", ["StartTag", "a", {"a":"", "(":""}]]},
+{"description":"<a a (>",
+"input":"<a a (>",
+"output":[["StartTag", "a", {"a":"", "(":""}]]},
-{"description":"<a a -",
-"input":"<a a -",
-"output":["ParseError", ["StartTag", "a", {"a":"", "-":""}]]},
+{"description":"<a a ->",
+"input":"<a a ->",
+"output":[["StartTag", "a", {"a":"", "-":""}]]},
-{"description":"<a a .",
-"input":"<a a .",
-"output":["ParseError", ["StartTag", "a", {"a":"", ".":""}]]},
+{"description":"<a a .>",
+"input":"<a a .>",
+"output":[["StartTag", "a", {"a":"", ".":""}]]},
-{"description":"<a a /",
-"input":"<a a /",
-"output":["ParseError", ["StartTag", "a", {"a":""}]]},
+{"description":"<a a />",
+"input":"<a a />",
+"output":[["StartTag", "a", {"a":""}, true]]},
-{"description":"<a a 0",
-"input":"<a a 0",
-"output":["ParseError", ["StartTag", "a", {"a":"", "0":""}]]},
+{"description":"<a a 0>",
+"input":"<a a 0>",
+"output":[["StartTag", "a", {"a":"", "0":""}]]},
-{"description":"<a a 1",
-"input":"<a a 1",
-"output":["ParseError", ["StartTag", "a", {"a":"", "1":""}]]},
+{"description":"<a a 1>",
+"input":"<a a 1>",
+"output":[["StartTag", "a", {"a":"", "1":""}]]},
-{"description":"<a a 9",
-"input":"<a a 9",
-"output":["ParseError", ["StartTag", "a", {"a":"", "9":""}]]},
+{"description":"<a a 9>",
+"input":"<a a 9>",
+"output":[["StartTag", "a", {"a":"", "9":""}]]},
-{"description":"<a a <",
-"input":"<a a <",
+{"description":"<a a <>",
+"input":"<a a <>",
"output":["ParseError", ["StartTag", "a", {"a":"", "<":""}]]},
-{"description":"<a a =",
-"input":"<a a =",
+{"description":"<a a =>",
+"input":"<a a =>",
"output":["ParseError", ["StartTag", "a", {"a":""}]]},
{"description":"<a a >",
"input":"<a a >",
"output":[["StartTag", "a", {"a":""}]]},
-{"description":"<a a ?",
-"input":"<a a ?",
-"output":["ParseError", ["StartTag", "a", {"a":"", "?":""}]]},
+{"description":"<a a ?>",
+"input":"<a a ?>",
+"output":[["StartTag", "a", {"a":"", "?":""}]]},
-{"description":"<a a @",
-"input":"<a a @",
-"output":["ParseError", ["StartTag", "a", {"a":"", "@":""}]]},
+{"description":"<a a @>",
+"input":"<a a @>",
+"output":[["StartTag", "a", {"a":"", "@":""}]]},
-{"description":"<a a A",
-"input":"<a a A",
-"output":["ParseError", "ParseError", ["StartTag", "a", {"a":""}]]},
+{"description":"<a a A>",
+"input":"<a a A>",
+"output":["ParseError", ["StartTag", "a", {"a":""}]]},
-{"description":"<a a B",
-"input":"<a a B",
-"output":["ParseError", ["StartTag", "a", {"a":"", "b":""}]]},
+{"description":"<a a B>",
+"input":"<a a B>",
+"output":[["StartTag", "a", {"a":"", "b":""}]]},
-{"description":"<a a Y",
-"input":"<a a Y",
-"output":["ParseError", ["StartTag", "a", {"a":"", "y":""}]]},
+{"description":"<a a Y>",
+"input":"<a a Y>",
+"output":[["StartTag", "a", {"a":"", "y":""}]]},
-{"description":"<a a Z",
-"input":"<a a Z",
-"output":["ParseError", ["StartTag", "a", {"a":"", "z":""}]]},
+{"description":"<a a Z>",
+"input":"<a a Z>",
+"output":[["StartTag", "a", {"a":"", "z":""}]]},
-{"description":"<a a [",
-"input":"<a a [",
-"output":["ParseError", ["StartTag", "a", {"a":"", "[":""}]]},
+{"description":"<a a [>",
+"input":"<a a [>",
+"output":[["StartTag", "a", {"a":"", "[":""}]]},
-{"description":"<a a `",
-"input":"<a a `",
-"output":["ParseError", ["StartTag", "a", {"a":"", "`":""}]]},
+{"description":"<a a `>",
+"input":"<a a `>",
+"output":[["StartTag", "a", {"a":"", "`":""}]]},
-{"description":"<a a a",
-"input":"<a a a",
-"output":["ParseError", "ParseError", ["StartTag", "a", {"a":""}]]},
+{"description":"<a a a>",
+"input":"<a a a>",
+"output":["ParseError", ["StartTag", "a", {"a":""}]]},
-{"description":"<a a b",
-"input":"<a a b",
-"output":["ParseError", ["StartTag", "a", {"a":"", "b":""}]]},
+{"description":"<a a b>",
+"input":"<a a b>",
+"output":[["StartTag", "a", {"a":"", "b":""}]]},
-{"description":"<a a y",
-"input":"<a a y",
-"output":["ParseError", ["StartTag", "a", {"a":"", "y":""}]]},
+{"description":"<a a y>",
+"input":"<a a y>",
+"output":[["StartTag", "a", {"a":"", "y":""}]]},
-{"description":"<a a z",
-"input":"<a a z",
-"output":["ParseError", ["StartTag", "a", {"a":"", "z":""}]]},
+{"description":"<a a z>",
+"input":"<a a z>",
+"output":[["StartTag", "a", {"a":"", "z":""}]]},
-{"description":"<a a {",
-"input":"<a a {",
-"output":["ParseError", ["StartTag", "a", {"a":"", "{":""}]]},
+{"description":"<a a {>",
+"input":"<a a {>",
+"output":[["StartTag", "a", {"a":"", "{":""}]]},
-{"description":"<a a \\uDBC0\\uDC00",
-"input":"<a a \uDBC0\uDC00",
-"output":["ParseError", ["StartTag", "a", {"a":"", "\uDBC0\uDC00":""}]]},
+{"description":"<a a \\uDBC0\\uDC00>",
+"input":"<a a \uDBC0\uDC00>",
+"output":[["StartTag", "a", {"a":"", "\uDBC0\uDC00":""}]]},
-{"description":"<a a!",
-"input":"<a a!",
-"output":["ParseError", ["StartTag", "a", {"a!":""}]]},
+{"description":"<a a!>",
+"input":"<a a!>",
+"output":[["StartTag", "a", {"a!":""}]]},
-{"description":"<a a\"",
-"input":"<a a\"",
-"output":["ParseError", "ParseError", ["StartTag", "a", {"a\"":""}]]},
+{"description":"<a a\">",
+"input":"<a a\">",
+"output":["ParseError", ["StartTag", "a", {"a\"":""}]]},
-{"description":"<a a#",
-"input":"<a a#",
-"output":["ParseError", ["StartTag", "a", {"a#":""}]]},
+{"description":"<a a#>",
+"input":"<a a#>",
+"output":[["StartTag", "a", {"a#":""}]]},
-{"description":"<a a&",
-"input":"<a a&",
-"output":["ParseError", ["StartTag", "a", {"a&":""}]]},
+{"description":"<a a&>",
+"input":"<a a&>",
+"output":[["StartTag", "a", {"a&":""}]]},
-{"description":"<a a'",
-"input":"<a a'",
-"output":["ParseError", "ParseError", ["StartTag", "a", {"a'":""}]]},
+{"description":"<a a'>",
+"input":"<a a'>",
+"output":["ParseError", ["StartTag", "a", {"a'":""}]]},
-{"description":"<a a(",
-"input":"<a a(",
-"output":["ParseError", ["StartTag", "a", {"a(":""}]]},
+{"description":"<a a(>",
+"input":"<a a(>",
+"output":[["StartTag", "a", {"a(":""}]]},
-{"description":"<a a-",
-"input":"<a a-",
-"output":["ParseError", ["StartTag", "a", {"a-":""}]]},
+{"description":"<a a->",
+"input":"<a a->",
+"output":[["StartTag", "a", {"a-":""}]]},
-{"description":"<a a.",
-"input":"<a a.",
-"output":["ParseError", ["StartTag", "a", {"a.":""}]]},
+{"description":"<a a.>",
+"input":"<a a.>",
+"output":[["StartTag", "a", {"a.":""}]]},
-{"description":"<a a/",
-"input":"<a a/",
-"output":["ParseError", ["StartTag", "a", {"a":""}]]},
+{"description":"<a a/>",
+"input":"<a a/>",
+"output":[["StartTag", "a", {"a":""}, true]]},
-{"description":"<a a0",
-"input":"<a a0",
-"output":["ParseError", ["StartTag", "a", {"a0":""}]]},
+{"description":"<a a0>",
+"input":"<a a0>",
+"output":[["StartTag", "a", {"a0":""}]]},
-{"description":"<a a1",
-"input":"<a a1",
-"output":["ParseError", ["StartTag", "a", {"a1":""}]]},
+{"description":"<a a1>",
+"input":"<a a1>",
+"output":[["StartTag", "a", {"a1":""}]]},
-{"description":"<a a9",
-"input":"<a a9",
-"output":["ParseError", ["StartTag", "a", {"a9":""}]]},
+{"description":"<a a9>",
+"input":"<a a9>",
+"output":[["StartTag", "a", {"a9":""}]]},
-{"description":"<a a<",
-"input":"<a a<",
+{"description":"<a a<>",
+"input":"<a a<>",
"output":["ParseError", ["StartTag", "a", {"a<":""}]]},
-{"description":"<a a=",
-"input":"<a a=",
+{"description":"<a a=>",
+"input":"<a a=>",
"output":["ParseError", ["StartTag", "a", {"a":""}]]},
-{"description":"<a a=\\u0000",
-"input":"<a a=\u0000",
-"output":["ParseError", "ParseError", ["StartTag", "a", {"a":"\uFFFD"}]]},
+{"description":"<a a=\\u0000>",
+"input":"<a a=\u0000>",
+"output":["ParseError", ["StartTag", "a", {"a":"\uFFFD"}]]},
-{"description":"<a a=\\u0008",
-"input":"<a a=\u0008",
-"output":["ParseError", "ParseError", ["StartTag", "a", {"a":"\u0008"}]]},
+{"description":"<a a=\\u0008>",
+"input":"<a a=\u0008>",
+"output":["ParseError", ["StartTag", "a", {"a":"\u0008"}]]},
-{"description":"<a a=\\u0009",
-"input":"<a a=\u0009",
+{"description":"<a a=\\u0009>",
+"input":"<a a=\u0009>",
"output":["ParseError", ["StartTag", "a", {"a":""}]]},
-{"description":"<a a=\\u000A",
-"input":"<a a=\u000A",
+{"description":"<a a=\\u000A>",
+"input":"<a a=\u000A>",
"output":["ParseError", ["StartTag", "a", {"a":""}]]},
-{"description":"<a a=\\u000B",
-"input":"<a a=\u000B",
-"output":["ParseError", "ParseError", ["StartTag", "a", {"a":"\u000B"}]]},
+{"description":"<a a=\\u000B>",
+"input":"<a a=\u000B>",
+"output":["ParseError", ["StartTag", "a", {"a":"\u000B"}]]},
-{"description":"<a a=\\u000C",
-"input":"<a a=\u000C",
+{"description":"<a a=\\u000C>",
+"input":"<a a=\u000C>",
"output":["ParseError", ["StartTag", "a", {"a":""}]]},
-{"description":"<a a=\\u000D",
-"input":"<a a=\u000D",
+{"description":"<a a=\\u000D>",
+"input":"<a a=\u000D>",
"output":["ParseError", ["StartTag", "a", {"a":""}]]},
-{"description":"<a a=\\u001F",
-"input":"<a a=\u001F",
-"output":["ParseError", "ParseError", ["StartTag", "a", {"a":"\u001F"}]]},
+{"description":"<a a=\\u001F>",
+"input":"<a a=\u001F>",
+"output":["ParseError", ["StartTag", "a", {"a":"\u001F"}]]},
-{"description":"<a a= ",
-"input":"<a a= ",
+{"description":"<a a= >",
+"input":"<a a= >",
"output":["ParseError", ["StartTag", "a", {"a":""}]]},
-{"description":"<a a=!",
-"input":"<a a=!",
-"output":["ParseError", ["StartTag", "a", {"a":"!"}]]},
+{"description":"<a a=!>",
+"input":"<a a=!>",
+"output":[["StartTag", "a", {"a":"!"}]]},
-{"description":"<a a=\"",
-"input":"<a a=\"",
-"output":["ParseError", ["StartTag", "a", {"a":""}]]},
+{"description":"<a a=\"\">",
+"input":"<a a=\"\">",
+"output":[["StartTag", "a", {"a":""}]]},
-{"description":"<a a=\"\\u0000",
-"input":"<a a=\"\u0000",
-"output":["ParseError", "ParseError", ["StartTag", "a", {"a":"\uFFFD"}]]},
+{"description":"<a a=\"\\u0000\">",
+"input":"<a a=\"\u0000\">",
+"output":["ParseError", ["StartTag", "a", {"a":"\uFFFD"}]]},
-{"description":"<a a=\"\\u0009",
-"input":"<a a=\"\u0009",
-"output":["ParseError", ["StartTag", "a", {"a":"\u0009"}]]},
+{"description":"<a a=\"\\u0009\">",
+"input":"<a a=\"\u0009\">",
+"output":[["StartTag", "a", {"a":"\u0009"}]]},
-{"description":"<a a=\"\\u000A",
-"input":"<a a=\"\u000A",
-"output":["ParseError", ["StartTag", "a", {"a":"\u000A"}]]},
+{"description":"<a a=\"\\u000A\">",
+"input":"<a a=\"\u000A\">",
+"output":[["StartTag", "a", {"a":"\u000A"}]]},
-{"description":"<a a=\"\\u000B",
-"input":"<a a=\"\u000B",
-"output":["ParseError", "ParseError", ["StartTag", "a", {"a":"\u000B"}]]},
+{"description":"<a a=\"\\u000B\">",
+"input":"<a a=\"\u000B\">",
+"output":["ParseError", ["StartTag", "a", {"a":"\u000B"}]]},
-{"description":"<a a=\"\\u000C",
-"input":"<a a=\"\u000C",
-"output":["ParseError", ["StartTag", "a", {"a":"\u000C"}]]},
+{"description":"<a a=\"\\u000C\">",
+"input":"<a a=\"\u000C\">",
+"output":[["StartTag", "a", {"a":"\u000C"}]]},
-{"description":"<a a=\" ",
-"input":"<a a=\" ",
-"output":["ParseError", ["StartTag", "a", {"a":" "}]]},
+{"description":"<a a=\" \">",
+"input":"<a a=\" \">",
+"output":[["StartTag", "a", {"a":" "}]]},
-{"description":"<a a=\"!",
-"input":"<a a=\"!",
-"output":["ParseError", ["StartTag", "a", {"a":"!"}]]},
+{"description":"<a a=\"!\">",
+"input":"<a a=\"!\">",
+"output":[["StartTag", "a", {"a":"!"}]]},
-{"description":"<a a=\"\"",
-"input":"<a a=\"\"",
-"output":["ParseError", ["StartTag", "a", {"a":""}]]},
+{"description":"<a a=\"\">",
+"input":"<a a=\"\">",
+"output":[["StartTag", "a", {"a":""}]]},
-{"description":"<a a=\"#",
-"input":"<a a=\"#",
-"output":["ParseError", ["StartTag", "a", {"a":"#"}]]},
+{"description":"<a a=\"#\">",
+"input":"<a a=\"#\">",
+"output":[["StartTag", "a", {"a":"#"}]]},
-{"description":"<a a=\"%",
-"input":"<a a=\"%",
-"output":["ParseError", ["StartTag", "a", {"a":"%"}]]},
+{"description":"<a a=\"%\">",
+"input":"<a a=\"%\">",
+"output":[["StartTag", "a", {"a":"%"}]]},
-{"description":"<a a=\"&",
-"input":"<a a=\"&",
-"output":["ParseError", ["StartTag", "a", {"a":"&"}]]},
+{"description":"<a a=\"&\">",
+"input":"<a a=\"&\">",
+"output":[["StartTag", "a", {"a":"&"}]]},
-{"description":"<a a=\"'",
-"input":"<a a=\"'",
-"output":["ParseError", ["StartTag", "a", {"a":"'"}]]},
+{"description":"<a a=\"'\">",
+"input":"<a a=\"'\">",
+"output":[["StartTag", "a", {"a":"'"}]]},
-{"description":"<a a=\"-",
-"input":"<a a=\"-",
-"output":["ParseError", ["StartTag", "a", {"a":"-"}]]},
+{"description":"<a a=\"-\">",
+"input":"<a a=\"-\">",
+"output":[["StartTag", "a", {"a":"-"}]]},
-{"description":"<a a=\"/",
-"input":"<a a=\"/",
-"output":["ParseError", ["StartTag", "a", {"a":"/"}]]},
+{"description":"<a a=\"/\">",
+"input":"<a a=\"/\">",
+"output":[["StartTag", "a", {"a":"/"}]]},
-{"description":"<a a=\"0",
-"input":"<a a=\"0",
-"output":["ParseError", ["StartTag", "a", {"a":"0"}]]},
+{"description":"<a a=\"0\">",
+"input":"<a a=\"0\">",
+"output":[["StartTag", "a", {"a":"0"}]]},
-{"description":"<a a=\"1",
-"input":"<a a=\"1",
-"output":["ParseError", ["StartTag", "a", {"a":"1"}]]},
+{"description":"<a a=\"1\">",
+"input":"<a a=\"1\">",
+"output":[["StartTag", "a", {"a":"1"}]]},
-{"description":"<a a=\"9",
-"input":"<a a=\"9",
-"output":["ParseError", ["StartTag", "a", {"a":"9"}]]},
+{"description":"<a a=\"9\">",
+"input":"<a a=\"9\">",
+"output":[["StartTag", "a", {"a":"9"}]]},
-{"description":"<a a=\"<",
-"input":"<a a=\"<",
-"output":["ParseError", ["StartTag", "a", {"a":"<"}]]},
+{"description":"<a a=\"<\">",
+"input":"<a a=\"<\">",
+"output":[["StartTag", "a", {"a":"<"}]]},
-{"description":"<a a=\"=",
-"input":"<a a=\"=",
-"output":["ParseError", ["StartTag", "a", {"a":"="}]]},
+{"description":"<a a=\"=\">",
+"input":"<a a=\"=\">",
+"output":[["StartTag", "a", {"a":"="}]]},
-{"description":"<a a=\">",
-"input":"<a a=\">",
-"output":["ParseError", ["StartTag", "a", {"a":">"}]]},
+{"description":"<a a=\">\">",
+"input":"<a a=\">\">",
+"output":[["StartTag", "a", {"a":">"}]]},
-{"description":"<a a=\"?",
-"input":"<a a=\"?",
-"output":["ParseError", ["StartTag", "a", {"a":"?"}]]},
+{"description":"<a a=\"?\">",
+"input":"<a a=\"?\">",
+"output":[["StartTag", "a", {"a":"?"}]]},
-{"description":"<a a=\"@",
-"input":"<a a=\"@",
-"output":["ParseError", ["StartTag", "a", {"a":"@"}]]},
+{"description":"<a a=\"@\">",
+"input":"<a a=\"@\">",
+"output":[["StartTag", "a", {"a":"@"}]]},
-{"description":"<a a=\"A",
-"input":"<a a=\"A",
-"output":["ParseError", ["StartTag", "a", {"a":"A"}]]},
+{"description":"<a a=\"A\">",
+"input":"<a a=\"A\">",
+"output":[["StartTag", "a", {"a":"A"}]]},
-{"description":"<a a=\"B",
-"input":"<a a=\"B",
-"output":["ParseError", ["StartTag", "a", {"a":"B"}]]},
+{"description":"<a a=\"B\">",
+"input":"<a a=\"B\">",
+"output":[["StartTag", "a", {"a":"B"}]]},
-{"description":"<a a=\"Y",
-"input":"<a a=\"Y",
-"output":["ParseError", ["StartTag", "a", {"a":"Y"}]]},
+{"description":"<a a=\"Y\">",
+"input":"<a a=\"Y\">",
+"output":[["StartTag", "a", {"a":"Y"}]]},
-{"description":"<a a=\"Z",
-"input":"<a a=\"Z",
-"output":["ParseError", ["StartTag", "a", {"a":"Z"}]]},
+{"description":"<a a=\"Z\">",
+"input":"<a a=\"Z\">",
+"output":[["StartTag", "a", {"a":"Z"}]]},
-{"description":"<a a=\"`",
-"input":"<a a=\"`",
-"output":["ParseError", ["StartTag", "a", {"a":"`"}]]},
+{"description":"<a a=\"`\">",
+"input":"<a a=\"`\">",
+"output":[["StartTag", "a", {"a":"`"}]]},
-{"description":"<a a=\"a",
-"input":"<a a=\"a",
-"output":["ParseError", ["StartTag", "a", {"a":"a"}]]},
+{"description":"<a a=\"a\">",
+"input":"<a a=\"a\">",
+"output":[["StartTag", "a", {"a":"a"}]]},
-{"description":"<a a=\"b",
-"input":"<a a=\"b",
-"output":["ParseError", ["StartTag", "a", {"a":"b"}]]},
+{"description":"<a a=\"b\">",
+"input":"<a a=\"b\">",
+"output":[["StartTag", "a", {"a":"b"}]]},
-{"description":"<a a=\"y",
-"input":"<a a=\"y",
-"output":["ParseError", ["StartTag", "a", {"a":"y"}]]},
+{"description":"<a a=\"y\">",
+"input":"<a a=\"y\">",
+"output":[["StartTag", "a", {"a":"y"}]]},
-{"description":"<a a=\"z",
-"input":"<a a=\"z",
-"output":["ParseError", ["StartTag", "a", {"a":"z"}]]},
+{"description":"<a a=\"z\">",
+"input":"<a a=\"z\">",
+"output":[["StartTag", "a", {"a":"z"}]]},
-{"description":"<a a=\"{",
-"input":"<a a=\"{",
-"output":["ParseError", ["StartTag", "a", {"a":"{"}]]},
+{"description":"<a a=\"{\">",
+"input":"<a a=\"{\">",
+"output":[["StartTag", "a", {"a":"{"}]]},
-{"description":"<a a=\"\\uDBC0\\uDC00",
-"input":"<a a=\"\uDBC0\uDC00",
-"output":["ParseError", ["StartTag", "a", {"a":"\uDBC0\uDC00"}]]},
+{"description":"<a a=\"\\uDBC0\\uDC00\">",
+"input":"<a a=\"\uDBC0\uDC00\">",
+"output":[["StartTag", "a", {"a":"\uDBC0\uDC00"}]]},
-{"description":"<a a=#",
-"input":"<a a=#",
-"output":["ParseError", ["StartTag", "a", {"a":"#"}]]},
+{"description":"<a a=#>",
+"input":"<a a=#>",
+"output":[["StartTag", "a", {"a":"#"}]]},
-{"description":"<a a=%",
-"input":"<a a=%",
-"output":["ParseError", ["StartTag", "a", {"a":"%"}]]},
+{"description":"<a a=%>",
+"input":"<a a=%>",
+"output":[["StartTag", "a", {"a":"%"}]]},
-{"description":"<a a=&",
-"input":"<a a=&",
-"output":["ParseError", ["StartTag", "a", {"a":"&"}]]},
+{"description":"<a a=&>",
+"input":"<a a=&>",
+"output":[["StartTag", "a", {"a":"&"}]]},
-{"description":"<a a='",
-"input":"<a a='",
-"output":["ParseError", ["StartTag", "a", {"a":""}]]},
+{"description":"<a a=''>",
+"input":"<a a=''>",
+"output":[["StartTag", "a", {"a":""}]]},
-{"description":"<a a='\\u0000",
-"input":"<a a='\u0000",
-"output":["ParseError", "ParseError", ["StartTag", "a", {"a":"\uFFFD"}]]},
+{"description":"<a a='\\u0000'>",
+"input":"<a a='\u0000'>",
+"output":["ParseError", ["StartTag", "a", {"a":"\uFFFD"}]]},
-{"description":"<a a='\\u0009",
-"input":"<a a='\u0009",
-"output":["ParseError", ["StartTag", "a", {"a":"\u0009"}]]},
+{"description":"<a a='\\u0009'>",
+"input":"<a a='\u0009'>",
+"output":[["StartTag", "a", {"a":"\u0009"}]]},
-{"description":"<a a='\\u000A",
-"input":"<a a='\u000A",
-"output":["ParseError", ["StartTag", "a", {"a":"\u000A"}]]},
+{"description":"<a a='\\u000A'>",
+"input":"<a a='\u000A'>",
+"output":[["StartTag", "a", {"a":"\u000A"}]]},
-{"description":"<a a='\\u000B",
-"input":"<a a='\u000B",
-"output":["ParseError", "ParseError", ["StartTag", "a", {"a":"\u000B"}]]},
+{"description":"<a a='\\u000B'>",
+"input":"<a a='\u000B'>",
+"output":["ParseError", ["StartTag", "a", {"a":"\u000B"}]]},
-{"description":"<a a='\\u000C",
-"input":"<a a='\u000C",
-"output":["ParseError", ["StartTag", "a", {"a":"\u000C"}]]},
+{"description":"<a a='\\u000C'>",
+"input":"<a a='\u000C'>",
+"output":[["StartTag", "a", {"a":"\u000C"}]]},
-{"description":"<a a=' ",
-"input":"<a a=' ",
-"output":["ParseError", ["StartTag", "a", {"a":" "}]]},
+{"description":"<a a=' '>",
+"input":"<a a=' '>",
+"output":[["StartTag", "a", {"a":" "}]]},
-{"description":"<a a='!",
-"input":"<a a='!",
-"output":["ParseError", ["StartTag", "a", {"a":"!"}]]},
+{"description":"<a a='!'>",
+"input":"<a a='!'>",
+"output":[["StartTag", "a", {"a":"!"}]]},
-{"description":"<a a='\"",
-"input":"<a a='\"",
-"output":["ParseError", ["StartTag", "a", {"a":"\""}]]},
+{"description":"<a a='\"'>",
+"input":"<a a='\"'>",
+"output":[["StartTag", "a", {"a":"\""}]]},
-{"description":"<a a='%",
-"input":"<a a='%",
-"output":["ParseError", ["StartTag", "a", {"a":"%"}]]},
+{"description":"<a a='%'>",
+"input":"<a a='%'>",
+"output":[["StartTag", "a", {"a":"%"}]]},
-{"description":"<a a='&",
-"input":"<a a='&",
-"output":["ParseError", ["StartTag", "a", {"a":"&"}]]},
+{"description":"<a a='&'>",
+"input":"<a a='&'>",
+"output":[["StartTag", "a", {"a":"&"}]]},
-{"description":"<a a=''",
-"input":"<a a=''",
-"output":["ParseError", ["StartTag", "a", {"a":""}]]},
+{"description":"<a a=''>",
+"input":"<a a=''>",
+"output":[["StartTag", "a", {"a":""}]]},
-{"description":"<a a=''\\u0000",
-"input":"<a a=''\u0000",
-"output":["ParseError", "ParseError", "ParseError", ["StartTag", "a", {"a":"", "\uFFFD":""}]]},
+{"description":"<a a=''\\u0000>",
+"input":"<a a=''\u0000>",
+"output":["ParseError", "ParseError", ["StartTag", "a", {"a":"", "\uFFFD":""}]]},
-{"description":"<a a=''\\u0008",
-"input":"<a a=''\u0008",
-"output":["ParseError", "ParseError", "ParseError", ["StartTag", "a", {"a":"", "\u0008":""}]]},
+{"description":"<a a=''\\u0008>",
+"input":"<a a=''\u0008>",
+"output":["ParseError", "ParseError", ["StartTag", "a", {"a":"", "\u0008":""}]]},
-{"description":"<a a=''\\u0009",
-"input":"<a a=''\u0009",
-"output":["ParseError", ["StartTag", "a", {"a":""}]]},
+{"description":"<a a=''\\u0009>",
+"input":"<a a=''\u0009>",
+"output":[["StartTag", "a", {"a":""}]]},
-{"description":"<a a=''\\u000A",
-"input":"<a a=''\u000A",
-"output":["ParseError", ["StartTag", "a", {"a":""}]]},
+{"description":"<a a=''\\u000A>",
+"input":"<a a=''\u000A>",
+"output":[["StartTag", "a", {"a":""}]]},
-{"description":"<a a=''\\u000B",
-"input":"<a a=''\u000B",
-"output":["ParseError", "ParseError", "ParseError", ["StartTag", "a", {"a":"", "\u000B":""}]]},
+{"description":"<a a=''\\u000B>",
+"input":"<a a=''\u000B>",
+"output":["ParseError", "ParseError", ["StartTag", "a", {"a":"", "\u000B":""}]]},
-{"description":"<a a=''\\u000C",
-"input":"<a a=''\u000C",
-"output":["ParseError", ["StartTag", "a", {"a":""}]]},
+{"description":"<a a=''\\u000C>",
+"input":"<a a=''\u000C>",
+"output":[["StartTag", "a", {"a":""}]]},
-{"description":"<a a=''\\u000D",
-"input":"<a a=''\u000D",
-"output":["ParseError", ["StartTag", "a", {"a":""}]]},
+{"description":"<a a=''\\u000D>",
+"input":"<a a=''\u000D>",
+"output":[["StartTag", "a", {"a":""}]]},
-{"description":"<a a=''\\u001F",
-"input":"<a a=''\u001F",
-"output":["ParseError", "ParseError", "ParseError", ["StartTag", "a", {"a":"", "\u001F":""}]]},
+{"description":"<a a=''\\u001F>",
+"input":"<a a=''\u001F>",
+"output":["ParseError", "ParseError", ["StartTag", "a", {"a":"", "\u001F":""}]]},
-{"description":"<a a='' ",
-"input":"<a a='' ",
-"output":["ParseError", ["StartTag", "a", {"a":""}]]},
+{"description":"<a a='' >",
+"input":"<a a='' >",
+"output":[["StartTag", "a", {"a":""}]]},
-{"description":"<a a=''!",
-"input":"<a a=''!",
-"output":["ParseError", "ParseError", ["StartTag", "a", {"a":"", "!":""}]]},
+{"description":"<a a=''!>",
+"input":"<a a=''!>",
+"output":["ParseError", ["StartTag", "a", {"a":"", "!":""}]]},
-{"description":"<a a=''\"",
-"input":"<a a=''\"",
-"output":["ParseError", "ParseError", "ParseError", ["StartTag", "a", {"a":"", "\"":""}]]},
+{"description":"<a a=''\">",
+"input":"<a a=''\">",
+"output":["ParseError", "ParseError", ["StartTag", "a", {"a":"", "\"":""}]]},
-{"description":"<a a=''&",
-"input":"<a a=''&",
-"output":["ParseError", "ParseError", ["StartTag", "a", {"a":"", "&":""}]]},
+{"description":"<a a=''&>",
+"input":"<a a=''&>",
+"output":["ParseError", ["StartTag", "a", {"a":"", "&":""}]]},
-{"description":"<a a='''",
-"input":"<a a='''",
-"output":["ParseError", "ParseError", "ParseError", ["StartTag", "a", {"a":"", "'":""}]]},
+{"description":"<a a='''>",
+"input":"<a a='''>",
+"output":["ParseError", "ParseError", ["StartTag", "a", {"a":"", "'":""}]]},
-{"description":"<a a=''-",
-"input":"<a a=''-",
-"output":["ParseError", "ParseError", ["StartTag", "a", {"a":"", "-":""}]]},
+{"description":"<a a=''->",
+"input":"<a a=''->",
+"output":["ParseError", ["StartTag", "a", {"a":"", "-":""}]]},
-{"description":"<a a=''.",
-"input":"<a a=''.",
-"output":["ParseError", "ParseError", ["StartTag", "a", {"a":"", ".":""}]]},
+{"description":"<a a=''.>",
+"input":"<a a=''.>",
+"output":["ParseError", ["StartTag", "a", {"a":"", ".":""}]]},
-{"description":"<a a=''/",
-"input":"<a a=''/",
-"output":["ParseError", ["StartTag", "a", {"a":""}]]},
+{"description":"<a a=''/>",
+"input":"<a a=''/>",
+"output":[["StartTag", "a", {"a":""}, true]]},
-{"description":"<a a=''0",
-"input":"<a a=''0",
-"output":["ParseError", "ParseError", ["StartTag", "a", {"a":"", "0":""}]]},
+{"description":"<a a=''0>",
+"input":"<a a=''0>",
+"output":["ParseError", ["StartTag", "a", {"a":"", "0":""}]]},
-{"description":"<a a=''1",
-"input":"<a a=''1",
-"output":["ParseError", "ParseError", ["StartTag", "a", {"a":"", "1":""}]]},
+{"description":"<a a=''1>",
+"input":"<a a=''1>",
+"output":["ParseError", ["StartTag", "a", {"a":"", "1":""}]]},
-{"description":"<a a=''9",
-"input":"<a a=''9",
-"output":["ParseError", "ParseError", ["StartTag", "a", {"a":"", "9":""}]]},
+{"description":"<a a=''9>",
+"input":"<a a=''9>",
+"output":["ParseError", ["StartTag", "a", {"a":"", "9":""}]]},
-{"description":"<a a=''<",
-"input":"<a a=''<",
+{"description":"<a a=''<>",
+"input":"<a a=''<>",
"output":["ParseError", "ParseError", ["StartTag", "a", {"a":"", "<":""}]]},
-{"description":"<a a=''=",
-"input":"<a a=''=",
-"output":["ParseError", "ParseError", "ParseError", ["StartTag", "a", {"a":"", "=":""}]]},
+{"description":"<a a=''=>",
+"input":"<a a=''=>",
+"output":["ParseError", "ParseError", ["StartTag", "a", {"a":"", "=":""}]]},
{"description":"<a a=''>",
"input":"<a a=''>",
"output":[["StartTag", "a", {"a":""}]]},
-{"description":"<a a=''?",
-"input":"<a a=''?",
-"output":["ParseError", "ParseError", ["StartTag", "a", {"a":"", "?":""}]]},
+{"description":"<a a=''?>",
+"input":"<a a=''?>",
+"output":["ParseError", ["StartTag", "a", {"a":"", "?":""}]]},
-{"description":"<a a=''@",
-"input":"<a a=''@",
-"output":["ParseError", "ParseError", ["StartTag", "a", {"a":"", "@":""}]]},
+{"description":"<a a=''@>",
+"input":"<a a=''@>",
+"output":["ParseError", ["StartTag", "a", {"a":"", "@":""}]]},
-{"description":"<a a=''A",
-"input":"<a a=''A",
-"output":["ParseError", "ParseError", "ParseError", ["StartTag", "a", {"a":""}]]},
+{"description":"<a a=''A>",
+"input":"<a a=''A>",
+"output":["ParseError", "ParseError", ["StartTag", "a", {"a":""}]]},
-{"description":"<a a=''B",
-"input":"<a a=''B",
-"output":["ParseError", "ParseError", ["StartTag", "a", {"a":"", "b":""}]]},
+{"description":"<a a=''B>",
+"input":"<a a=''B>",
+"output":["ParseError", ["StartTag", "a", {"a":"", "b":""}]]},
-{"description":"<a a=''Y",
-"input":"<a a=''Y",
-"output":["ParseError", "ParseError", ["StartTag", "a", {"a":"", "y":""}]]},
+{"description":"<a a=''Y>",
+"input":"<a a=''Y>",
+"output":["ParseError", ["StartTag", "a", {"a":"", "y":""}]]},
-{"description":"<a a=''Z",
-"input":"<a a=''Z",
-"output":["ParseError", "ParseError", ["StartTag", "a", {"a":"", "z":""}]]},
+{"description":"<a a=''Z>",
+"input":"<a a=''Z>",
+"output":["ParseError", ["StartTag", "a", {"a":"", "z":""}]]},
-{"description":"<a a=''`",
-"input":"<a a=''`",
-"output":["ParseError", "ParseError", ["StartTag", "a", {"a":"", "`":""}]]},
+{"description":"<a a=''`>",
+"input":"<a a=''`>",
+"output":["ParseError", ["StartTag", "a", {"a":"", "`":""}]]},
-{"description":"<a a=''a",
-"input":"<a a=''a",
-"output":["ParseError", "ParseError", "ParseError", ["StartTag", "a", {"a":""}]]},
+{"description":"<a a=''a>",
+"input":"<a a=''a>",
+"output":["ParseError", "ParseError", ["StartTag", "a", {"a":""}]]},
-{"description":"<a a=''b",
-"input":"<a a=''b",
-"output":["ParseError", "ParseError", ["StartTag", "a", {"a":"", "b":""}]]},
+{"description":"<a a=''b>",
+"input":"<a a=''b>",
+"output":["ParseError", ["StartTag", "a", {"a":"", "b":""}]]},
-{"description":"<a a=''y",
-"input":"<a a=''y",
-"output":["ParseError", "ParseError", ["StartTag", "a", {"a":"", "y":""}]]},
+{"description":"<a a=''y>",
+"input":"<a a=''y>",
+"output":["ParseError", ["StartTag", "a", {"a":"", "y":""}]]},
-{"description":"<a a=''z",
-"input":"<a a=''z",
-"output":["ParseError", "ParseError", ["StartTag", "a", {"a":"", "z":""}]]},
+{"description":"<a a=''z>",
+"input":"<a a=''z>",
+"output":["ParseError", ["StartTag", "a", {"a":"", "z":""}]]},
-{"description":"<a a=''{",
-"input":"<a a=''{",
-"output":["ParseError", "ParseError", ["StartTag", "a", {"a":"", "{":""}]]},
+{"description":"<a a=''{>",
+"input":"<a a=''{>",
+"output":["ParseError", ["StartTag", "a", {"a":"", "{":""}]]},
-{"description":"<a a=''\\uDBC0\\uDC00",
-"input":"<a a=''\uDBC0\uDC00",
-"output":["ParseError", "ParseError", ["StartTag", "a", {"a":"", "\uDBC0\uDC00":""}]]},
+{"description":"<a a=''\\uDBC0\\uDC00>",
+"input":"<a a=''\uDBC0\uDC00>",
+"output":["ParseError", ["StartTag", "a", {"a":"", "\uDBC0\uDC00":""}]]},
-{"description":"<a a='(",
-"input":"<a a='(",
-"output":["ParseError", ["StartTag", "a", {"a":"("}]]},
+{"description":"<a a='('>",
+"input":"<a a='('>",
+"output":[["StartTag", "a", {"a":"("}]]},
-{"description":"<a a='-",
-"input":"<a a='-",
-"output":["ParseError", ["StartTag", "a", {"a":"-"}]]},
+{"description":"<a a='-'>",
+"input":"<a a='-'>",
+"output":[["StartTag", "a", {"a":"-"}]]},
-{"description":"<a a='/",
-"input":"<a a='/",
-"output":["ParseError", ["StartTag", "a", {"a":"/"}]]},
+{"description":"<a a='/'>",
+"input":"<a a='/'>",
+"output":[["StartTag", "a", {"a":"/"}]]},
-{"description":"<a a='0",
-"input":"<a a='0",
-"output":["ParseError", ["StartTag", "a", {"a":"0"}]]},
+{"description":"<a a='0'>",
+"input":"<a a='0'>",
+"output":[["StartTag", "a", {"a":"0"}]]},
-{"description":"<a a='1",
-"input":"<a a='1",
-"output":["ParseError", ["StartTag", "a", {"a":"1"}]]},
+{"description":"<a a='1'>",
+"input":"<a a='1'>",
+"output":[["StartTag", "a", {"a":"1"}]]},
-{"description":"<a a='9",
-"input":"<a a='9",
-"output":["ParseError", ["StartTag", "a", {"a":"9"}]]},
+{"description":"<a a='9'>",
+"input":"<a a='9'>",
+"output":[["StartTag", "a", {"a":"9"}]]},
-{"description":"<a a='<",
-"input":"<a a='<",
-"output":["ParseError", ["StartTag", "a", {"a":"<"}]]},
+{"description":"<a a='<'>",
+"input":"<a a='<'>",
+"output":[["StartTag", "a", {"a":"<"}]]},
-{"description":"<a a='=",
-"input":"<a a='=",
-"output":["ParseError", ["StartTag", "a", {"a":"="}]]},
+{"description":"<a a='='>",
+"input":"<a a='='>",
+"output":[["StartTag", "a", {"a":"="}]]},
-{"description":"<a a='>",
-"input":"<a a='>",
-"output":["ParseError", ["StartTag", "a", {"a":">"}]]},
+{"description":"<a a='>'>",
+"input":"<a a='>'>",
+"output":[["StartTag", "a", {"a":">"}]]},
-{"description":"<a a='?",
-"input":"<a a='?",
-"output":["ParseError", ["StartTag", "a", {"a":"?"}]]},
+{"description":"<a a='?'>",
+"input":"<a a='?'>",
+"output":[["StartTag", "a", {"a":"?"}]]},
-{"description":"<a a='@",
-"input":"<a a='@",
-"output":["ParseError", ["StartTag", "a", {"a":"@"}]]},
+{"description":"<a a='@'>",
+"input":"<a a='@'>",
+"output":[["StartTag", "a", {"a":"@"}]]},
-{"description":"<a a='A",
-"input":"<a a='A",
-"output":["ParseError", ["StartTag", "a", {"a":"A"}]]},
+{"description":"<a a='A'>",
+"input":"<a a='A'>",
+"output":[["StartTag", "a", {"a":"A"}]]},
-{"description":"<a a='B",
-"input":"<a a='B",
-"output":["ParseError", ["StartTag", "a", {"a":"B"}]]},
+{"description":"<a a='B'>",
+"input":"<a a='B'>",
+"output":[["StartTag", "a", {"a":"B"}]]},
-{"description":"<a a='Y",
-"input":"<a a='Y",
-"output":["ParseError", ["StartTag", "a", {"a":"Y"}]]},
+{"description":"<a a='Y'>",
+"input":"<a a='Y'>",
+"output":[["StartTag", "a", {"a":"Y"}]]},
-{"description":"<a a='Z",
-"input":"<a a='Z",
-"output":["ParseError", ["StartTag", "a", {"a":"Z"}]]},
+{"description":"<a a='Z'>",
+"input":"<a a='Z'>",
+"output":[["StartTag", "a", {"a":"Z"}]]},
-{"description":"<a a='`",
-"input":"<a a='`",
-"output":["ParseError", ["StartTag", "a", {"a":"`"}]]},
+{"description":"<a a='`'>",
+"input":"<a a='`'>",
+"output":[["StartTag", "a", {"a":"`"}]]},
-{"description":"<a a='a",
-"input":"<a a='a",
-"output":["ParseError", ["StartTag", "a", {"a":"a"}]]},
+{"description":"<a a='a'>",
+"input":"<a a='a'>",
+"output":[["StartTag", "a", {"a":"a"}]]},
-{"description":"<a a='b",
-"input":"<a a='b",
-"output":["ParseError", ["StartTag", "a", {"a":"b"}]]},
+{"description":"<a a='b'>",
+"input":"<a a='b'>",
+"output":[["StartTag", "a", {"a":"b"}]]},
-{"description":"<a a='y",
-"input":"<a a='y",
-"output":["ParseError", ["StartTag", "a", {"a":"y"}]]},
+{"description":"<a a='y'>",
+"input":"<a a='y'>",
+"output":[["StartTag", "a", {"a":"y"}]]},
-{"description":"<a a='z",
-"input":"<a a='z",
-"output":["ParseError", ["StartTag", "a", {"a":"z"}]]},
+{"description":"<a a='z'>",
+"input":"<a a='z'>",
+"output":[["StartTag", "a", {"a":"z"}]]},
-{"description":"<a a='{",
-"input":"<a a='{",
-"output":["ParseError", ["StartTag", "a", {"a":"{"}]]},
+{"description":"<a a='{'>",
+"input":"<a a='{'>",
+"output":[["StartTag", "a", {"a":"{"}]]},
-{"description":"<a a='\\uDBC0\\uDC00",
-"input":"<a a='\uDBC0\uDC00",
-"output":["ParseError", ["StartTag", "a", {"a":"\uDBC0\uDC00"}]]},
+{"description":"<a a='\\uDBC0\\uDC00'>",
+"input":"<a a='\uDBC0\uDC00'>",
+"output":[["StartTag", "a", {"a":"\uDBC0\uDC00"}]]},
-{"description":"<a a=(",
-"input":"<a a=(",
-"output":["ParseError", ["StartTag", "a", {"a":"("}]]},
+{"description":"<a a=(>",
+"input":"<a a=(>",
+"output":[["StartTag", "a", {"a":"("}]]},
-{"description":"<a a=-",
-"input":"<a a=-",
-"output":["ParseError", ["StartTag", "a", {"a":"-"}]]},
+{"description":"<a a=->",
+"input":"<a a=->",
+"output":[["StartTag", "a", {"a":"-"}]]},
-{"description":"<a a=/",
-"input":"<a a=/",
-"output":["ParseError", ["StartTag", "a", {"a":"/"}]]},
+{"description":"<a a=/>",
+"input":"<a a=/>",
+"output":[["StartTag", "a", {"a":"/"}]]},
-{"description":"<a a=0",
-"input":"<a a=0",
-"output":["ParseError", ["StartTag", "a", {"a":"0"}]]},
+{"description":"<a a=0>",
+"input":"<a a=0>",
+"output":[["StartTag", "a", {"a":"0"}]]},
-{"description":"<a a=1",
-"input":"<a a=1",
-"output":["ParseError", ["StartTag", "a", {"a":"1"}]]},
+{"description":"<a a=1>",
+"input":"<a a=1>",
+"output":[["StartTag", "a", {"a":"1"}]]},
-{"description":"<a a=9",
-"input":"<a a=9",
-"output":["ParseError", ["StartTag", "a", {"a":"9"}]]},
+{"description":"<a a=9>",
+"input":"<a a=9>",
+"output":[["StartTag", "a", {"a":"9"}]]},
-{"description":"<a a=<",
-"input":"<a a=<",
+{"description":"<a a=<>",
+"input":"<a a=<>",
"output":["ParseError", ["StartTag", "a", {"a":"<"}]]},
-{"description":"<a a==",
-"input":"<a a==",
-"output":["ParseError", "ParseError", ["StartTag", "a", {"a":"="}]]},
+{"description":"<a a==>",
+"input":"<a a==>",
+"output":["ParseError", ["StartTag", "a", {"a":"="}]]},
{"description":"<a a=>",
"input":"<a a=>",
"output":["ParseError", ["StartTag", "a", {"a":""}]]},
-{"description":"<a a=?",
-"input":"<a a=?",
-"output":["ParseError", ["StartTag", "a", {"a":"?"}]]},
+{"description":"<a a=?>",
+"input":"<a a=?>",
+"output":[["StartTag", "a", {"a":"?"}]]},
-{"description":"<a a=@",
-"input":"<a a=@",
-"output":["ParseError", ["StartTag", "a", {"a":"@"}]]},
+{"description":"<a a=@>",
+"input":"<a a=@>",
+"output":[["StartTag", "a", {"a":"@"}]]},
-{"description":"<a a=A",
-"input":"<a a=A",
-"output":["ParseError", ["StartTag", "a", {"a":"A"}]]},
+{"description":"<a a=A>",
+"input":"<a a=A>",
+"output":[["StartTag", "a", {"a":"A"}]]},
-{"description":"<a a=B",
-"input":"<a a=B",
-"output":["ParseError", ["StartTag", "a", {"a":"B"}]]},
+{"description":"<a a=B>",
+"input":"<a a=B>",
+"output":[["StartTag", "a", {"a":"B"}]]},
-{"description":"<a a=Y",
-"input":"<a a=Y",
-"output":["ParseError", ["StartTag", "a", {"a":"Y"}]]},
+{"description":"<a a=Y>",
+"input":"<a a=Y>",
+"output":[["StartTag", "a", {"a":"Y"}]]},
-{"description":"<a a=Z",
-"input":"<a a=Z",
-"output":["ParseError", ["StartTag", "a", {"a":"Z"}]]},
+{"description":"<a a=Z>",
+"input":"<a a=Z>",
+"output":[["StartTag", "a", {"a":"Z"}]]},
-{"description":"<a a=`",
-"input":"<a a=`",
+{"description":"<a a=`>",
+"input":"<a a=`>",
"output":["ParseError", ["StartTag", "a", {"a":"`"}]]},
-{"description":"<a a=a",
-"input":"<a a=a",
-"output":["ParseError", ["StartTag", "a", {"a":"a"}]]},
+{"description":"<a a=a>",
+"input":"<a a=a>",
+"output":[["StartTag", "a", {"a":"a"}]]},
-{"description":"<a a=a\\u0000",
-"input":"<a a=a\u0000",
-"output":["ParseError", "ParseError", ["StartTag", "a", {"a":"a\uFFFD"}]]},
+{"description":"<a a=a\\u0000>",
+"input":"<a a=a\u0000>",
+"output":["ParseError", ["StartTag", "a", {"a":"a\uFFFD"}]]},
-{"description":"<a a=a\\u0008",
-"input":"<a a=a\u0008",
-"output":["ParseError", "ParseError", ["StartTag", "a", {"a":"a\u0008"}]]},
+{"description":"<a a=a\\u0008>",
+"input":"<a a=a\u0008>",
+"output":["ParseError", ["StartTag", "a", {"a":"a\u0008"}]]},
-{"description":"<a a=a\\u0009",
-"input":"<a a=a\u0009",
-"output":["ParseError", ["StartTag", "a", {"a":"a"}]]},
+{"description":"<a a=a\\u0009>",
+"input":"<a a=a\u0009>",
+"output":[["StartTag", "a", {"a":"a"}]]},
-{"description":"<a a=a\\u000A",
-"input":"<a a=a\u000A",
-"output":["ParseError", ["StartTag", "a", {"a":"a"}]]},
+{"description":"<a a=a\\u000A>",
+"input":"<a a=a\u000A>",
+"output":[["StartTag", "a", {"a":"a"}]]},
-{"description":"<a a=a\\u000B",
-"input":"<a a=a\u000B",
-"output":["ParseError", "ParseError", ["StartTag", "a", {"a":"a\u000B"}]]},
+{"description":"<a a=a\\u000B>",
+"input":"<a a=a\u000B>",
+"output":["ParseError", ["StartTag", "a", {"a":"a\u000B"}]]},
-{"description":"<a a=a\\u000C",
-"input":"<a a=a\u000C",
-"output":["ParseError", ["StartTag", "a", {"a":"a"}]]},
+{"description":"<a a=a\\u000C>",
+"input":"<a a=a\u000C>",
+"output":[["StartTag", "a", {"a":"a"}]]},
-{"description":"<a a=a\\u000D",
-"input":"<a a=a\u000D",
-"output":["ParseError", ["StartTag", "a", {"a":"a"}]]},
+{"description":"<a a=a\\u000D>",
+"input":"<a a=a\u000D>",
+"output":[["StartTag", "a", {"a":"a"}]]},
-{"description":"<a a=a\\u001F",
-"input":"<a a=a\u001F",
-"output":["ParseError", "ParseError", ["StartTag", "a", {"a":"a\u001F"}]]},
+{"description":"<a a=a\\u001F>",
+"input":"<a a=a\u001F>",
+"output":["ParseError", ["StartTag", "a", {"a":"a\u001F"}]]},
-{"description":"<a a=a ",
-"input":"<a a=a ",
-"output":["ParseError", ["StartTag", "a", {"a":"a"}]]},
+{"description":"<a a=a >",
+"input":"<a a=a >",
+"output":[["StartTag", "a", {"a":"a"}]]},
-{"description":"<a a=a!",
-"input":"<a a=a!",
-"output":["ParseError", ["StartTag", "a", {"a":"a!"}]]},
+{"description":"<a a=a!>",
+"input":"<a a=a!>",
+"output":[["StartTag", "a", {"a":"a!"}]]},
-{"description":"<a a=a\"",
-"input":"<a a=a\"",
-"output":["ParseError", "ParseError", ["StartTag", "a", {"a":"a\""}]]},
+{"description":"<a a=a\">",
+"input":"<a a=a\">",
+"output":["ParseError", ["StartTag", "a", {"a":"a\""}]]},
-{"description":"<a a=a#",
-"input":"<a a=a#",
-"output":["ParseError", ["StartTag", "a", {"a":"a#"}]]},
+{"description":"<a a=a#>",
+"input":"<a a=a#>",
+"output":[["StartTag", "a", {"a":"a#"}]]},
-{"description":"<a a=a%",
-"input":"<a a=a%",
-"output":["ParseError", ["StartTag", "a", {"a":"a%"}]]},
+{"description":"<a a=a%>",
+"input":"<a a=a%>",
+"output":[["StartTag", "a", {"a":"a%"}]]},
-{"description":"<a a=a&",
-"input":"<a a=a&",
-"output":["ParseError", ["StartTag", "a", {"a":"a&"}]]},
+{"description":"<a a=a&>",
+"input":"<a a=a&>",
+"output":[["StartTag", "a", {"a":"a&"}]]},
-{"description":"<a a=a'",
-"input":"<a a=a'",
-"output":["ParseError", "ParseError", ["StartTag", "a", {"a":"a'"}]]},
+{"description":"<a a=a'>",
+"input":"<a a=a'>",
+"output":["ParseError", ["StartTag", "a", {"a":"a'"}]]},
-{"description":"<a a=a(",
-"input":"<a a=a(",
-"output":["ParseError", ["StartTag", "a", {"a":"a("}]]},
+{"description":"<a a=a(>",
+"input":"<a a=a(>",
+"output":[["StartTag", "a", {"a":"a("}]]},
-{"description":"<a a=a-",
-"input":"<a a=a-",
-"output":["ParseError", ["StartTag", "a", {"a":"a-"}]]},
+{"description":"<a a=a->",
+"input":"<a a=a->",
+"output":[["StartTag", "a", {"a":"a-"}]]},
-{"description":"<a a=a/",
-"input":"<a a=a/",
-"output":["ParseError", ["StartTag", "a", {"a":"a/"}]]},
+{"description":"<a a=a/>",
+"input":"<a a=a/>",
+"output":[["StartTag", "a", {"a":"a/"}]]},
-{"description":"<a a=a0",
-"input":"<a a=a0",
-"output":["ParseError", ["StartTag", "a", {"a":"a0"}]]},
+{"description":"<a a=a0>",
+"input":"<a a=a0>",
+"output":[["StartTag", "a", {"a":"a0"}]]},
-{"description":"<a a=a1",
-"input":"<a a=a1",
-"output":["ParseError", ["StartTag", "a", {"a":"a1"}]]},
+{"description":"<a a=a1>",
+"input":"<a a=a1>",
+"output":[["StartTag", "a", {"a":"a1"}]]},
-{"description":"<a a=a9",
-"input":"<a a=a9",
-"output":["ParseError", ["StartTag", "a", {"a":"a9"}]]},
+{"description":"<a a=a9>",
+"input":"<a a=a9>",
+"output":[["StartTag", "a", {"a":"a9"}]]},
-{"description":"<a a=a<",
-"input":"<a a=a<",
+{"description":"<a a=a<>",
+"input":"<a a=a<>",
"output":["ParseError", ["StartTag", "a", {"a":"a<"}]]},
-{"description":"<a a=a=",
-"input":"<a a=a=",
-"output":["ParseError", "ParseError", ["StartTag", "a", {"a":"a="}]]},
+{"description":"<a a=a=>",
+"input":"<a a=a=>",
+"output":["ParseError", ["StartTag", "a", {"a":"a="}]]},
{"description":"<a a=a>",
"input":"<a a=a>",
"output":[["StartTag", "a", {"a":"a"}]]},
-{"description":"<a a=a?",
-"input":"<a a=a?",
-"output":["ParseError", ["StartTag", "a", {"a":"a?"}]]},
+{"description":"<a a=a?>",
+"input":"<a a=a?>",
+"output":[["StartTag", "a", {"a":"a?"}]]},
-{"description":"<a a=a@",
-"input":"<a a=a@",
-"output":["ParseError", ["StartTag", "a", {"a":"a@"}]]},
+{"description":"<a a=a@>",
+"input":"<a a=a@>",
+"output":[["StartTag", "a", {"a":"a@"}]]},
-{"description":"<a a=aA",
-"input":"<a a=aA",
-"output":["ParseError", ["StartTag", "a", {"a":"aA"}]]},
+{"description":"<a a=aA>",
+"input":"<a a=aA>",
+"output":[["StartTag", "a", {"a":"aA"}]]},
-{"description":"<a a=aB",
-"input":"<a a=aB",
-"output":["ParseError", ["StartTag", "a", {"a":"aB"}]]},
+{"description":"<a a=aB>",
+"input":"<a a=aB>",
+"output":[["StartTag", "a", {"a":"aB"}]]},
-{"description":"<a a=aY",
-"input":"<a a=aY",
-"output":["ParseError", ["StartTag", "a", {"a":"aY"}]]},
+{"description":"<a a=aY>",
+"input":"<a a=aY>",
+"output":[["StartTag", "a", {"a":"aY"}]]},
-{"description":"<a a=aZ",
-"input":"<a a=aZ",
-"output":["ParseError", ["StartTag", "a", {"a":"aZ"}]]},
+{"description":"<a a=aZ>",
+"input":"<a a=aZ>",
+"output":[["StartTag", "a", {"a":"aZ"}]]},
-{"description":"<a a=a`",
-"input":"<a a=a`",
+{"description":"<a a=a`>",
+"input":"<a a=a`>",
"output":["ParseError", ["StartTag", "a", {"a":"a`"}]]},
-{"description":"<a a=aa",
-"input":"<a a=aa",
-"output":["ParseError", ["StartTag", "a", {"a":"aa"}]]},
+{"description":"<a a=aa>",
+"input":"<a a=aa>",
+"output":[["StartTag", "a", {"a":"aa"}]]},
-{"description":"<a a=ab",
-"input":"<a a=ab",
-"output":["ParseError", ["StartTag", "a", {"a":"ab"}]]},
+{"description":"<a a=ab>",
+"input":"<a a=ab>",
+"output":[["StartTag", "a", {"a":"ab"}]]},
-{"description":"<a a=ay",
-"input":"<a a=ay",
-"output":["ParseError", ["StartTag", "a", {"a":"ay"}]]},
+{"description":"<a a=ay>",
+"input":"<a a=ay>",
+"output":[["StartTag", "a", {"a":"ay"}]]},
-{"description":"<a a=az",
-"input":"<a a=az",
-"output":["ParseError", ["StartTag", "a", {"a":"az"}]]},
+{"description":"<a a=az>",
+"input":"<a a=az>",
+"output":[["StartTag", "a", {"a":"az"}]]},
-{"description":"<a a=a{",
-"input":"<a a=a{",
-"output":["ParseError", ["StartTag", "a", {"a":"a{"}]]},
+{"description":"<a a=a{>",
+"input":"<a a=a{>",
+"output":[["StartTag", "a", {"a":"a{"}]]},
-{"description":"<a a=a\\uDBC0\\uDC00",
-"input":"<a a=a\uDBC0\uDC00",
-"output":["ParseError", ["StartTag", "a", {"a":"a\uDBC0\uDC00"}]]},
+{"description":"<a a=a\\uDBC0\\uDC00>",
+"input":"<a a=a\uDBC0\uDC00>",
+"output":[["StartTag", "a", {"a":"a\uDBC0\uDC00"}]]},
-{"description":"<a a=b",
-"input":"<a a=b",
-"output":["ParseError", ["StartTag", "a", {"a":"b"}]]},
+{"description":"<a a=b>",
+"input":"<a a=b>",
+"output":[["StartTag", "a", {"a":"b"}]]},
-{"description":"<a a=y",
-"input":"<a a=y",
-"output":["ParseError", ["StartTag", "a", {"a":"y"}]]},
+{"description":"<a a=y>",
+"input":"<a a=y>",
+"output":[["StartTag", "a", {"a":"y"}]]},
-{"description":"<a a=z",
-"input":"<a a=z",
-"output":["ParseError", ["StartTag", "a", {"a":"z"}]]},
+{"description":"<a a=z>",
+"input":"<a a=z>",
+"output":[["StartTag", "a", {"a":"z"}]]},
-{"description":"<a a={",
-"input":"<a a={",
-"output":["ParseError", ["StartTag", "a", {"a":"{"}]]},
+{"description":"<a a={>",
+"input":"<a a={>",
+"output":[["StartTag", "a", {"a":"{"}]]},
-{"description":"<a a=\\uDBC0\\uDC00",
-"input":"<a a=\uDBC0\uDC00",
-"output":["ParseError", ["StartTag", "a", {"a":"\uDBC0\uDC00"}]]},
+{"description":"<a a=\\uDBC0\\uDC00>",
+"input":"<a a=\uDBC0\uDC00>",
+"output":[["StartTag", "a", {"a":"\uDBC0\uDC00"}]]},
{"description":"<a a>",
"input":"<a a>",
"output":[["StartTag", "a", {"a":""}]]},
-{"description":"<a a?",
-"input":"<a a?",
-"output":["ParseError", ["StartTag", "a", {"a?":""}]]},
+{"description":"<a a?>",
+"input":"<a a?>",
+"output":[["StartTag", "a", {"a?":""}]]},
-{"description":"<a a@",
-"input":"<a a@",
-"output":["ParseError", ["StartTag", "a", {"a@":""}]]},
+{"description":"<a a@>",
+"input":"<a a@>",
+"output":[["StartTag", "a", {"a@":""}]]},
-{"description":"<a aA",
-"input":"<a aA",
-"output":["ParseError", ["StartTag", "a", {"aa":""}]]},
+{"description":"<a aA>",
+"input":"<a aA>",
+"output":[["StartTag", "a", {"aa":""}]]},
-{"description":"<a aB",
-"input":"<a aB",
-"output":["ParseError", ["StartTag", "a", {"ab":""}]]},
+{"description":"<a aB>",
+"input":"<a aB>",
+"output":[["StartTag", "a", {"ab":""}]]},
-{"description":"<a aY",
-"input":"<a aY",
-"output":["ParseError", ["StartTag", "a", {"ay":""}]]},
+{"description":"<a aY>",
+"input":"<a aY>",
+"output":[["StartTag", "a", {"ay":""}]]},
-{"description":"<a aZ",
-"input":"<a aZ",
-"output":["ParseError", ["StartTag", "a", {"az":""}]]},
+{"description":"<a aZ>",
+"input":"<a aZ>",
+"output":[["StartTag", "a", {"az":""}]]},
-{"description":"<a a[",
-"input":"<a a[",
-"output":["ParseError", ["StartTag", "a", {"a[":""}]]},
+{"description":"<a a[>",
+"input":"<a a[>",
+"output":[["StartTag", "a", {"a[":""}]]},
-{"description":"<a a`",
-"input":"<a a`",
-"output":["ParseError", ["StartTag", "a", {"a`":""}]]},
+{"description":"<a a`>",
+"input":"<a a`>",
+"output":[["StartTag", "a", {"a`":""}]]},
-{"description":"<a aa",
-"input":"<a aa",
-"output":["ParseError", ["StartTag", "a", {"aa":""}]]},
+{"description":"<a aa>",
+"input":"<a aa>",
+"output":[["StartTag", "a", {"aa":""}]]},
-{"description":"<a ab",
-"input":"<a ab",
-"output":["ParseError", ["StartTag", "a", {"ab":""}]]},
+{"description":"<a ab>",
+"input":"<a ab>",
+"output":[["StartTag", "a", {"ab":""}]]},
-{"description":"<a ay",
-"input":"<a ay",
-"output":["ParseError", ["StartTag", "a", {"ay":""}]]},
+{"description":"<a ay>",
+"input":"<a ay>",
+"output":[["StartTag", "a", {"ay":""}]]},
-{"description":"<a az",
-"input":"<a az",
-"output":["ParseError", ["StartTag", "a", {"az":""}]]},
+{"description":"<a az>",
+"input":"<a az>",
+"output":[["StartTag", "a", {"az":""}]]},
-{"description":"<a a{",
-"input":"<a a{",
-"output":["ParseError", ["StartTag", "a", {"a{":""}]]},
+{"description":"<a a{>",
+"input":"<a a{>",
+"output":[["StartTag", "a", {"a{":""}]]},
-{"description":"<a a\\uDBC0\\uDC00",
-"input":"<a a\uDBC0\uDC00",
-"output":["ParseError", ["StartTag", "a", {"a\uDBC0\uDC00":""}]]},
+{"description":"<a a\\uDBC0\\uDC00>",
+"input":"<a a\uDBC0\uDC00>",
+"output":[["StartTag", "a", {"a\uDBC0\uDC00":""}]]},
-{"description":"<a b",
-"input":"<a b",
-"output":["ParseError", ["StartTag", "a", {"b":""}]]},
+{"description":"<a b>",
+"input":"<a b>",
+"output":[["StartTag", "a", {"b":""}]]},
-{"description":"<a y",
-"input":"<a y",
-"output":["ParseError", ["StartTag", "a", {"y":""}]]},
+{"description":"<a y>",
+"input":"<a y>",
+"output":[["StartTag", "a", {"y":""}]]},
-{"description":"<a z",
-"input":"<a z",
-"output":["ParseError", ["StartTag", "a", {"z":""}]]},
+{"description":"<a z>",
+"input":"<a z>",
+"output":[["StartTag", "a", {"z":""}]]},
-{"description":"<a {",
-"input":"<a {",
-"output":["ParseError", ["StartTag", "a", {"{":""}]]},
+{"description":"<a {>",
+"input":"<a {>",
+"output":[["StartTag", "a", {"{":""}]]},
-{"description":"<a \\uDBC0\\uDC00",
-"input":"<a \uDBC0\uDC00",
-"output":["ParseError", ["StartTag", "a", {"\uDBC0\uDC00":""}]]},
+{"description":"<a \\uDBC0\\uDC00>",
+"input":"<a \uDBC0\uDC00>",
+"output":[["StartTag", "a", {"\uDBC0\uDC00":""}]]},
-{"description":"<a!",
-"input":"<a!",
-"output":["ParseError", ["StartTag", "a!", {}]]},
+{"description":"<a!>",
+"input":"<a!>",
+"output":[["StartTag", "a!", {}]]},
-{"description":"<a\"",
-"input":"<a\"",
-"output":["ParseError", ["StartTag", "a\"", {}]]},
+{"description":"<a\">",
+"input":"<a\">",
+"output":[["StartTag", "a\"", {}]]},
-{"description":"<a&",
-"input":"<a&",
-"output":["ParseError", ["StartTag", "a&", {}]]},
+{"description":"<a&>",
+"input":"<a&>",
+"output":[["StartTag", "a&", {}]]},
-{"description":"<a'",
-"input":"<a'",
-"output":["ParseError", ["StartTag", "a'", {}]]},
+{"description":"<a'>",
+"input":"<a'>",
+"output":[["StartTag", "a'", {}]]},
-{"description":"<a-",
-"input":"<a-",
-"output":["ParseError", ["StartTag", "a-", {}]]},
+{"description":"<a->",
+"input":"<a->",
+"output":[["StartTag", "a-", {}]]},
-{"description":"<a.",
-"input":"<a.",
-"output":["ParseError", ["StartTag", "a.", {}]]},
+{"description":"<a.>",
+"input":"<a.>",
+"output":[["StartTag", "a.", {}]]},
-{"description":"<a/",
-"input":"<a/",
-"output":["ParseError", ["StartTag", "a", {}]]},
+{"description":"<a/>",
+"input":"<a/>",
+"output":[["StartTag", "a", {}, true]]},
-{"description":"<a/\\u0000",
-"input":"<a/\u0000",
-"output":["ParseError", "ParseError", "ParseError", ["StartTag", "a", {"\uFFFD":""}]]},
+{"description":"<a/\\u0000>",
+"input":"<a/\u0000>",
+"output":["ParseError", "ParseError", ["StartTag", "a", {"\uFFFD":""}]]},
-{"description":"<a/\\u0009",
-"input":"<a/\u0009",
-"output":["ParseError", "ParseError", ["StartTag", "a", {}]]},
+{"description":"<a/\\u0009>",
+"input":"<a/\u0009>",
+"output":["ParseError", ["StartTag", "a", {}]]},
-{"description":"<a/\\u000A",
-"input":"<a/\u000A",
-"output":["ParseError", "ParseError", ["StartTag", "a", {}]]},
+{"description":"<a/\\u000A>",
+"input":"<a/\u000A>",
+"output":["ParseError", ["StartTag", "a", {}]]},
-{"description":"<a/\\u000B",
-"input":"<a/\u000B",
-"output":["ParseError", "ParseError", "ParseError", ["StartTag", "a", {"\u000B":""}]]},
+{"description":"<a/\\u000B>",
+"input":"<a/\u000B>",
+"output":["ParseError", "ParseError", ["StartTag", "a", {"\u000B":""}]]},
-{"description":"<a/\\u000C",
-"input":"<a/\u000C",
-"output":["ParseError", "ParseError", ["StartTag", "a", {}]]},
+{"description":"<a/\\u000C>",
+"input":"<a/\u000C>",
+"output":["ParseError", ["StartTag", "a", {}]]},
-{"description":"<a/ ",
-"input":"<a/ ",
-"output":["ParseError", "ParseError", ["StartTag", "a", {}]]},
+{"description":"<a/ >",
+"input":"<a/ >",
+"output":["ParseError", ["StartTag", "a", {}]]},
-{"description":"<a/!",
-"input":"<a/!",
-"output":["ParseError", "ParseError", ["StartTag", "a", {"!":""}]]},
+{"description":"<a/!>",
+"input":"<a/!>",
+"output":["ParseError", ["StartTag", "a", {"!":""}]]},
-{"description":"<a/\"",
-"input":"<a/\"",
-"output":["ParseError", "ParseError", "ParseError", ["StartTag", "a", {"\"":""}]]},
+{"description":"<a/\">",
+"input":"<a/\">",
+"output":["ParseError", "ParseError", ["StartTag", "a", {"\"":""}]]},
-{"description":"<a/&",
-"input":"<a/&",
-"output":["ParseError", "ParseError", ["StartTag", "a", {"&":""}]]},
+{"description":"<a/&>",
+"input":"<a/&>",
+"output":["ParseError", ["StartTag", "a", {"&":""}]]},
-{"description":"<a/'",
-"input":"<a/'",
-"output":["ParseError", "ParseError", "ParseError", ["StartTag", "a", {"'":""}]]},
+{"description":"<a/'>",
+"input":"<a/'>",
+"output":["ParseError", "ParseError", ["StartTag", "a", {"'":""}]]},
-{"description":"<a/-",
-"input":"<a/-",
-"output":["ParseError", "ParseError", ["StartTag", "a", {"-":""}]]},
+{"description":"<a/->",
+"input":"<a/->",
+"output":["ParseError", ["StartTag", "a", {"-":""}]]},
-{"description":"<a//",
-"input":"<a//",
-"output":["ParseError", "ParseError", ["StartTag", "a", {}]]},
+{"description":"<a//>",
+"input":"<a//>",
+"output":["ParseError", ["StartTag", "a", {}, true]]},
-{"description":"<a/0",
-"input":"<a/0",
-"output":["ParseError", "ParseError", ["StartTag", "a", {"0":""}]]},
+{"description":"<a/0>",
+"input":"<a/0>",
+"output":["ParseError", ["StartTag", "a", {"0":""}]]},
-{"description":"<a/1",
-"input":"<a/1",
-"output":["ParseError", "ParseError", ["StartTag", "a", {"1":""}]]},
+{"description":"<a/1>",
+"input":"<a/1>",
+"output":["ParseError", ["StartTag", "a", {"1":""}]]},
-{"description":"<a/9",
-"input":"<a/9",
-"output":["ParseError", "ParseError", ["StartTag", "a", {"9":""}]]},
+{"description":"<a/9>",
+"input":"<a/9>",
+"output":["ParseError", ["StartTag", "a", {"9":""}]]},
-{"description":"<a/<",
-"input":"<a/<",
+{"description":"<a/<>",
+"input":"<a/<>",
"output":["ParseError", "ParseError", ["StartTag", "a", {"<":""}]]},
-{"description":"<a/=",
-"input":"<a/=",
-"output":["ParseError", "ParseError", "ParseError", ["StartTag", "a", {"=":""}]]},
+{"description":"<a/=>",
+"input":"<a/=>",
+"output":["ParseError", "ParseError", ["StartTag", "a", {"=":""}]]},
{"description":"<a/>",
"input":"<a/>",
"output":[["StartTag", "a", {}, true]]},
-{"description":"<a/?",
-"input":"<a/?",
-"output":["ParseError", "ParseError", ["StartTag", "a", {"?":""}]]},
+{"description":"<a/?>",
+"input":"<a/?>",
+"output":["ParseError", ["StartTag", "a", {"?":""}]]},
-{"description":"<a/@",
-"input":"<a/@",
-"output":["ParseError", "ParseError", ["StartTag", "a", {"@":""}]]},
+{"description":"<a/@>",
+"input":"<a/@>",
+"output":["ParseError", ["StartTag", "a", {"@":""}]]},
-{"description":"<a/A",
-"input":"<a/A",
-"output":["ParseError", "ParseError", ["StartTag", "a", {"a":""}]]},
+{"description":"<a/A>",
+"input":"<a/A>",
+"output":["ParseError", ["StartTag", "a", {"a":""}]]},
-{"description":"<a/B",
-"input":"<a/B",
-"output":["ParseError", "ParseError", ["StartTag", "a", {"b":""}]]},
+{"description":"<a/B>",
+"input":"<a/B>",
+"output":["ParseError", ["StartTag", "a", {"b":""}]]},
-{"description":"<a/Y",
-"input":"<a/Y",
-"output":["ParseError", "ParseError", ["StartTag", "a", {"y":""}]]},
+{"description":"<a/Y>",
+"input":"<a/Y>",
+"output":["ParseError", ["StartTag", "a", {"y":""}]]},
-{"description":"<a/Z",
-"input":"<a/Z",
-"output":["ParseError", "ParseError", ["StartTag", "a", {"z":""}]]},
+{"description":"<a/Z>",
+"input":"<a/Z>",
+"output":["ParseError", ["StartTag", "a", {"z":""}]]},
-{"description":"<a/`",
-"input":"<a/`",
-"output":["ParseError", "ParseError", ["StartTag", "a", {"`":""}]]},
+{"description":"<a/`>",
+"input":"<a/`>",
+"output":["ParseError", ["StartTag", "a", {"`":""}]]},
-{"description":"<a/a",
-"input":"<a/a",
-"output":["ParseError", "ParseError", ["StartTag", "a", {"a":""}]]},
+{"description":"<a/a>",
+"input":"<a/a>",
+"output":["ParseError", ["StartTag", "a", {"a":""}]]},
-{"description":"<a/b",
-"input":"<a/b",
-"output":["ParseError", "ParseError", ["StartTag", "a", {"b":""}]]},
+{"description":"<a/b>",
+"input":"<a/b>",
+"output":["ParseError", ["StartTag", "a", {"b":""}]]},
-{"description":"<a/y",
-"input":"<a/y",
-"output":["ParseError", "ParseError", ["StartTag", "a", {"y":""}]]},
+{"description":"<a/y>",
+"input":"<a/y>",
+"output":["ParseError", ["StartTag", "a", {"y":""}]]},
-{"description":"<a/z",
-"input":"<a/z",
-"output":["ParseError", "ParseError", ["StartTag", "a", {"z":""}]]},
+{"description":"<a/z>",
+"input":"<a/z>",
+"output":["ParseError", ["StartTag", "a", {"z":""}]]},
-{"description":"<a/{",
-"input":"<a/{",
-"output":["ParseError", "ParseError", ["StartTag", "a", {"{":""}]]},
+{"description":"<a/{>",
+"input":"<a/{>",
+"output":["ParseError", ["StartTag", "a", {"{":""}]]},
-{"description":"<a/\\uDBC0\\uDC00",
-"input":"<a/\uDBC0\uDC00",
-"output":["ParseError", "ParseError", ["StartTag", "a", {"\uDBC0\uDC00":""}]]},
+{"description":"<a/\\uDBC0\\uDC00>",
+"input":"<a/\uDBC0\uDC00>",
+"output":["ParseError", ["StartTag", "a", {"\uDBC0\uDC00":""}]]},
-{"description":"<a0",
-"input":"<a0",
-"output":["ParseError", ["StartTag", "a0", {}]]},
+{"description":"<a0>",
+"input":"<a0>",
+"output":[["StartTag", "a0", {}]]},
-{"description":"<a1",
-"input":"<a1",
-"output":["ParseError", ["StartTag", "a1", {}]]},
+{"description":"<a1>",
+"input":"<a1>",
+"output":[["StartTag", "a1", {}]]},
-{"description":"<a9",
-"input":"<a9",
-"output":["ParseError", ["StartTag", "a9", {}]]},
+{"description":"<a9>",
+"input":"<a9>",
+"output":[["StartTag", "a9", {}]]},
-{"description":"<a<",
-"input":"<a<",
-"output":["ParseError", ["StartTag", "a<", {}]]},
+{"description":"<a<>",
+"input":"<a<>",
+"output":[["StartTag", "a<", {}]]},
-{"description":"<a=",
-"input":"<a=",
-"output":["ParseError", ["StartTag", "a=", {}]]},
+{"description":"<a=>",
+"input":"<a=>",
+"output":[["StartTag", "a=", {}]]},
{"description":"<a>",
"input":"<a>",
"output":[["StartTag", "a", {}]]},
-{"description":"<a?",
-"input":"<a?",
-"output":["ParseError", ["StartTag", "a?", {}]]},
+{"description":"<a?>",
+"input":"<a?>",
+"output":[["StartTag", "a?", {}]]},
-{"description":"<a@",
-"input":"<a@",
-"output":["ParseError", ["StartTag", "a@", {}]]},
+{"description":"<a@>",
+"input":"<a@>",
+"output":[["StartTag", "a@", {}]]},
-{"description":"<aA",
-"input":"<aA",
-"output":["ParseError", ["StartTag", "aa", {}]]},
+{"description":"<aA>",
+"input":"<aA>",
+"output":[["StartTag", "aa", {}]]},
-{"description":"<aB",
-"input":"<aB",
-"output":["ParseError", ["StartTag", "ab", {}]]},
+{"description":"<aB>",
+"input":"<aB>",
+"output":[["StartTag", "ab", {}]]},
-{"description":"<aY",
-"input":"<aY",
-"output":["ParseError", ["StartTag", "ay", {}]]},
+{"description":"<aY>",
+"input":"<aY>",
+"output":[["StartTag", "ay", {}]]},
-{"description":"<aZ",
-"input":"<aZ",
-"output":["ParseError", ["StartTag", "az", {}]]},
+{"description":"<aZ>",
+"input":"<aZ>",
+"output":[["StartTag", "az", {}]]},
-{"description":"<a[",
-"input":"<a[",
-"output":["ParseError", ["StartTag", "a[", {}]]},
+{"description":"<a[>",
+"input":"<a[>",
+"output":[["StartTag", "a[", {}]]},
-{"description":"<a`",
-"input":"<a`",
-"output":["ParseError", ["StartTag", "a`", {}]]},
+{"description":"<a`>",
+"input":"<a`>",
+"output":[["StartTag", "a`", {}]]},
-{"description":"<aa",
-"input":"<aa",
-"output":["ParseError", ["StartTag", "aa", {}]]},
+{"description":"<aa>",
+"input":"<aa>",
+"output":[["StartTag", "aa", {}]]},
-{"description":"<ab",
-"input":"<ab",
-"output":["ParseError", ["StartTag", "ab", {}]]},
+{"description":"<ab>",
+"input":"<ab>",
+"output":[["StartTag", "ab", {}]]},
-{"description":"<ay",
-"input":"<ay",
-"output":["ParseError", ["StartTag", "ay", {}]]},
+{"description":"<ay>",
+"input":"<ay>",
+"output":[["StartTag", "ay", {}]]},
-{"description":"<az",
-"input":"<az",
-"output":["ParseError", ["StartTag", "az", {}]]},
+{"description":"<az>",
+"input":"<az>",
+"output":[["StartTag", "az", {}]]},
-{"description":"<a{",
-"input":"<a{",
-"output":["ParseError", ["StartTag", "a{", {}]]},
+{"description":"<a{>",
+"input":"<a{>",
+"output":[["StartTag", "a{", {}]]},
-{"description":"<a\\uDBC0\\uDC00",
-"input":"<a\uDBC0\uDC00",
-"output":["ParseError", ["StartTag", "a\uDBC0\uDC00", {}]]},
+{"description":"<a\\uDBC0\\uDC00>",
+"input":"<a\uDBC0\uDC00>",
+"output":[["StartTag", "a\uDBC0\uDC00", {}]]},
-{"description":"<b",
-"input":"<b",
-"output":["ParseError", ["StartTag", "b", {}]]},
+{"description":"<b>",
+"input":"<b>",
+"output":[["StartTag", "b", {}]]},
-{"description":"<y",
-"input":"<y",
-"output":["ParseError", ["StartTag", "y", {}]]},
+{"description":"<y>",
+"input":"<y>",
+"output":[["StartTag", "y", {}]]},
-{"description":"<z",
-"input":"<z",
-"output":["ParseError", ["StartTag", "z", {}]]},
+{"description":"<z>",
+"input":"<z>",
+"output":[["StartTag", "z", {}]]},
{"description":"<{",
"input":"<{",
diff --git a/test/data/tokeniser2/test4.test b/test/data/tokeniser2/test4.test
index ec8f72c..4be94b0 100644
--- a/test/data/tokeniser2/test4.test
+++ b/test/data/tokeniser2/test4.test
@@ -1,11 +1,11 @@
{"tests": [
{"description":"< in attribute name",
-"input":"<z/0 <",
+"input":"<z/0 <>",
"output":["ParseError", "ParseError", ["StartTag", "z", {"0": "", "<": ""}]]},
{"description":"< in attribute value",
-"input":"<z x=<",
+"input":"<z x=<>",
"output":["ParseError", ["StartTag", "z", {"x": "<"}]]},
{"description":"= in unquoted attribute value",
@@ -28,25 +28,25 @@
"input":"<z ====>",
"output":["ParseError", "ParseError", "ParseError", ["StartTag", "z", {"=": "=="}]]},
-{"description":"Allowed \" after ampersand in attribute value",
+{"description":"\" after ampersand in double-quoted attribute value",
"input":"<z z=\"&\">",
"output":[["StartTag", "z", {"z": "&"}]]},
-{"description":"Non-allowed ' after ampersand in attribute value",
+{"description":"' after ampersand in double-quoted attribute value",
"input":"<z z=\"&'\">",
-"output":["ParseError", ["StartTag", "z", {"z": "&'"}]]},
+"output":[["StartTag", "z", {"z": "&'"}]]},
-{"description":"Allowed ' after ampersand in attribute value",
+{"description":"' after ampersand in single-quoted attribute value",
"input":"<z z='&'>",
"output":[["StartTag", "z", {"z": "&"}]]},
-{"description":"Non-allowed \" after ampersand in attribute value",
+{"description":"\" after ampersand in single-quoted attribute value",
"input":"<z z='&\"'>",
-"output":["ParseError", ["StartTag", "z", {"z": "&\""}]]},
+"output":[["StartTag", "z", {"z": "&\""}]]},
{"description":"Text after bogus character reference",
"input":"<z z='&xlink_xmlns;'>bar<z>",
-"output":["ParseError",["StartTag","z",{"z":"&xlink_xmlns;"}],["Character","bar"],["StartTag","z",{}]]},
+"output":[["StartTag","z",{"z":"&xlink_xmlns;"}],["Character","bar"],["StartTag","z",{}]]},
{"description":"Text after hex character reference",
"input":"<z z='  foo'>bar<z>",
@@ -98,11 +98,11 @@
{"description":"CR EOF in tag name",
"input":"<z\r",
-"output":["ParseError", ["StartTag", "z", {}]]},
+"output":["ParseError"]},
{"description":"Slash EOF in tag name",
"input":"<z/",
-"output":["ParseError", ["StartTag", "z", {}]]},
+"output":["ParseError"]},
{"description":"Zero hex numeric entity",
"input":"�",
@@ -134,7 +134,7 @@
{"description":"Maximum non-BMP numeric entity",
"input":"",
-"output":["ParseError", ["Character", "\uFFFD"]]},
+"output":["ParseError", ["Character", "\uDBFF\uDFFF"]]},
{"description":"Above maximum numeric entity",
"input":"�",
@@ -222,12 +222,12 @@
{"description":"U+0000 in lookahead region after non-matching character",
"input":"<!doc>\u0000",
-"output":["ParseError", ["Comment", "doc"], "ParseError", ["Character", "\uFFFD"]],
+"output":["ParseError", ["Comment", "doc"], "ParseError", ["Character", "\u0000"]],
"ignoreErrorOrder":true},
{"description":"U+0000 in lookahead region",
"input":"<!doc\u0000",
-"output":["ParseError", "ParseError", ["Comment", "doc\uFFFD"]],
+"output":["ParseError", ["Comment", "doc\uFFFD"]],
"ignoreErrorOrder":true},
{"description":"U+0080 in lookahead region",
@@ -245,11 +245,6 @@
"output":["ParseError", "ParseError", ["Comment", "doc\uD83F\uDFFF"]],
"ignoreErrorOrder":true},
-{"description":"CR followed by U+0000",
-"input":"\r\u0000",
-"output":["ParseError", ["Character", "\n\uFFFD"]],
-"ignoreErrorOrder":true},
-
{"description":"CR followed by non-LF",
"input":"\r?",
"output":[["Character", "\n?"]]},
@@ -300,6 +295,50 @@
{"description":"Doctype html x>text",
"input":"<!DOCTYPE html x>text",
-"output":["ParseError", ["DOCTYPE", "html", null, null, false], ["Character", "text"]]}
+"output":["ParseError", ["DOCTYPE", "html", null, null, false], ["Character", "text"]]},
+
+{"description":"Grave accent in unquoted attribute",
+"input":"<a a=aa`>",
+"output":["ParseError", ["StartTag", "a", {"a":"aa`"}]]},
+
+{"description":"EOF in tag name state ",
+"input":"<a",
+"output":["ParseError"]},
+
+{"description":"EOF in tag name state",
+"input":"<a",
+"output":["ParseError"]},
+
+{"description":"EOF in before attribute name state",
+"input":"<a ",
+"output":["ParseError"]},
+
+{"description":"EOF in attribute name state",
+"input":"<a a",
+"output":["ParseError"]},
+
+{"description":"EOF in after attribute name state",
+"input":"<a a ",
+"output":["ParseError"]},
+
+{"description":"EOF in before attribute value state",
+"input":"<a a =",
+"output":["ParseError"]},
+
+{"description":"EOF in attribute value (double quoted) state",
+"input":"<a a =\"a",
+"output":["ParseError"]},
+
+{"description":"EOF in attribute value (single quoted) state",
+"input":"<a a ='a",
+"output":["ParseError"]},
+
+{"description":"EOF in attribute value (unquoted) state",
+"input":"<a a =a",
+"output":["ParseError"]},
+
+{"description":"EOF in after attribute value state",
+"input":"<a a ='a'",
+"output":["ParseError"]}
]}
diff --git a/test/data/tokeniser2/unicodeChars.test b/test/data/tokeniser2/unicodeChars.test
index 9b59015..c778668 100644
--- a/test/data/tokeniser2/unicodeChars.test
+++ b/test/data/tokeniser2/unicodeChars.test
@@ -112,14 +112,6 @@
"input": "\u007F",
"output": ["ParseError", ["Character", "\u007F"]]},
-{"description": "Invalid Unicode character U+D800",
-"input": "\uD800",
-"output": ["ParseError", ["Character", "\uD800"]]},
-
-{"description": "Invalid Unicode character U+DFFF",
-"input": "\uDFFF",
-"output": ["ParseError", ["Character", "\uDFFF"]]},
-
{"description": "Invalid Unicode character U+FDD0",
"input": "\uFDD0",
"output": ["ParseError", ["Character", "\uFDD0"]]},
diff --git a/test/testutils.h b/test/testutils.h
index 45870f9..fa159d6 100644
--- a/test/testutils.h
+++ b/test/testutils.h
@@ -63,6 +63,7 @@ typedef bool (*line_func)(const char *data, size_t datalen, void *pw);
static size_t parse_strlen(const char *str, size_t limit);
bool parse_testfile(const char *filename, line_func callback, void *pw);
size_t parse_filesize(const char *filename);
+size_t n_str(const char *str);
/**
* Testcase datafile parser driver
@@ -147,6 +148,24 @@ size_t parse_filesize(const char *filename)
return len;
}
+/**
+ * Utility string length measurer; assumes strings are '\0' terminated
+ *
+ * \param str String to measure length of
+ * \return String length
+ */
+size_t n_str(const char *str)
+{
+ size_t len = 0;
+
+ if (str == NULL)
+ return 0;
+
+ for (; *str++;len++);
+
+ return len;
+}
+
#ifndef strndup
char *my_strndup(const char *s, size_t n);
diff --git a/test/tokeniser2.c b/test/tokeniser2.c
index c8ab9c0..c320f42 100644
--- a/test/tokeniser2.c
+++ b/test/tokeniser2.c
@@ -14,6 +14,8 @@
#include "testutils.h"
+#define strlen n_str
+
typedef struct context {
const uint8_t *pbuffer;
@@ -301,7 +303,8 @@ hubbub_error token_handler(const hubbub_token *token, void *pw)
gotsys,
(int) token->data.doctype.system_id.len);
}
-
+ printf(":%d: :%d:\n", (int)token->data.doctype.name.len, (int) strlen(expname));
+ printf(":%s: :%s:\n", gotname, expname);
assert(token->data.doctype.name.len == strlen(expname));
assert(strncmp(gotname, expname, strlen(expname)) == 0);
--
1.8.3.2
-
0002-Replacing-content-model-with-states-except-SCRIPT-DA.patch (57,023 bytes) 2014-03-11 17:00
From 2a58f19635d9c8b2c5a1ce293b6a3fc5f57be7d8 Mon Sep 17 00:00:00 2001
From: Achal-Aggarwal <theachalaggarwal@gmail.com>
Date: Tue, 11 Mar 2014 17:57:08 +0530
Subject: [PATCH 2/4] Replacing content model with states (except SCRIPT DATA).
---
include/hubbub/parser.h | 6 +-
include/hubbub/types.h | 13 +-
src/parser.c | 4 +-
src/tokeniser/tokeniser.c | 1224 +++++++++++++++++++++++----
src/tokeniser/tokeniser.h | 6 +-
src/treebuilder/in_body.c | 4 +-
src/treebuilder/treebuilder.c | 6 +-
test/data/tokeniser2/contentModelFlags.test | 50 +-
test/data/tokeniser2/escapeFlag.test | 24 +-
test/tokeniser2.c | 47 +-
10 files changed, 1129 insertions(+), 255 deletions(-)
diff --git a/include/hubbub/parser.h b/include/hubbub/parser.h
index bdc5e20..42d68cc 100644
--- a/include/hubbub/parser.h
+++ b/include/hubbub/parser.h
@@ -29,7 +29,7 @@ typedef struct hubbub_parser hubbub_parser;
typedef enum hubbub_parser_opttype {
HUBBUB_PARSER_TOKEN_HANDLER,
HUBBUB_PARSER_ERROR_HANDLER,
- HUBBUB_PARSER_CONTENT_MODEL,
+ HUBBUB_PARSER_INITIAL_STATE,
HUBBUB_PARSER_TREE_HANDLER,
HUBBUB_PARSER_DOCUMENT_NODE,
HUBBUB_PARSER_ENABLE_SCRIPTING,
@@ -51,8 +51,8 @@ typedef union hubbub_parser_optparams {
} error_handler; /**< Error handling callback */
struct {
- hubbub_content_model model;
- } content_model; /**< Current content model */
+ hubbub_initial_state state;
+ } initial_state; /**< Initial state of tokeniser */
hubbub_tree_handler *tree_handler; /**< Tree handling callbacks */
diff --git a/include/hubbub/types.h b/include/hubbub/types.h
index e5c208b..6e14fb7 100644
--- a/include/hubbub/types.h
+++ b/include/hubbub/types.h
@@ -29,12 +29,13 @@ typedef enum hubbub_charset_source {
/**
* Content model flag
*/
-typedef enum hubbub_content_model {
- HUBBUB_CONTENT_MODEL_PCDATA,
- HUBBUB_CONTENT_MODEL_RCDATA,
- HUBBUB_CONTENT_MODEL_CDATA,
- HUBBUB_CONTENT_MODEL_PLAINTEXT
-} hubbub_content_model;
+typedef enum hubbub_initial_state {
+ HUBBUB_INITIAL_STATE_DATA,
+ HUBBUB_INITIAL_STATE_RCDATA,
+ HUBBUB_INITIAL_STATE_CDATA,
+ HUBBUB_INITIAL_STATE_PLAINTEXT,
+ HUBBUB_INITIAL_STATE_RAWTEXT
+} hubbub_initial_state;
/**
* Quirks mode flag
diff --git a/src/parser.c b/src/parser.c
index 671e129..749c674 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -160,9 +160,9 @@ hubbub_error hubbub_parser_setopt(hubbub_parser *parser,
}
break;
- case HUBBUB_PARSER_CONTENT_MODEL:
+ case HUBBUB_PARSER_INITIAL_STATE:
result = hubbub_tokeniser_setopt(parser->tok,
- HUBBUB_TOKENISER_CONTENT_MODEL,
+ HUBBUB_TOKENISER_INITIAL_STATE,
(hubbub_tokeniser_optparams *) params);
break;
diff --git a/src/tokeniser/tokeniser.c b/src/tokeniser/tokeniser.c
index 3eab8a7..7152f05 100644
--- a/src/tokeniser/tokeniser.c
+++ b/src/tokeniser/tokeniser.c
@@ -43,16 +43,26 @@ static const hubbub_string u_fffd_str = { u_fffd, sizeof(u_fffd) };
static const uint8_t lf = '\n';
static const hubbub_string lf_str = { &lf, 1 };
-
/**
* Tokeniser states
*/
typedef enum hubbub_tokeniser_state {
STATE_DATA,
STATE_CHARACTER_REFERENCE_DATA,
+ STATE_RCDATA,
+ STATE_CHARACTER_REFERENCE_RCDATA,
+ STATE_RAWTEXT,
+ STATE_SCRIPT_DATA,
+ STATE_PLAINTEXT,
STATE_TAG_OPEN,
STATE_CLOSE_TAG_OPEN,
STATE_TAG_NAME,
+ STATE_RCDATA_LESSTHAN,
+ STATE_RCDATA_CLOSE_TAG_OPEN,
+ STATE_RCDATA_CLOSE_TAG_NAME,
+ STATE_RAWTEXT_LESSTHAN,
+ STATE_RAWTEXT_CLOSE_TAG_OPEN,
+ STATE_RAWTEXT_CLOSE_TAG_NAME,
STATE_BEFORE_ATTRIBUTE_NAME,
STATE_ATTRIBUTE_NAME,
STATE_AFTER_ATTRIBUTE_NAME,
@@ -166,8 +176,6 @@ typedef struct hubbub_tokeniser_context {
*/
struct hubbub_tokeniser {
hubbub_tokeniser_state state; /**< Current tokeniser state */
- hubbub_content_model content_model; /**< Current content
- * model flag */
bool escape_flag; /**< Escape flag **/
bool process_cdata_section; /**< Whether to process CDATA sections*/
bool paused; /**< flag for if parsing is currently paused */
@@ -188,12 +196,34 @@ struct hubbub_tokeniser {
static hubbub_error hubbub_tokeniser_handle_data(hubbub_tokeniser *tokeniser);
static hubbub_error hubbub_tokeniser_handle_character_reference_data(
hubbub_tokeniser *tokeniser);
+static hubbub_error hubbub_tokeniser_handle_rcdata(
+ hubbub_tokeniser *tokeniser);
+static hubbub_error hubbub_tokeniser_handle_character_reference_rcdata(
+ hubbub_tokeniser *tokeniser);
+static hubbub_error hubbub_tokeniser_handle_rawtext(
+ hubbub_tokeniser *tokeniser);
+static hubbub_error hubbub_tokeniser_handle_script_data(
+ hubbub_tokeniser *tokeniser);
+static hubbub_error hubbub_tokeniser_handle_plaintext(
+ hubbub_tokeniser *tokeniser);
static hubbub_error hubbub_tokeniser_handle_tag_open(
hubbub_tokeniser *tokeniser);
static hubbub_error hubbub_tokeniser_handle_close_tag_open(
hubbub_tokeniser *tokeniser);
static hubbub_error hubbub_tokeniser_handle_tag_name(
hubbub_tokeniser *tokeniser);
+static hubbub_error hubbub_tokeniser_handle_rcdata_lessthan(
+ hubbub_tokeniser *tokeniser);
+static hubbub_error hubbub_tokeniser_handle_rcdata_close_tag_open(
+ hubbub_tokeniser *tokeniser);
+static hubbub_error hubbub_tokeniser_handle_rcdata_close_tag_name(
+ hubbub_tokeniser *tokeniser);
+static hubbub_error hubbub_tokeniser_handle_rawtext_lessthan(
+ hubbub_tokeniser *tokeniser);
+static hubbub_error hubbub_tokeniser_handle_rawtext_close_tag_open(
+ hubbub_tokeniser *tokeniser);
+static hubbub_error hubbub_tokeniser_handle_rawtext_close_tag_name(
+ hubbub_tokeniser *tokeniser);
static hubbub_error hubbub_tokeniser_handle_before_attribute_name(
hubbub_tokeniser *tokeniser);
static hubbub_error hubbub_tokeniser_handle_attribute_name(
@@ -313,7 +343,6 @@ hubbub_error hubbub_tokeniser_create(parserutils_inputstream *input,
}
tok->state = STATE_DATA;
- tok->content_model = HUBBUB_CONTENT_MODEL_PCDATA;
tok->escape_flag = false;
tok->process_cdata_section = false;
@@ -385,8 +414,18 @@ hubbub_error hubbub_tokeniser_setopt(hubbub_tokeniser *tokeniser,
tokeniser->error_handler = params->error_handler.handler;
tokeniser->error_pw = params->error_handler.pw;
break;
- case HUBBUB_TOKENISER_CONTENT_MODEL:
- tokeniser->content_model = params->content_model.model;
+ case HUBBUB_TOKENISER_INITIAL_STATE:
+ if (params->initial_state.state == HUBBUB_INITIAL_STATE_DATA) {
+ tokeniser->state = STATE_DATA;
+ } else if (params->initial_state.state == HUBBUB_INITIAL_STATE_RCDATA) {
+ tokeniser->state = STATE_RCDATA;
+ } else if (params->initial_state.state == HUBBUB_INITIAL_STATE_CDATA) {
+ tokeniser->state = STATE_CDATA_BLOCK;
+ } else if (params->initial_state.state == HUBBUB_INITIAL_STATE_PLAINTEXT) {
+ tokeniser->state = STATE_PLAINTEXT;
+ } else if (params->initial_state.state == HUBBUB_INITIAL_STATE_RAWTEXT) {
+ tokeniser->state = STATE_RAWTEXT;
+ }
break;
case HUBBUB_TOKENISER_PROCESS_CDATA:
tokeniser->process_cdata_section = params->process_cdata;
@@ -465,6 +504,26 @@ hubbub_error hubbub_tokeniser_run(hubbub_tokeniser *tokeniser)
cont = hubbub_tokeniser_handle_character_reference_data(
tokeniser);
break;
+ state(STATE_RCDATA)
+ cont = hubbub_tokeniser_handle_rcdata(
+ tokeniser);
+ break;
+ state(STATE_CHARACTER_REFERENCE_RCDATA)
+ cont = hubbub_tokeniser_handle_character_reference_rcdata(
+ tokeniser);
+ break;
+ state(STATE_RAWTEXT)
+ cont = hubbub_tokeniser_handle_rawtext(
+ tokeniser);
+ break;
+ state(STATE_SCRIPT_DATA)
+ cont = hubbub_tokeniser_handle_script_data(
+ tokeniser);
+ break;
+ state(STATE_PLAINTEXT)
+ cont = hubbub_tokeniser_handle_plaintext(
+ tokeniser);
+ break;
state(STATE_TAG_OPEN)
cont = hubbub_tokeniser_handle_tag_open(tokeniser);
break;
@@ -475,6 +534,30 @@ hubbub_error hubbub_tokeniser_run(hubbub_tokeniser *tokeniser)
state(STATE_TAG_NAME)
cont = hubbub_tokeniser_handle_tag_name(tokeniser);
break;
+ state(STATE_RCDATA_LESSTHAN)
+ cont = hubbub_tokeniser_handle_rcdata_lessthan(
+ tokeniser);
+ break;
+ state(STATE_RCDATA_CLOSE_TAG_OPEN)
+ cont = hubbub_tokeniser_handle_rcdata_close_tag_open(
+ tokeniser);
+ break;
+ state(STATE_RCDATA_CLOSE_TAG_NAME)
+ cont = hubbub_tokeniser_handle_rcdata_close_tag_name(
+ tokeniser);
+ break;
+ state(STATE_RAWTEXT_LESSTHAN)
+ cont = hubbub_tokeniser_handle_rawtext_lessthan(
+ tokeniser);
+ break;
+ state(STATE_RAWTEXT_CLOSE_TAG_OPEN)
+ cont = hubbub_tokeniser_handle_rawtext_close_tag_open(
+ tokeniser);
+ break;
+ state(STATE_RAWTEXT_CLOSE_TAG_NAME)
+ cont = hubbub_tokeniser_handle_rawtext_close_tag_name(
+ tokeniser);
+ break;
state(STATE_BEFORE_ATTRIBUTE_NAME)
cont = hubbub_tokeniser_handle_before_attribute_name(
tokeniser);
@@ -703,103 +786,899 @@ hubbub_error hubbub_tokeniser_handle_data(hubbub_tokeniser *tokeniser)
break;
}
- if (tokeniser->context.pending > 0) {
- /* Emit any pending characters */
- emit_current_chars(tokeniser);
- }
+ if (tokeniser->context.pending > 0) {
+ /* Emit any pending characters */
+ emit_current_chars(tokeniser);
+ }
+
+ if (error == PARSERUTILS_EOF || *cptr != '\n') {
+ /* Emit newline */
+ emit_character_token(tokeniser, &lf_str);
+ }
+
+ /* Advance over */
+ parserutils_inputstream_advance(tokeniser->input, 1);
+ } else {
+ if (c == '\0') {
+ /** \todo parse error */
+ }
+
+ /* Just collect into buffer */
+ tokeniser->context.pending += len;
+ }
+ }
+ if (tokeniser->state != STATE_TAG_OPEN &&
+ (tokeniser->state != STATE_DATA || error == PARSERUTILS_EOF) &&
+ tokeniser->context.pending > 0) {
+ /* Emit any pending characters */
+ emit_current_chars(tokeniser);
+ }
+
+ if (error == PARSERUTILS_EOF) {
+ token.type = HUBBUB_TOKEN_EOF;
+ hubbub_tokeniser_emit_token(tokeniser, &token);
+ }
+
+ if (error == PARSERUTILS_EOF) {
+ return HUBBUB_NEEDDATA;
+ } else {
+ return hubbub_error_from_parserutils_error(error);
+ }
+}
+
+
+
+/* emit any pending tokens before calling */
+hubbub_error hubbub_tokeniser_handle_character_reference_data(
+ hubbub_tokeniser *tokeniser)
+{
+ assert(tokeniser->context.pending == 0);
+
+ if (tokeniser->context.match_entity.complete == false) {
+ return hubbub_tokeniser_consume_character_reference(tokeniser,
+ tokeniser->context.pending);
+ } else {
+ hubbub_token token;
+
+ uint8_t utf8[6];
+ uint8_t *utf8ptr = utf8;
+ size_t len = sizeof(utf8);
+
+ token.type = HUBBUB_TOKEN_CHARACTER;
+
+ if (tokeniser->context.match_entity.codepoint) {
+ parserutils_charset_utf8_from_ucs4(
+ tokeniser->context.match_entity.codepoint,
+ &utf8ptr, &len);
+
+ token.data.character.ptr = utf8;
+ token.data.character.len = sizeof(utf8) - len;
+
+ hubbub_tokeniser_emit_token(tokeniser, &token);
+
+ /* +1 for ampersand */
+ parserutils_inputstream_advance(tokeniser->input,
+ tokeniser->context.match_entity.length
+ + 1);
+ } else {
+ parserutils_error error;
+ const uint8_t *cptr = NULL;
+
+ error = parserutils_inputstream_peek(
+ tokeniser->input,
+ tokeniser->context.pending,
+ &cptr,
+ &len);
+ if (error != PARSERUTILS_OK) {
+ return hubbub_error_from_parserutils_error(
+ error);
+ }
+
+ token.data.character.ptr = cptr;
+ token.data.character.len = len;
+
+ hubbub_tokeniser_emit_token(tokeniser, &token);
+ parserutils_inputstream_advance(tokeniser->input, len);
+ }
+
+ /* Reset for next time */
+ tokeniser->context.match_entity.complete = false;
+
+ tokeniser->state = STATE_DATA;
+ }
+
+ return HUBBUB_OK;
+}
+
+hubbub_error hubbub_tokeniser_handle_rcdata(hubbub_tokeniser *tokeniser)
+{
+ parserutils_error error;
+ hubbub_token token;
+ const uint8_t *cptr;
+ size_t len;
+
+ while ((error = parserutils_inputstream_peek(tokeniser->input,
+ tokeniser->context.pending, &cptr, &len)) ==
+ PARSERUTILS_OK) {
+ const uint8_t c = *cptr;
+
+ if (c == '&') {
+ tokeniser->state = STATE_CHARACTER_REFERENCE_RCDATA;
+ /* Don't eat the '&'; it'll be handled by entity
+ * consumption */
+ break;
+ } else if (c == '<') {
+ if (tokeniser->context.pending > 0) {
+ /* Emit any pending characters */
+ emit_current_chars(tokeniser);
+ }
+
+ /* Buffer '<' */
+ tokeniser->context.pending = len;
+ tokeniser->state = STATE_RCDATA_LESSTHAN;
+ break;
+ } else if (c == '\r') {
+ error = parserutils_inputstream_peek(
+ tokeniser->input,
+ tokeniser->context.pending + len,
+ &cptr,
+ &len);
+
+ if (error != PARSERUTILS_OK &&
+ error != PARSERUTILS_EOF) {
+ break;
+ }
+
+ if (tokeniser->context.pending > 0) {
+ /* Emit any pending characters */
+ emit_current_chars(tokeniser);
+ }
+
+ if (error == PARSERUTILS_EOF || *cptr != '\n') {
+ /* Emit newline */
+ emit_character_token(tokeniser, &lf_str);
+ }
+
+ /* Advance over */
+ parserutils_inputstream_advance(tokeniser->input, 1);
+ } else {
+ if (c == '\0') {
+ /** \todo parse error */
+ error = parserutils_buffer_append(tokeniser->buffer,
+ u_fffd, sizeof(u_fffd));
+ if (error != PARSERUTILS_OK)
+ return hubbub_error_from_parserutils_error(error);
+ }
+
+ /* Just collect into buffer */
+ tokeniser->context.pending += len;
+ }
+ }
+ if (tokeniser->state != STATE_RCDATA_LESSTHAN &&
+ (tokeniser->state != STATE_RCDATA || error == PARSERUTILS_EOF) &&
+ tokeniser->context.pending > 0) {
+ /* Emit any pending characters */
+ emit_current_chars(tokeniser);
+ }
+
+ if (error == PARSERUTILS_EOF) {
+ token.type = HUBBUB_TOKEN_EOF;
+ hubbub_tokeniser_emit_token(tokeniser, &token);
+ }
+
+ if (error == PARSERUTILS_EOF) {
+ return HUBBUB_NEEDDATA;
+ } else {
+ return hubbub_error_from_parserutils_error(error);
+ }
+}
+
+
+
+/* emit any pending tokens before calling */
+hubbub_error hubbub_tokeniser_handle_character_reference_rcdata(
+ hubbub_tokeniser *tokeniser)
+{
+ assert(tokeniser->context.pending == 0);
+
+ if (tokeniser->context.match_entity.complete == false) {
+ return hubbub_tokeniser_consume_character_reference(tokeniser,
+ tokeniser->context.pending);
+ } else {
+ hubbub_token token;
+
+ uint8_t utf8[6];
+ uint8_t *utf8ptr = utf8;
+ size_t len = sizeof(utf8);
+
+ token.type = HUBBUB_TOKEN_CHARACTER;
+
+ if (tokeniser->context.match_entity.codepoint) {
+ parserutils_charset_utf8_from_ucs4(
+ tokeniser->context.match_entity.codepoint,
+ &utf8ptr, &len);
+
+ token.data.character.ptr = utf8;
+ token.data.character.len = sizeof(utf8) - len;
+
+ hubbub_tokeniser_emit_token(tokeniser, &token);
+
+ /* +1 for ampersand */
+ parserutils_inputstream_advance(tokeniser->input,
+ tokeniser->context.match_entity.length
+ + 1);
+ } else {
+ parserutils_error error;
+ const uint8_t *cptr = NULL;
+
+ error = parserutils_inputstream_peek(
+ tokeniser->input,
+ tokeniser->context.pending,
+ &cptr,
+ &len);
+ if (error != PARSERUTILS_OK) {
+ return hubbub_error_from_parserutils_error(
+ error);
+ }
+
+ token.data.character.ptr = cptr;
+ token.data.character.len = len;
+
+ hubbub_tokeniser_emit_token(tokeniser, &token);
+ parserutils_inputstream_advance(tokeniser->input, len);
+ }
+
+ /* Reset for next time */
+ tokeniser->context.match_entity.complete = false;
+
+ tokeniser->state = STATE_RCDATA;
+ }
+
+ return HUBBUB_OK;
+}
+
+hubbub_error hubbub_tokeniser_handle_rawtext(hubbub_tokeniser *tokeniser)
+{
+ parserutils_error error;
+ hubbub_token token;
+ const uint8_t *cptr;
+ size_t len;
+
+ while ((error = parserutils_inputstream_peek(tokeniser->input,
+ tokeniser->context.pending, &cptr, &len)) ==
+ PARSERUTILS_OK) {
+ const uint8_t c = *cptr;
+
+ if (c == '<') {
+ if (tokeniser->context.pending > 0) {
+ /* Emit any pending characters */
+ emit_current_chars(tokeniser);
+ }
+
+ /* Buffer '<' */
+ tokeniser->context.pending = len;
+ tokeniser->state = STATE_RAWTEXT_LESSTHAN;
+ break;
+ } else if (c == '\r') {
+ error = parserutils_inputstream_peek(
+ tokeniser->input,
+ tokeniser->context.pending + len,
+ &cptr,
+ &len);
+
+ if (error != PARSERUTILS_OK &&
+ error != PARSERUTILS_EOF) {
+ break;
+ }
+
+ if (tokeniser->context.pending > 0) {
+ /* Emit any pending characters */
+ emit_current_chars(tokeniser);
+ }
+
+ if (error == PARSERUTILS_EOF || *cptr != '\n') {
+ /* Emit newline */
+ emit_character_token(tokeniser, &lf_str);
+ }
+
+ /* Advance over */
+ parserutils_inputstream_advance(tokeniser->input, 1);
+ } else {
+ if (c == '\0') {
+ /** \todo parse error */
+ error = parserutils_buffer_append(tokeniser->buffer,
+ u_fffd, sizeof(u_fffd));
+ if (error != PARSERUTILS_OK)
+ return hubbub_error_from_parserutils_error(error);
+ }
+
+ /* Just collect into buffer */
+ tokeniser->context.pending += len;
+ }
+ }
+ if (tokeniser->state != STATE_RAWTEXT_LESSTHAN &&
+ (tokeniser->state != STATE_RAWTEXT || error == PARSERUTILS_EOF) &&
+ tokeniser->context.pending > 0) {
+ /* Emit any pending characters */
+ emit_current_chars(tokeniser);
+ }
+
+ if (error == PARSERUTILS_EOF) {
+ token.type = HUBBUB_TOKEN_EOF;
+ hubbub_tokeniser_emit_token(tokeniser, &token);
+ }
+
+ if (error == PARSERUTILS_EOF) {
+ return HUBBUB_NEEDDATA;
+ } else {
+ return hubbub_error_from_parserutils_error(error);
+ }
+}
+
+hubbub_error hubbub_tokeniser_handle_script_data(hubbub_tokeniser *tokeniser)
+{
+ parserutils_error error;
+ hubbub_token token;
+ const uint8_t *cptr;
+ size_t len;
+
+ while ((error = parserutils_inputstream_peek(tokeniser->input,
+ tokeniser->context.pending, &cptr, &len)) ==
+ PARSERUTILS_OK) {
+ const uint8_t c = *cptr;
+
+ if (c == '<') {
+ if (tokeniser->context.pending > 0) {
+ /* Emit any pending characters */
+ emit_current_chars(tokeniser);
+ }
+
+ /* Buffer '<' */
+ tokeniser->context.pending = len;
+ ////////tokeniser->state = STATE_SCRIPT_DATA_LESSTHAN;
+ break;
+ } else if (c == '\r') {
+ error = parserutils_inputstream_peek(
+ tokeniser->input,
+ tokeniser->context.pending + len,
+ &cptr,
+ &len);
+
+ if (error != PARSERUTILS_OK &&
+ error != PARSERUTILS_EOF) {
+ break;
+ }
+
+ if (tokeniser->context.pending > 0) {
+ /* Emit any pending characters */
+ emit_current_chars(tokeniser);
+ }
+
+ if (error == PARSERUTILS_EOF || *cptr != '\n') {
+ /* Emit newline */
+ emit_character_token(tokeniser, &lf_str);
+ }
+
+ /* Advance over */
+ parserutils_inputstream_advance(tokeniser->input, 1);
+ } else {
+ if (c == '\0') {
+ /** \todo parse error */
+ error = parserutils_buffer_append(tokeniser->buffer,
+ u_fffd, sizeof(u_fffd));
+ if (error != PARSERUTILS_OK)
+ return hubbub_error_from_parserutils_error(error);
+ }
+
+ /* Just collect into buffer */
+ tokeniser->context.pending += len;
+ }
+ }
+ if (tokeniser->state != STATE_SCRIPT_DATA &&
+ (/*tokeniser->state != STATE_SCRIPT_DATA_LESSTHAN || */error == PARSERUTILS_EOF) &&
+ tokeniser->context.pending > 0) {
+ /* Emit any pending characters */
+ emit_current_chars(tokeniser);
+ }
+
+ if (error == PARSERUTILS_EOF) {
+ token.type = HUBBUB_TOKEN_EOF;
+ hubbub_tokeniser_emit_token(tokeniser, &token);
+ }
+
+ if (error == PARSERUTILS_EOF) {
+ return HUBBUB_NEEDDATA;
+ } else {
+ return hubbub_error_from_parserutils_error(error);
+ }
+}
+
+hubbub_error hubbub_tokeniser_handle_plaintext(hubbub_tokeniser *tokeniser)
+{
+ parserutils_error error;
+ hubbub_token token;
+ const uint8_t *cptr;
+ size_t len;
+
+ while ((error = parserutils_inputstream_peek(tokeniser->input,
+ tokeniser->context.pending, &cptr, &len)) ==
+ PARSERUTILS_OK) {
+ const uint8_t c = *cptr;
+
+ if (c == '\r') {
+ error = parserutils_inputstream_peek(
+ tokeniser->input,
+ tokeniser->context.pending + len,
+ &cptr,
+ &len);
+
+ if (error != PARSERUTILS_OK &&
+ error != PARSERUTILS_EOF) {
+ break;
+ }
+
+ if (tokeniser->context.pending > 0) {
+ /* Emit any pending characters */
+ emit_current_chars(tokeniser);
+ }
+
+ if (error == PARSERUTILS_EOF || *cptr != '\n') {
+ /* Emit newline */
+ emit_character_token(tokeniser, &lf_str);
+ }
+
+ /* Advance over */
+ parserutils_inputstream_advance(tokeniser->input, 1);
+ } else {
+ if (c == '\0') {
+ /** \todo parse error */
+ error = parserutils_buffer_append(tokeniser->buffer,
+ u_fffd, sizeof(u_fffd));
+ if (error != PARSERUTILS_OK)
+ return hubbub_error_from_parserutils_error(error);
+ }
+
+ /* Just collect into buffer */
+ tokeniser->context.pending += len;
+ }
+ }
+ if (tokeniser->context.pending > 0) {
+ /* Emit any pending characters */
+ emit_current_chars(tokeniser);
+ }
+
+ if (error == PARSERUTILS_EOF) {
+ token.type = HUBBUB_TOKEN_EOF;
+ hubbub_tokeniser_emit_token(tokeniser, &token);
+ }
+
+ if (error == PARSERUTILS_EOF) {
+ return HUBBUB_NEEDDATA;
+ } else {
+ return hubbub_error_from_parserutils_error(error);
+ }
+}
+
+/* this state always switches to another state straight away */
+/* this state expects the current character to be '<' */
+hubbub_error hubbub_tokeniser_handle_tag_open(hubbub_tokeniser *tokeniser)
+{
+ hubbub_tag *ctag = &tokeniser->context.current_tag;
+
+ size_t len;
+ const uint8_t *cptr;
+ parserutils_error error;
+ uint8_t c;
+
+ assert(tokeniser->context.pending == 1);
+/* assert(tokeniser->context.chars.ptr[0] == '<'); */
+
+ error = parserutils_inputstream_peek(tokeniser->input,
+ tokeniser->context.pending, &cptr, &len);
+
+ if (error != PARSERUTILS_OK) {
+ if (error == PARSERUTILS_EOF) {
+ /** \todo parse error */
+ /* Emit single '<' char */
+ emit_current_chars(tokeniser);
+ tokeniser->state = STATE_DATA;
+ return HUBBUB_OK;
+ } else {
+ return hubbub_error_from_parserutils_error(error);
+ }
+ }
+
+ c = *cptr;
+
+ if (c == '!') {
+ parserutils_inputstream_advance(tokeniser->input, SLEN("<!"));
+
+ tokeniser->context.pending = 0;
+ tokeniser->state = STATE_MARKUP_DECLARATION_OPEN;
+ } else if (c == '/'){
+ tokeniser->context.pending += len;
+
+ tokeniser->context.close_tag_match.match = false;
+ tokeniser->context.close_tag_match.count = 0;
+
+ tokeniser->state = STATE_CLOSE_TAG_OPEN;
+ } else if ('A' <= c && c <= 'Z') {
+ uint8_t lc = (c + 0x20);
+
+ START_BUF(ctag->name, &lc, len);
+ ctag->n_attributes = 0;
+ tokeniser->context.current_tag_type =
+ HUBBUB_TOKEN_START_TAG;
+
+ tokeniser->context.pending += len;
+
+ tokeniser->state = STATE_TAG_NAME;
+ } else if ('a' <= c && c <= 'z') {
+ START_BUF(ctag->name, cptr, len);
+ ctag->n_attributes = 0;
+ tokeniser->context.current_tag_type =
+ HUBBUB_TOKEN_START_TAG;
+
+ tokeniser->context.pending += len;
+
+ tokeniser->state = STATE_TAG_NAME;
+ } else if (c == '?'){
+ /** \todo parse error */
+ /* Cursor still at "<", need to advance past it */
+ parserutils_inputstream_advance(
+ tokeniser->input, SLEN("<"));
+ tokeniser->context.pending = 0;
+
+ tokeniser->state = STATE_BOGUS_COMMENT;
+ } else {
+ /** \todo parse error */
+ /* Emit single '<' char */
+ emit_current_chars(tokeniser);
+ tokeniser->state = STATE_DATA;
+ }
+
+
+ return HUBBUB_OK;
+}
+
+/* this state expects tokeniser->context.chars to be "</" */
+/* this state never stays in this state for more than one character */
+hubbub_error hubbub_tokeniser_handle_close_tag_open(hubbub_tokeniser *tokeniser)
+{
+ size_t len;
+ const uint8_t *cptr;
+ parserutils_error error;
+ uint8_t c;
+
+ assert(tokeniser->context.pending == 2);
+/* assert(tokeniser->context.chars.ptr[0] == '<'); */
+/* assert(tokeniser->context.chars.ptr[1] == '/'); */
+
+ error = parserutils_inputstream_peek(tokeniser->input,
+ tokeniser->context.pending, &cptr, &len);
+
+ if (error != PARSERUTILS_OK) {
+ if (error == PARSERUTILS_EOF) {
+ /** \todo parse error */
+ /* Emit '</' chars */
+ emit_current_chars(tokeniser);
+ tokeniser->state = STATE_DATA;
+ return HUBBUB_OK;
+ } else {
+ return hubbub_error_from_parserutils_error(error);
+ }
+ }
+
+ c = *cptr;
+
+ if ('A' <= c && c <= 'Z') {
+ uint8_t lc = (c + 0x20);
+ START_BUF(tokeniser->context.current_tag.name,
+ &lc, len);
+ tokeniser->context.current_tag.n_attributes = 0;
+
+ tokeniser->context.current_tag_type = HUBBUB_TOKEN_END_TAG;
+
+ tokeniser->context.pending += len;
+
+ tokeniser->state = STATE_TAG_NAME;
+ } else if ('a' <= c && c <= 'z') {
+ START_BUF(tokeniser->context.current_tag.name,
+ cptr, len);
+ tokeniser->context.current_tag.n_attributes = 0;
+
+ tokeniser->context.current_tag_type = HUBBUB_TOKEN_END_TAG;
+
+ tokeniser->context.pending += len;
+
+ tokeniser->state = STATE_TAG_NAME;
+ } else if (c == '>') {
+ /** \todo parse error */
+
+ /* Cursor still at "</", need to collect ">" */
+ tokeniser->context.pending += len;
+
+ /* Now need to advance past "</>" */
+ parserutils_inputstream_advance(tokeniser->input,
+ tokeniser->context.pending);
+ tokeniser->context.pending = 0;
+
+ tokeniser->state = STATE_DATA;
+ } else {
+ /** \todo parse error */
+
+ /* Cursor still at "</", need to advance past it */
+ parserutils_inputstream_advance(tokeniser->input,
+ tokeniser->context.pending);
+ tokeniser->context.pending = 0;
+
+ tokeniser->state = STATE_BOGUS_COMMENT;
+ }
+
+ return HUBBUB_OK;
+}
+
+/* this state expects tokeniser->context.current_tag to already have its
+ first character set */
+hubbub_error hubbub_tokeniser_handle_tag_name(hubbub_tokeniser *tokeniser)
+{
+ hubbub_tag *ctag = &tokeniser->context.current_tag;
+
+ size_t len;
+ const uint8_t *cptr;
+ parserutils_error error;
+ uint8_t c;
+
+ assert(tokeniser->context.pending > 0);
+/* assert(tokeniser->context.chars.ptr[0] == '<'); */
+ assert(ctag->name.len > 0);
+/* assert(ctag->name.ptr); */
+
+ error = parserutils_inputstream_peek(tokeniser->input,
+ tokeniser->context.pending, &cptr, &len);
+
+ if (error != PARSERUTILS_OK) {
+ if (error == PARSERUTILS_EOF) {
+ /** \todo parse error */
+ tokeniser->state = STATE_DATA;
+
+ // skips all pending charachters
+ parserutils_inputstream_advance(
+ tokeniser->input, tokeniser->context.pending);
+ return HUBBUB_OK;
+ } else {
+ return hubbub_error_from_parserutils_error(error);
+ }
+ }
+
+ c = *cptr;
+
+ if (c == '\t' || c == '\n' || c == '\f' || c == ' ' || c == '\r') {
+ tokeniser->context.pending += len;
+ tokeniser->state = STATE_BEFORE_ATTRIBUTE_NAME;
+ } else if (c == '/') {
+ tokeniser->context.pending += len;
+ tokeniser->state = STATE_SELF_CLOSING_START_TAG;
+ } else if (c == '>') {
+ tokeniser->context.pending += len;
+ tokeniser->state = STATE_DATA;
+ return emit_current_tag(tokeniser);
+ } else if ('A' <= c && c <= 'Z') {
+ uint8_t lc = (c + 0x20);
+ COLLECT(ctag->name, &lc, len);
+ tokeniser->context.pending += len;
+ } else if (c == '\0') {
+ COLLECT(ctag->name, u_fffd, sizeof(u_fffd));
+ tokeniser->context.pending += len;
+ } else {
+ COLLECT(ctag->name, cptr, len);
+ tokeniser->context.pending += len;
+ }
+
+ return HUBBUB_OK;
+}
+
+/* this state always switches to another state straight away */
+/* this state expects the current character to be '<' */
+hubbub_error hubbub_tokeniser_handle_rcdata_lessthan(hubbub_tokeniser *tokeniser)
+{
+ //hubbub_tag *ctag = &tokeniser->context.current_tag;
+
+ size_t len;
+ const uint8_t *cptr;
+ parserutils_error error;
+ uint8_t c;
+
+ assert(tokeniser->context.pending == 1);
+/* assert(tokeniser->context.chars.ptr[0] == '<'); */
+
+ error = parserutils_inputstream_peek(tokeniser->input,
+ tokeniser->context.pending, &cptr, &len);
+
+ if (error != PARSERUTILS_OK) {
+ if (error == PARSERUTILS_EOF) {
+ /** \todo parse error */
+ /* Emit single '<' char */
+ emit_current_chars(tokeniser);
+ tokeniser->state = STATE_RCDATA;
+ return HUBBUB_OK;
+ } else {
+ return hubbub_error_from_parserutils_error(error);
+ }
+ }
+
+ c = *cptr;
+
+ if (c == '/'){
+ tokeniser->context.pending += len;
+
+ tokeniser->context.close_tag_match.match = false;
+ tokeniser->context.close_tag_match.count = 0;
+
+ tokeniser->state = STATE_RCDATA_CLOSE_TAG_OPEN;
+ } else {
+ /* Emit single '<' char */
+ emit_current_chars(tokeniser);
+ tokeniser->state = STATE_RCDATA;
+ }
+
+
+ return HUBBUB_OK;
+}
+
+/* this state expects tokeniser->context.chars to be "</" */
+/* this state never stays in this state for more than one character */
+hubbub_error hubbub_tokeniser_handle_rcdata_close_tag_open(hubbub_tokeniser *tokeniser)
+{
+ hubbub_tokeniser_context *ctx = &tokeniser->context;
+
+ size_t len;
+ const uint8_t *cptr;
+ parserutils_error error;
+ uint8_t c;
+
+ assert(tokeniser->context.pending == 2);
+/* assert(tokeniser->context.chars.ptr[0] == '<'); */
+/* assert(tokeniser->context.chars.ptr[1] == '/'); */
+
+ uint8_t *start_tag_name =
+ tokeniser->context.last_start_tag_name;
+ size_t start_tag_len =
+ tokeniser->context.last_start_tag_len;
- if (error == PARSERUTILS_EOF || *cptr != '\n') {
- /* Emit newline */
- emit_character_token(tokeniser, &lf_str);
- }
+ while ((error = parserutils_inputstream_peek(tokeniser->input,
+ ctx->pending +
+ ctx->close_tag_match.count,
+ &cptr,
+ &len)) == PARSERUTILS_OK) {
+ c = *cptr;
- /* Advance over */
- parserutils_inputstream_advance(tokeniser->input, 1);
- } else {
- if (c == '\0') {
- /** \todo parse error */
- }
+ if ((start_tag_name[ctx->close_tag_match.count] & ~0x20)
+ != (c & ~0x20)) {
+ break;
+ }
- /* Just collect into buffer */
- tokeniser->context.pending += len;
+ ctx->close_tag_match.count += len;
+
+ if (ctx->close_tag_match.count == start_tag_len) {
+
+ // Sets the flag to be used in name state.
+ ctx->close_tag_match.match = true;
+ break;
}
}
- if (tokeniser->state != STATE_TAG_OPEN &&
- (tokeniser->state != STATE_DATA || error == PARSERUTILS_EOF) &&
- tokeniser->context.pending > 0) {
- /* Emit any pending characters */
- emit_current_chars(tokeniser);
- }
- if (error == PARSERUTILS_EOF) {
- token.type = HUBBUB_TOKEN_EOF;
- hubbub_tokeniser_emit_token(tokeniser, &token);
+ if (error != PARSERUTILS_OK) {
+ if (error == PARSERUTILS_EOF) {
+ tokeniser->state = STATE_RCDATA;
+ tokeniser->context.pending += ctx->close_tag_match.count;
+ return HUBBUB_OK;
+ } else {
+ return hubbub_error_from_parserutils_error(error);
+ }
}
- if (error == PARSERUTILS_EOF) {
- return HUBBUB_NEEDDATA;
- } else {
- return hubbub_error_from_parserutils_error(error);
+ if (ctx->close_tag_match.match == true) {
+ error = parserutils_inputstream_peek(
+ tokeniser->input,
+ ctx->pending +
+ ctx->close_tag_match.count,
+ &cptr,
+ &len);
+
+ if (error != PARSERUTILS_OK &&
+ error != PARSERUTILS_EOF) {
+ return hubbub_error_from_parserutils_error(
+ error);
+ } else if (error != PARSERUTILS_EOF) {
+ c = *cptr;
+
+ if (c != '\t' && c != '\n' && c != '\f' && c != '\r' &&
+ c != ' ' && c != '>' &&
+ c != '/') {
+ ctx->close_tag_match.match = false;
+ }
+ }
}
-}
-/* emit any pending tokens before calling */
-hubbub_error hubbub_tokeniser_handle_character_reference_data(
- hubbub_tokeniser *tokeniser)
-{
- assert(tokeniser->context.pending == 0);
+ if (ctx->close_tag_match.match == true) {
- if (tokeniser->context.match_entity.complete == false) {
- return hubbub_tokeniser_consume_character_reference(tokeniser,
- tokeniser->context.pending);
- } else {
- hubbub_token token;
+ tokeniser->state = STATE_RCDATA_CLOSE_TAG_NAME;
- uint8_t utf8[6];
- uint8_t *utf8ptr = utf8;
- size_t len = sizeof(utf8);
+ // Creates a new buffer and sets first charachter of the tag name
+ START_BUF(ctx->current_tag.name,
+ &start_tag_name[0], len);
+ tokeniser->context.current_tag.n_attributes = 0;
- token.type = HUBBUB_TOKEN_CHARACTER;
+ tokeniser->context.current_tag_type =
+ HUBBUB_TOKEN_END_TAG;
- if (tokeniser->context.match_entity.codepoint) {
- parserutils_charset_utf8_from_ucs4(
- tokeniser->context.match_entity.codepoint,
- &utf8ptr, &len);
+ tokeniser->context.pending += len;
- token.data.character.ptr = utf8;
- token.data.character.len = sizeof(utf8) - len;
+ tokeniser->state = STATE_RCDATA_CLOSE_TAG_NAME;
+ } else {
+ emit_current_chars(tokeniser);
+ tokeniser->state = STATE_RCDATA;
+ }
- hubbub_tokeniser_emit_token(tokeniser, &token);
+ return HUBBUB_OK;
+}
- /* +1 for ampersand */
- parserutils_inputstream_advance(tokeniser->input,
- tokeniser->context.match_entity.length
- + 1);
- } else {
- parserutils_error error;
- const uint8_t *cptr = NULL;
+/* this state expects tokeniser->context.current_tag to already have its
+ first character set */
+hubbub_error hubbub_tokeniser_handle_rcdata_close_tag_name(hubbub_tokeniser *tokeniser)
+{
+ hubbub_tokeniser_context *ctx = &tokeniser->context;
- error = parserutils_inputstream_peek(
- tokeniser->input,
- tokeniser->context.pending,
- &cptr,
- &len);
- if (error != PARSERUTILS_OK) {
- return hubbub_error_from_parserutils_error(
- error);
- }
+ size_t len;
+ const uint8_t *cptr;
+ parserutils_error error;
+ uint8_t c;
- token.data.character.ptr = cptr;
- token.data.character.len = len;
+ assert(tokeniser->context.pending > 0);
+/* assert(tokeniser->context.chars.ptr[0] == '<'); */
+ assert(ctx.current_tag->name.len > 0);
+/* assert(ctx.current_tag->name.ptr); */
- hubbub_tokeniser_emit_token(tokeniser, &token);
- parserutils_inputstream_advance(tokeniser->input, len);
+ error = parserutils_inputstream_peek(tokeniser->input,
+ tokeniser->context.pending, &cptr, &len);
+
+ if (error != PARSERUTILS_OK) {
+ if (error == PARSERUTILS_EOF) {
+ /** \todo parse error */
+ tokeniser->state = STATE_RCDATA;
+ return HUBBUB_OK;
+ } else {
+ return hubbub_error_from_parserutils_error(error);
}
+ }
- /* Reset for next time */
- tokeniser->context.match_entity.complete = false;
+ c = *cptr;
+ if ((c == '\t' || c == '\n' || c == '\f' || c == ' ' || c == '\r')
+ && ctx->close_tag_match.match == true) {
+ // Add condition for approproiate end tag token
+ tokeniser->context.pending += len;
+ tokeniser->state = STATE_BEFORE_ATTRIBUTE_NAME;
+ } else if (c == '/' && ctx->close_tag_match.match == true) {
+ // Add condition for approproiate end tag token
+ tokeniser->context.pending += len;
+ tokeniser->state = STATE_SELF_CLOSING_START_TAG;
+ } else if (c == '>' && ctx->close_tag_match.match == true) {
+ // Add condition for approproiate end tag token
+ tokeniser->context.pending += len;
tokeniser->state = STATE_DATA;
+ return emit_current_tag(tokeniser);
+ } else if ('A' <= c && c <= 'Z') {
+ uint8_t lc = (c + 0x20);
+ COLLECT(ctx->current_tag.name, &lc, len);
+ tokeniser->context.pending += len;
+ } else if ('a' <= c && c <= 'z') {
+ COLLECT(ctx->current_tag.name, cptr, len);
+ tokeniser->context.pending += len;
+ } else {
+ tokeniser->state = STATE_RCDATA;
+ return emit_current_chars(tokeniser);
}
return HUBBUB_OK;
@@ -807,9 +1686,9 @@ hubbub_error hubbub_tokeniser_handle_character_reference_data(
/* this state always switches to another state straight away */
/* this state expects the current character to be '<' */
-hubbub_error hubbub_tokeniser_handle_tag_open(hubbub_tokeniser *tokeniser)
+hubbub_error hubbub_tokeniser_handle_rawtext_lessthan(hubbub_tokeniser *tokeniser)
{
- hubbub_tag *ctag = &tokeniser->context.current_tag;
+ //hubbub_tag *ctag = &tokeniser->context.current_tag;
size_t len;
const uint8_t *cptr;
@@ -827,7 +1706,7 @@ hubbub_error hubbub_tokeniser_handle_tag_open(hubbub_tokeniser *tokeniser)
/** \todo parse error */
/* Emit single '<' char */
emit_current_chars(tokeniser);
- tokeniser->state = STATE_DATA;
+ tokeniser->state = STATE_RAWTEXT;
return HUBBUB_OK;
} else {
return hubbub_error_from_parserutils_error(error);
@@ -836,51 +1715,17 @@ hubbub_error hubbub_tokeniser_handle_tag_open(hubbub_tokeniser *tokeniser)
c = *cptr;
- if (c == '!') {
- parserutils_inputstream_advance(tokeniser->input, SLEN("<!"));
-
- tokeniser->context.pending = 0;
- tokeniser->state = STATE_MARKUP_DECLARATION_OPEN;
- } else if (c == '/'){
+ if (c == '/'){
tokeniser->context.pending += len;
tokeniser->context.close_tag_match.match = false;
tokeniser->context.close_tag_match.count = 0;
- tokeniser->state = STATE_CLOSE_TAG_OPEN;
- } else if ('A' <= c && c <= 'Z') {
- uint8_t lc = (c + 0x20);
-
- START_BUF(ctag->name, &lc, len);
- ctag->n_attributes = 0;
- tokeniser->context.current_tag_type =
- HUBBUB_TOKEN_START_TAG;
-
- tokeniser->context.pending += len;
-
- tokeniser->state = STATE_TAG_NAME;
- } else if ('a' <= c && c <= 'z') {
- START_BUF(ctag->name, cptr, len);
- ctag->n_attributes = 0;
- tokeniser->context.current_tag_type =
- HUBBUB_TOKEN_START_TAG;
-
- tokeniser->context.pending += len;
-
- tokeniser->state = STATE_TAG_NAME;
- } else if (c == '?'){
- /** \todo parse error */
- /* Cursor still at "<", need to advance past it */
- parserutils_inputstream_advance(
- tokeniser->input, SLEN("<"));
- tokeniser->context.pending = 0;
-
- tokeniser->state = STATE_BOGUS_COMMENT;
+ tokeniser->state = STATE_RAWTEXT_CLOSE_TAG_OPEN;
} else {
- /** \todo parse error */
/* Emit single '<' char */
emit_current_chars(tokeniser);
- tokeniser->state = STATE_DATA;
+ tokeniser->state = STATE_RCDATA;
}
@@ -889,8 +1734,10 @@ hubbub_error hubbub_tokeniser_handle_tag_open(hubbub_tokeniser *tokeniser)
/* this state expects tokeniser->context.chars to be "</" */
/* this state never stays in this state for more than one character */
-hubbub_error hubbub_tokeniser_handle_close_tag_open(hubbub_tokeniser *tokeniser)
+hubbub_error hubbub_tokeniser_handle_rawtext_close_tag_open(hubbub_tokeniser *tokeniser)
{
+ hubbub_tokeniser_context *ctx = &tokeniser->context;
+
size_t len;
const uint8_t *cptr;
parserutils_error error;
@@ -900,65 +1747,84 @@ hubbub_error hubbub_tokeniser_handle_close_tag_open(hubbub_tokeniser *tokeniser)
/* assert(tokeniser->context.chars.ptr[0] == '<'); */
/* assert(tokeniser->context.chars.ptr[1] == '/'); */
- error = parserutils_inputstream_peek(tokeniser->input,
- tokeniser->context.pending, &cptr, &len);
+ uint8_t *start_tag_name =
+ tokeniser->context.last_start_tag_name;
+ size_t start_tag_len =
+ tokeniser->context.last_start_tag_len;
+
+ while ((error = parserutils_inputstream_peek(tokeniser->input,
+ ctx->pending +
+ ctx->close_tag_match.count,
+ &cptr,
+ &len)) == PARSERUTILS_OK) {
+ c = *cptr;
+
+ if ((start_tag_name[ctx->close_tag_match.count] & ~0x20)
+ != (c & ~0x20)) {
+ break;
+ }
+
+ ctx->close_tag_match.count += len;
+
+ if (ctx->close_tag_match.count == start_tag_len) {
+
+ // Sets the flag to be used in name state.
+ ctx->close_tag_match.match = true;
+ break;
+ }
+ }
if (error != PARSERUTILS_OK) {
if (error == PARSERUTILS_EOF) {
- /** \todo parse error */
- /* Emit '</' chars */
- emit_current_chars(tokeniser);
- tokeniser->state = STATE_DATA;
+ tokeniser->state = STATE_RAWTEXT;
+ tokeniser->context.pending += ctx->close_tag_match.count;
return HUBBUB_OK;
} else {
return hubbub_error_from_parserutils_error(error);
}
}
- c = *cptr;
+ if (ctx->close_tag_match.match == true) {
+ error = parserutils_inputstream_peek(
+ tokeniser->input,
+ ctx->pending +
+ ctx->close_tag_match.count,
+ &cptr,
+ &len);
+
+ if (error != PARSERUTILS_OK &&
+ error != PARSERUTILS_EOF) {
+ return hubbub_error_from_parserutils_error(
+ error);
+ } else if (error != PARSERUTILS_EOF) {
+ c = *cptr;
- if ('A' <= c && c <= 'Z') {
- uint8_t lc = (c + 0x20);
- START_BUF(tokeniser->context.current_tag.name,
- &lc, len);
- tokeniser->context.current_tag.n_attributes = 0;
+ if (c != '\t' && c != '\n' && c != '\f' && c != '\r' &&
+ c != ' ' && c != '>' &&
+ c != '/') {
+ ctx->close_tag_match.match = false;
+ }
+ }
+ }
- tokeniser->context.current_tag_type = HUBBUB_TOKEN_END_TAG;
+ if (ctx->close_tag_match.match == true) {
- tokeniser->context.pending += len;
+ tokeniser->state = STATE_RCDATA_CLOSE_TAG_NAME;
- tokeniser->state = STATE_TAG_NAME;
- } else if ('a' <= c && c <= 'z') {
- START_BUF(tokeniser->context.current_tag.name,
- cptr, len);
+ // Creates a new buffer and sets first charachter of the tag name
+ START_BUF(ctx->current_tag.name,
+ &start_tag_name[0], len);
tokeniser->context.current_tag.n_attributes = 0;
- tokeniser->context.current_tag_type = HUBBUB_TOKEN_END_TAG;
-
- tokeniser->context.pending += len;
-
- tokeniser->state = STATE_TAG_NAME;
- } else if (c == '>') {
- /** \todo parse error */
+ tokeniser->context.current_tag_type =
+ HUBBUB_TOKEN_END_TAG;
- /* Cursor still at "</", need to collect ">" */
tokeniser->context.pending += len;
- /* Now need to advance past "</>" */
- parserutils_inputstream_advance(tokeniser->input,
- tokeniser->context.pending);
- tokeniser->context.pending = 0;
-
- tokeniser->state = STATE_DATA;
+ tokeniser->state = STATE_RAWTEXT_CLOSE_TAG_NAME;
} else {
- /** \todo parse error */
-
- /* Cursor still at "</", need to advance past it */
- parserutils_inputstream_advance(tokeniser->input,
- tokeniser->context.pending);
- tokeniser->context.pending = 0;
-
- tokeniser->state = STATE_BOGUS_COMMENT;
+ emit_current_chars(tokeniser);
+ tokeniser->state = STATE_RAWTEXT;
}
return HUBBUB_OK;
@@ -966,9 +1832,9 @@ hubbub_error hubbub_tokeniser_handle_close_tag_open(hubbub_tokeniser *tokeniser)
/* this state expects tokeniser->context.current_tag to already have its
first character set */
-hubbub_error hubbub_tokeniser_handle_tag_name(hubbub_tokeniser *tokeniser)
+hubbub_error hubbub_tokeniser_handle_rawtext_close_tag_name(hubbub_tokeniser *tokeniser)
{
- hubbub_tag *ctag = &tokeniser->context.current_tag;
+ hubbub_tokeniser_context *ctx = &tokeniser->context;
size_t len;
const uint8_t *cptr;
@@ -985,12 +1851,9 @@ hubbub_error hubbub_tokeniser_handle_tag_name(hubbub_tokeniser *tokeniser)
if (error != PARSERUTILS_OK) {
if (error == PARSERUTILS_EOF) {
- /** \todo parse error */
- tokeniser->state = STATE_DATA;
+ tokeniser->state = STATE_RAWTEXT;
- // skips all pending charachters
- parserutils_inputstream_advance(
- tokeniser->input, tokeniser->context.pending);
+ emit_current_chars(tokeniser);
return HUBBUB_OK;
} else {
return hubbub_error_from_parserutils_error(error);
@@ -999,26 +1862,30 @@ hubbub_error hubbub_tokeniser_handle_tag_name(hubbub_tokeniser *tokeniser)
c = *cptr;
- if (c == '\t' || c == '\n' || c == '\f' || c == ' ' || c == '\r') {
+ if ((c == '\t' || c == '\n' || c == '\f' || c == ' ' || c == '\r')
+ && ctx->close_tag_match.match == true) {
+ // Add condition for approproiate end tag token
tokeniser->context.pending += len;
tokeniser->state = STATE_BEFORE_ATTRIBUTE_NAME;
- } else if (c == '/') {
+ } else if (c == '/' && ctx->close_tag_match.match == true) {
+ // Add condition for approproiate end tag token
tokeniser->context.pending += len;
tokeniser->state = STATE_SELF_CLOSING_START_TAG;
- } else if (c == '>') {
+ } else if (c == '>' && ctx->close_tag_match.match == true) {
+ // Add condition for approproiate end tag token
tokeniser->context.pending += len;
tokeniser->state = STATE_DATA;
return emit_current_tag(tokeniser);
} else if ('A' <= c && c <= 'Z') {
uint8_t lc = (c + 0x20);
- COLLECT(ctag->name, &lc, len);
+ COLLECT(ctx->current_tag.name, &lc, len);
tokeniser->context.pending += len;
- } else if (c == '\0') {
- COLLECT(ctag->name, u_fffd, sizeof(u_fffd));
+ } else if ('a' <= c && c <= 'z') {
+ COLLECT(ctx->current_tag.name, cptr, len);
tokeniser->context.pending += len;
} else {
- COLLECT(ctag->name, cptr, len);
- tokeniser->context.pending += len;
+ tokeniser->state = STATE_RAWTEXT;
+ return emit_current_chars(tokeniser);
}
return HUBBUB_OK;
@@ -3315,7 +4182,7 @@ hubbub_error emit_current_tag(hubbub_tokeniser *tokeniser)
err = hubbub_tokeniser_emit_token(tokeniser, &token);
if (token.type == HUBBUB_TOKEN_START_TAG) {
- /* Save start tag name for R?CDATA */
+ /* Save start tag name for R?CDATA states */
if (token.data.tag.name.len <
sizeof(tokeniser->context.last_start_tag_name)) {
strncpy((char *) tokeniser->context.last_start_tag_name,
@@ -3328,8 +4195,9 @@ hubbub_error emit_current_tag(hubbub_tokeniser *tokeniser)
tokeniser->context.last_start_tag_len = 0;
}
} else /* if (token->type == HUBBUB_TOKEN_END_TAG) */ {
- /* Reset content model after R?CDATA elements */
- tokeniser->content_model = HUBBUB_CONTENT_MODEL_PCDATA;
+ /* Reset content model (i.e state will be now STATE_DATA)
+ after R?CDATA elements */
+ tokeniser->state = STATE_DATA;
}
/* Reset the self-closing flag */
diff --git a/src/tokeniser/tokeniser.h b/src/tokeniser/tokeniser.h
index 5700923..cd8f662 100644
--- a/src/tokeniser/tokeniser.h
+++ b/src/tokeniser/tokeniser.h
@@ -25,7 +25,7 @@ typedef struct hubbub_tokeniser hubbub_tokeniser;
typedef enum hubbub_tokeniser_opttype {
HUBBUB_TOKENISER_TOKEN_HANDLER,
HUBBUB_TOKENISER_ERROR_HANDLER,
- HUBBUB_TOKENISER_CONTENT_MODEL,
+ HUBBUB_TOKENISER_INITIAL_STATE,
HUBBUB_TOKENISER_PROCESS_CDATA,
HUBBUB_TOKENISER_PAUSE
} hubbub_tokeniser_opttype;
@@ -45,8 +45,8 @@ typedef union hubbub_tokeniser_optparams {
} error_handler; /**< Error handling callback */
struct {
- hubbub_content_model model;
- } content_model; /**< Current content model */
+ hubbub_initial_state state;
+ } initial_state; /**< Initial State of the tokeniser */
bool process_cdata; /**< Whether to process CDATA sections*/
diff --git a/src/treebuilder/in_body.c b/src/treebuilder/in_body.c
index 5157e66..d16a365 100644
--- a/src/treebuilder/in_body.c
+++ b/src/treebuilder/in_body.c
@@ -740,10 +740,10 @@ hubbub_error process_plaintext_in_body(hubbub_treebuilder *treebuilder,
if (err != HUBBUB_OK)
return err;
- params.content_model.model = HUBBUB_CONTENT_MODEL_PLAINTEXT;
+ params.initial_state.state = HUBBUB_INITIAL_STATE_PLAINTEXT;
err = hubbub_tokeniser_setopt(treebuilder->tokeniser,
- HUBBUB_TOKENISER_CONTENT_MODEL,
+ HUBBUB_TOKENISER_INITIAL_STATE,
¶ms);
assert(err == HUBBUB_OK);
diff --git a/src/treebuilder/treebuilder.c b/src/treebuilder/treebuilder.c
index a6a4b43..5784a83 100644
--- a/src/treebuilder/treebuilder.c
+++ b/src/treebuilder/treebuilder.c
@@ -473,10 +473,10 @@ hubbub_error parse_generic_rcdata(hubbub_treebuilder *treebuilder,
if (error != HUBBUB_OK)
return error;
- params.content_model.model = rcdata ? HUBBUB_CONTENT_MODEL_RCDATA
- : HUBBUB_CONTENT_MODEL_CDATA;
+ params.initial_state.state = rcdata ? HUBBUB_INITIAL_STATE_RCDATA
+ : HUBBUB_INITIAL_STATE_CDATA;
error = hubbub_tokeniser_setopt(treebuilder->tokeniser,
- HUBBUB_TOKENISER_CONTENT_MODEL, ¶ms);
+ HUBBUB_TOKENISER_INITIAL_STATE, ¶ms);
/* There is no way that setopt can fail. Ensure this. */
assert(error == HUBBUB_OK);
diff --git a/test/data/tokeniser2/contentModelFlags.test b/test/data/tokeniser2/contentModelFlags.test
index 1dec3e8..a8b1695 100644
--- a/test/data/tokeniser2/contentModelFlags.test
+++ b/test/data/tokeniser2/contentModelFlags.test
@@ -1,73 +1,73 @@
{"tests": [
{"description":"PLAINTEXT content model flag",
-"contentModelFlags":["PLAINTEXT"],
+"initialStates":["PLAINTEXT state"],
"lastStartTag":"plaintext",
"input":"<head>&body;",
"output":[["Character", "<head>&body;"]]},
-{"description":"End tag closing RCDATA or CDATA",
-"contentModelFlags":["RCDATA", "CDATA"],
+{"description":"End tag closing RCDATA or RAWTEXT",
+"initialStates":["RCDATA state", "RAWTEXT state"],
"lastStartTag":"xmp",
"input":"foo</xmp>",
"output":[["Character", "foo"], ["EndTag", "xmp"]]},
-{"description":"End tag closing RCDATA or CDATA (case-insensitivity)",
-"contentModelFlags":["RCDATA", "CDATA"],
+{"description":"End tag closing RCDATA or RAWTEXT (case-insensitivity)",
+"initialStates":["RCDATA state", "RAWTEXT state"],
"lastStartTag":"xmp",
"input":"foo</xMp>",
"output":[["Character", "foo"], ["EndTag", "xmp"]]},
-{"description":"End tag closing RCDATA or CDATA (ending with space)",
-"contentModelFlags":["RCDATA", "CDATA"],
+{"description":"End tag closing RCDATA or RAWTEXT (ending with space)",
+"initialStates":["RCDATA state", "RAWTEXT state"],
"lastStartTag":"xmp",
"input":"foo</xmp ",
-"output":[["Character", "foo"], "ParseError", ["EndTag", "xmp"]]},
+"output":[["Character", "foo"], "ParseError"]},
-{"description":"End tag closing RCDATA or CDATA (ending with EOF)",
-"contentModelFlags":["RCDATA", "CDATA"],
+{"description":"End tag closing RCDATA or RAWTEXT (ending with EOF)",
+"initialStates":["RCDATA state", "RAWTEXT state"],
"lastStartTag":"xmp",
"input":"foo</xmp",
-"output":[["Character", "foo"], "ParseError", ["EndTag", "xmp"]]},
+"output":[["Character", "foo</xmp"]]},
-{"description":"End tag closing RCDATA or CDATA (ending with slash)",
-"contentModelFlags":["RCDATA", "CDATA"],
+{"description":"End tag closing RCDATA or RAWTEXT (ending with slash)",
+"initialStates":["RCDATA state", "RAWTEXT state"],
"lastStartTag":"xmp",
"input":"foo</xmp/",
-"output":[["Character", "foo"], "ParseError", ["EndTag", "xmp"]]},
+"output":[["Character", "foo"], "ParseError"]},
-{"description":"End tag not closing RCDATA or CDATA (ending with left-angle-bracket)",
-"contentModelFlags":["RCDATA", "CDATA"],
+{"description":"End tag not closing RCDATA or RAWTEXT (ending with left-angle-bracket)",
+"initialStates":["RCDATA state", "RAWTEXT state"],
"lastStartTag":"xmp",
"input":"foo</xmp<",
"output":[["Character", "foo</xmp<"]]},
-{"description":"End tag with incorrect name in RCDATA or CDATA",
-"contentModelFlags":["RCDATA", "CDATA"],
+{"description":"End tag with incorrect name in RCDATA or RAWTEXT",
+"initialStates":["RCDATA state", "RAWTEXT state"],
"lastStartTag":"xmp",
"input":"</foo>bar</xmp>",
"output":[["Character", "</foo>bar"], ["EndTag", "xmp"]]},
-{"description":"End tag with incorrect name in RCDATA or CDATA (starting like correct name)",
-"contentModelFlags":["RCDATA", "CDATA"],
+{"description":"End tag with incorrect name in RCDATA or RAWTEXT (starting like correct name)",
+"initialStates":["RCDATA state", "RAWTEXT state"],
"lastStartTag":"xmp",
"input":"</foo>bar</xmpaar>",
"output":[["Character", "</foo>bar</xmpaar>"]]},
-{"description":"End tag closing RCDATA or CDATA, switching back to PCDATA",
-"contentModelFlags":["RCDATA", "CDATA"],
+{"description":"End tag closing RCDATA or RAWTEXT, switching back to PCDATA",
+"initialStates":["RCDATA state", "RAWTEXT state"],
"lastStartTag":"xmp",
"input":"foo</xmp></baz>",
"output":[["Character", "foo"], ["EndTag", "xmp"], ["EndTag", "baz"]]},
-{"description":"CDATA w/ something looking like an entity",
-"contentModelFlags":["CDATA"],
+{"description":"RAWTEXT w/ something looking like an entity",
+"initialStates":["RAWTEXT state"],
"lastStartTag":"xmp",
"input":"&foo;",
"output":[["Character", "&foo;"]]},
{"description":"RCDATA w/ an entity",
-"contentModelFlags":["RCDATA"],
+"initialStates":["RCDATA state"],
"lastStartTag":"textarea",
"input":"<",
"output":[["Character", "<"]]}
diff --git a/test/data/tokeniser2/escapeFlag.test b/test/data/tokeniser2/escapeFlag.test
index 4c4bf51..18cb430 100644
--- a/test/data/tokeniser2/escapeFlag.test
+++ b/test/data/tokeniser2/escapeFlag.test
@@ -1,33 +1,33 @@
{"tests": [
-{"description":"Commented close tag in [R]CDATA",
-"contentModelFlags":["RCDATA", "CDATA"],
+{"description":"Commented close tag in RCDATA or RAWTEXT",
+"initialStates":["RCDATA state", "RAWTEXT state"],
"lastStartTag":"xmp",
"input":"foo<!--</xmp>--></xmp>",
-"output":[["Character", "foo<!--</xmp>-->"], ["EndTag", "xmp"]]},
+"output":[["Character", "foo<!--"], ["EndTag", "xmp"], ["Character", "-->"], ["EndTag", "xmp"]]},
-{"description":"Bogus comment in [R]CDATA",
-"contentModelFlags":["RCDATA", "CDATA"],
+{"description":"Bogus comment in RCDATA or RAWTEXT",
+"initialStates":["RCDATA state", "RAWTEXT state"],
"lastStartTag":"xmp",
"input":"foo<!-->baz</xmp>",
"output":[["Character", "foo<!-->baz"], ["EndTag", "xmp"]]},
-{"description":"End tag surrounded by bogus comment in [R]CDATA",
-"contentModelFlags":["RCDATA", "CDATA"],
+{"description":"End tag surrounded by bogus comment in RCDATA or RAWTEXT",
+"initialStates":["RCDATA state", "RAWTEXT state"],
"lastStartTag":"xmp",
"input":"foo<!--></xmp><!-->baz</xmp>",
"output":[["Character", "foo<!-->"], ["EndTag", "xmp"], "ParseError", ["Comment", ""], ["Character", "baz"], ["EndTag", "xmp"]]},
{"description":"Commented entities in RCDATA",
-"contentModelFlags":["RCDATA"],
+"initialStates":["RCDATA state"],
"lastStartTag":"xmp",
"input":" & <!-- & --> & </xmp>",
-"output":[["Character", " & <!-- & --> & "], ["EndTag", "xmp"]]},
+"output":[["Character", " & <!-- & --> & "], ["EndTag", "xmp"]]},
-{"description":"Incorrect comment ending sequences in [R]CDATA",
-"contentModelFlags":["RCDATA", "CDATA"],
+{"description":"Incorrect comment ending sequences in RCDATA or RAWTEXT",
+"initialStates":["RCDATA state", "RAWTEXT state"],
"lastStartTag":"xmp",
"input":"foo<!-- x --x>x-- >x--!>x--<></xmp>",
-"output":[["Character", "foo<!-- x --x>x-- >x--!>x--<></xmp>"]]}
+"output":[["Character", "foo<!-- x --x>x-- >x--!>x--<>"], ["EndTag", "xmp"]]}
]}
diff --git a/test/tokeniser2.c b/test/tokeniser2.c
index c320f42..d9bc3c1 100644
--- a/test/tokeniser2.c
+++ b/test/tokeniser2.c
@@ -27,7 +27,7 @@ typedef struct context {
size_t char_off;
const char *last_start_tag;
- struct array_list *content_model;
+ struct array_list *initial_state;
bool process_cdata;
} context;
@@ -65,7 +65,7 @@ int main(int argc, char **argv)
(struct json_object *) array_list_get_idx(tests, i);
ctx.last_start_tag = NULL;
- ctx.content_model = NULL;
+ ctx.initial_state = NULL;
ctx.process_cdata = false;
/* Extract settings */
@@ -88,8 +88,8 @@ int main(int argc, char **argv)
} else if (strcmp(key, "lastStartTag") == 0) {
ctx.last_start_tag = (const char *)
json_object_get_string(val);
- } else if (strcmp(key, "contentModelFlags") == 0) {
- ctx.content_model =
+ } else if (strcmp(key, "initialStates") == 0) {
+ ctx.initial_state =
json_object_get_array(val);
} else if (strcmp(key, "processCDATA") == 0) {
ctx.process_cdata =
@@ -116,10 +116,10 @@ void run_test(context *ctx)
int i, max_i;
struct array_list *outputsave = ctx->output;
- if (ctx->content_model == NULL) {
+ if (ctx->initial_state == NULL) {
max_i = 1;
} else {
- max_i = array_list_length(ctx->content_model);
+ max_i = array_list_length(ctx->initial_state);
}
/* We test for each of the content models specified */
@@ -163,30 +163,35 @@ void run_test(context *ctx)
HUBBUB_TOKENISER_TOKEN_HANDLER,
¶ms) == HUBBUB_OK);
- if (ctx->content_model == NULL) {
- params.content_model.model =
- HUBBUB_CONTENT_MODEL_PCDATA;
+ if (ctx->initial_state == NULL) {
+ params.initial_state.state =
+ HUBBUB_INITIAL_STATE_DATA;
} else {
const char *cm = json_object_get_string(
(struct json_object *)
- array_list_get_idx(ctx->content_model, i));
+ array_list_get_idx(ctx->initial_state, i));
if (strcmp(cm, "PCDATA") == 0) {
- params.content_model.model =
- HUBBUB_CONTENT_MODEL_PCDATA;
- } else if (strcmp(cm, "RCDATA") == 0) {
- params.content_model.model =
- HUBBUB_CONTENT_MODEL_RCDATA;
- } else if (strcmp(cm, "CDATA") == 0) {
- params.content_model.model =
- HUBBUB_CONTENT_MODEL_CDATA;
+ params.initial_state.state =
+ HUBBUB_INITIAL_STATE_DATA;
+ } else if (strcmp(cm, "RCDATA state") == 0) {
+
+ params.initial_state.state =
+ HUBBUB_INITIAL_STATE_RCDATA;
+ } else if (strcmp(cm, "CDATA state") == 0) {
+ params.initial_state.state =
+ HUBBUB_INITIAL_STATE_CDATA;
+ } else if (strcmp(cm, "RAWTEXT state") == 0) {
+ params.initial_state.state =
+ HUBBUB_INITIAL_STATE_RAWTEXT;
} else {
- params.content_model.model =
- HUBBUB_CONTENT_MODEL_PLAINTEXT;
+ params.initial_state.state =
+ HUBBUB_INITIAL_STATE_PLAINTEXT;
}
}
+
assert(hubbub_tokeniser_setopt(tok,
- HUBBUB_TOKENISER_CONTENT_MODEL,
+ HUBBUB_TOKENISER_INITIAL_STATE,
¶ms) == HUBBUB_OK);
assert(parserutils_inputstream_append(stream,
--
1.8.3.2
-
0003-Fix-tokeniser-test-executer-for-content-model-replac.patch (4,014 bytes) 2014-03-11 17:01
From 63739d3e61df0d30a520070b45ecc86e2aa771e7 Mon Sep 17 00:00:00 2001
From: Achal-Aggarwal <theachalaggarwal@gmail.com>
Date: Tue, 11 Mar 2014 18:04:11 +0530
Subject: [PATCH 3/4] Fix tokeniser test executer for content model
replacement.
---
test/tokeniser2.c | 1 -
test/tokeniser3.c | 48 +++++++++++++++++++++++++++---------------------
2 files changed, 27 insertions(+), 22 deletions(-)
diff --git a/test/tokeniser2.c b/test/tokeniser2.c
index d9bc3c1..db7c8f8 100644
--- a/test/tokeniser2.c
+++ b/test/tokeniser2.c
@@ -175,7 +175,6 @@ void run_test(context *ctx)
params.initial_state.state =
HUBBUB_INITIAL_STATE_DATA;
} else if (strcmp(cm, "RCDATA state") == 0) {
-
params.initial_state.state =
HUBBUB_INITIAL_STATE_RCDATA;
} else if (strcmp(cm, "CDATA state") == 0) {
diff --git a/test/tokeniser3.c b/test/tokeniser3.c
index 949ddd0..7ce2602 100644
--- a/test/tokeniser3.c
+++ b/test/tokeniser3.c
@@ -14,6 +14,8 @@
#include "testutils.h"
+#define strlen n_str
+
typedef struct context {
const uint8_t *input;
size_t input_len;
@@ -23,7 +25,7 @@ typedef struct context {
size_t char_off;
const char *last_start_tag;
- struct array_list *content_model;
+ struct array_list *initial_state;
bool process_cdata;
} context;
@@ -61,7 +63,7 @@ int main(int argc, char **argv)
(struct json_object *) array_list_get_idx(tests, i);
ctx.last_start_tag = NULL;
- ctx.content_model = NULL;
+ ctx.initial_state = NULL;
ctx.process_cdata = false;
/* Extract settings */
@@ -85,8 +87,8 @@ int main(int argc, char **argv)
} else if (strcmp(key, "lastStartTag") == 0) {
ctx.last_start_tag = (const char *)
json_object_get_string(val);
- } else if (strcmp(key, "contentModelFlags") == 0) {
- ctx.content_model =
+ } else if (strcmp(key, "initialStates") == 0) {
+ ctx.initial_state =
json_object_get_array(val);
} else if (strcmp(key, "processCDATA") == 0) {
ctx.process_cdata =
@@ -112,10 +114,10 @@ void run_test(context *ctx)
size_t j;
struct array_list *outputsave = ctx->output;
- if (ctx->content_model == NULL) {
+ if (ctx->initial_state == NULL) {
max_i = 1;
} else {
- max_i = array_list_length(ctx->content_model);
+ max_i = array_list_length(ctx->initial_state);
}
/* We test for each of the content models specified */
@@ -159,30 +161,34 @@ void run_test(context *ctx)
HUBBUB_TOKENISER_TOKEN_HANDLER,
¶ms) == HUBBUB_OK);
- if (ctx->content_model == NULL) {
- params.content_model.model =
- HUBBUB_CONTENT_MODEL_PCDATA;
+ if (ctx->initial_state == NULL) {
+ params.initial_state.state =
+ HUBBUB_INITIAL_STATE_DATA;
} else {
const char *cm = json_object_get_string(
(struct json_object *)
- array_list_get_idx(ctx->content_model, i));
+ array_list_get_idx(ctx->initial_state, i));
if (strcmp(cm, "PCDATA") == 0) {
- params.content_model.model =
- HUBBUB_CONTENT_MODEL_PCDATA;
- } else if (strcmp(cm, "RCDATA") == 0) {
- params.content_model.model =
- HUBBUB_CONTENT_MODEL_RCDATA;
- } else if (strcmp(cm, "CDATA") == 0) {
- params.content_model.model =
- HUBBUB_CONTENT_MODEL_CDATA;
+ params.initial_state.state =
+ HUBBUB_INITIAL_STATE_DATA;
+ } else if (strcmp(cm, "RCDATA state") == 0) {
+ params.initial_state.state =
+ HUBBUB_INITIAL_STATE_RCDATA;
+ } else if (strcmp(cm, "CDATA state") == 0) {
+ params.initial_state.state =
+ HUBBUB_INITIAL_STATE_CDATA;
+ } else if (strcmp(cm, "RAWTEXT state") == 0) {
+ params.initial_state.state =
+ HUBBUB_INITIAL_STATE_RAWTEXT;
} else {
- params.content_model.model =
- HUBBUB_CONTENT_MODEL_PLAINTEXT;
+ params.initial_state.state =
+ HUBBUB_INITIAL_STATE_PLAINTEXT;
}
}
+
assert(hubbub_tokeniser_setopt(tok,
- HUBBUB_TOKENISER_CONTENT_MODEL,
+ HUBBUB_TOKENISER_INITIAL_STATE,
¶ms) == HUBBUB_OK);
printf("Input: '%.*s' (%d)\n", (int) ctx->input_len,
--
1.8.3.2
-
0004-Fixing-rcdata-and-rawtext-close-tag-open-state-for-b.patch (4,433 bytes) 2014-03-11 17:01
From 7c54cf903300c4804540b8ed746ab5bca350bd81 Mon Sep 17 00:00:00 2001
From: Achal-Aggarwal <theachalaggarwal@gmail.com>
Date: Tue, 11 Mar 2014 19:15:02 +0530
Subject: [PATCH 4/4] Fixing rcdata and rawtext close tag open state for byte
by byte test.
---
src/tokeniser/tokeniser.c | 108 ++++++++++++++++++++++++----------------------
1 file changed, 56 insertions(+), 52 deletions(-)
diff --git a/src/tokeniser/tokeniser.c b/src/tokeniser/tokeniser.c
index 7152f05..3c18e92 100644
--- a/src/tokeniser/tokeniser.c
+++ b/src/tokeniser/tokeniser.c
@@ -1537,44 +1537,46 @@ hubbub_error hubbub_tokeniser_handle_rcdata_close_tag_open(hubbub_tokeniser *tok
parserutils_error error;
uint8_t c;
+ uint8_t *start_tag_name =
+ tokeniser->context.last_start_tag_name;
+ size_t start_tag_len =
+ tokeniser->context.last_start_tag_len;
+
assert(tokeniser->context.pending == 2);
/* assert(tokeniser->context.chars.ptr[0] == '<'); */
/* assert(tokeniser->context.chars.ptr[1] == '/'); */
- uint8_t *start_tag_name =
- tokeniser->context.last_start_tag_name;
- size_t start_tag_len =
- tokeniser->context.last_start_tag_len;
-
- while ((error = parserutils_inputstream_peek(tokeniser->input,
- ctx->pending +
- ctx->close_tag_match.count,
- &cptr,
- &len)) == PARSERUTILS_OK) {
- c = *cptr;
+ if (ctx->close_tag_match.match == false) {
- if ((start_tag_name[ctx->close_tag_match.count] & ~0x20)
- != (c & ~0x20)) {
- break;
- }
-
- ctx->close_tag_match.count += len;
+ while ((error = parserutils_inputstream_peek(tokeniser->input,
+ ctx->pending +
+ ctx->close_tag_match.count,
+ &cptr,
+ &len)) == PARSERUTILS_OK) {
+ c = *cptr;
+ if ((start_tag_name[ctx->close_tag_match.count] & ~0x20)
+ != (c & ~0x20)) {
+ break;
+ }
- if (ctx->close_tag_match.count == start_tag_len) {
+ ctx->close_tag_match.count += len;
- // Sets the flag to be used in name state.
- ctx->close_tag_match.match = true;
- break;
+ if (ctx->close_tag_match.count == start_tag_len) {
+ // Sets the flag to be used in name state.
+ ctx->close_tag_match.match = true;
+ break;
+ }
}
- }
- if (error != PARSERUTILS_OK) {
- if (error == PARSERUTILS_EOF) {
- tokeniser->state = STATE_RCDATA;
- tokeniser->context.pending += ctx->close_tag_match.count;
- return HUBBUB_OK;
- } else {
- return hubbub_error_from_parserutils_error(error);
+ if (error != PARSERUTILS_OK) {
+ if (error == PARSERUTILS_EOF) {
+ tokeniser->state = STATE_RCDATA;
+ tokeniser->context.pending += ctx->close_tag_match.count;
+
+ return HUBBUB_OK;
+ } else {
+ return hubbub_error_from_parserutils_error(error);
+ }
}
}
@@ -1752,35 +1754,37 @@ hubbub_error hubbub_tokeniser_handle_rawtext_close_tag_open(hubbub_tokeniser *to
size_t start_tag_len =
tokeniser->context.last_start_tag_len;
- while ((error = parserutils_inputstream_peek(tokeniser->input,
- ctx->pending +
- ctx->close_tag_match.count,
- &cptr,
- &len)) == PARSERUTILS_OK) {
- c = *cptr;
+ if (ctx->close_tag_match.match == false) {
+ while ((error = parserutils_inputstream_peek(tokeniser->input,
+ ctx->pending +
+ ctx->close_tag_match.count,
+ &cptr,
+ &len)) == PARSERUTILS_OK) {
+ c = *cptr;
- if ((start_tag_name[ctx->close_tag_match.count] & ~0x20)
- != (c & ~0x20)) {
- break;
- }
+ if ((start_tag_name[ctx->close_tag_match.count] & ~0x20)
+ != (c & ~0x20)) {
+ break;
+ }
- ctx->close_tag_match.count += len;
+ ctx->close_tag_match.count += len;
- if (ctx->close_tag_match.count == start_tag_len) {
+ if (ctx->close_tag_match.count == start_tag_len) {
- // Sets the flag to be used in name state.
- ctx->close_tag_match.match = true;
- break;
+ // Sets the flag to be used in name state.
+ ctx->close_tag_match.match = true;
+ break;
+ }
}
- }
- if (error != PARSERUTILS_OK) {
- if (error == PARSERUTILS_EOF) {
- tokeniser->state = STATE_RAWTEXT;
- tokeniser->context.pending += ctx->close_tag_match.count;
- return HUBBUB_OK;
- } else {
- return hubbub_error_from_parserutils_error(error);
+ if (error != PARSERUTILS_OK) {
+ if (error == PARSERUTILS_EOF) {
+ tokeniser->state = STATE_RAWTEXT;
+ tokeniser->context.pending += ctx->close_tag_match.count;
+ return HUBBUB_OK;
+ } else {
+ return hubbub_error_from_parserutils_error(error);
+ }
}
}
--
1.8.3.2
|
---|