示例#1
0
 protected function nextToken(SegmentedString $source)
 {
     while (true) {
         $char = $this->_SegmentedString->getCurrentChar();
         switch ($this->_state) {
             case static::DataState:
                 if ($char === '&') {
                     $this->_HTML_ADVANCE_TO(static::CharacterReferenceInDataState);
                 } else {
                     if ($char === '<') {
                         if ($this->_Token->getType() === HTMLToken::Character) {
                             // We have a bunch of character tokens queued up that we
                             // are emitting lazily here.
                             return true;
                         }
                         $this->_HTML_ADVANCE_TO(static::TagOpenState);
                     } else {
                         if ($char === static::kEndOfFileMarker) {
                             return $this->_emitEndOfFile();
                         } else {
                             $this->_bufferCharacter($char);
                             $this->_HTML_ADVANCE_TO(static::DataState);
                         }
                     }
                 }
                 break;
             case static::CharacterReferenceInDataState:
                 // TODO Do not expand the reference, so skip parse Character references.
                 $this->_HTML_SWITCH_TO(static::DataState);
                 break;
             case static::RCDATAState:
                 if ($char === '&') {
                     $this->_HTML_ADVANCE_TO(static::CharacterReferenceInRCDATAState);
                 } else {
                     if ($char === '<') {
                         $this->_HTML_ADVANCE_TO(static::RCDATALessThanSignState);
                     } else {
                         if ($char === static::kEndOfFileMarker) {
                             return $this->_emitEndOfFile();
                         } else {
                             $this->_bufferCharacter($char);
                             $this->_HTML_ADVANCE_TO(static::RCDATAState);
                         }
                     }
                 }
                 break;
             case static::CharacterReferenceInRCDATAState:
                 // TODO Do not expand the reference, so skip parse Character references.
                 $this->_HTML_SWITCH_TO(static::RCDATAState);
                 break;
             case static::RAWTEXTState:
                 if ($char === '<') {
                     $this->_HTML_ADVANCE_TO(static::RAWTEXTLessThanSignState);
                 } else {
                     if ($char === static::kEndOfFileMarker) {
                         return $this->_emitEndOfFile();
                     } else {
                         $this->_bufferCharacter($char);
                         $this->_HTML_ADVANCE_TO(static::RAWTEXTState);
                     }
                 }
                 break;
             case static::ScriptDataState:
                 if ($char === '<') {
                     $this->_HTML_ADVANCE_TO(static::ScriptDataLessThanSignState);
                 } else {
                     if ($char === static::kEndOfFileMarker) {
                         return $this->_emitEndOfFile();
                     } else {
                         $this->_bufferCharacter($char);
                         $this->_HTML_ADVANCE_TO(static::ScriptDataState);
                     }
                 }
                 break;
             case static::PLAINTEXTState:
                 if ($char === static::kEndOfFileMarker) {
                     return $this->_emitEndOfFile();
                 } else {
                     $this->_bufferCharacter($char);
                     $this->_HTML_ADVANCE_TO(static::PLAINTEXTState);
                 }
                 break;
             case static::TagOpenState:
                 if ($char === '!') {
                     $this->_HTML_ADVANCE_TO(static::MarkupDeclarationOpenState);
                 } else {
                     if ($char === '/') {
                         $this->_HTML_ADVANCE_TO(static::EndTagOpenState);
                     } else {
                         if (ctype_upper($char)) {
                             $this->_Token->beginStartTag(strtolower($char));
                             $this->_HTML_ADVANCE_TO(static::TagNameState);
                         } else {
                             if (ctype_lower($char)) {
                                 $this->_Token->beginStartTag(strtolower($char));
                                 $this->_HTML_ADVANCE_TO(static::TagNameState);
                             } else {
                                 if ($char === '?') {
                                     $this->_parseError();
                                     // The spec consumes the current character before switching
                                     // to the bogus comment state, but it's easier to implement
                                     // if we reconsume the current character.
                                     $this->_HTML_RECONSUME_IN(static::BogusCommentState);
                                 } else {
                                     $this->_parseError();
                                     $this->_bufferCharacter('<');
                                     $this->_HTML_RECONSUME_IN(static::DataState);
                                 }
                             }
                         }
                     }
                 }
                 break;
             case static::EndTagOpenState:
                 if (ctype_upper($char)) {
                     $this->_Token->beginEndTag(strtolower($char));
                     $this->_HTML_ADVANCE_TO(static::TagNameState);
                 } else {
                     if (ctype_lower($char)) {
                         $this->_Token->beginEndTag(strtolower($char));
                         $this->_HTML_ADVANCE_TO(static::TagNameState);
                     } else {
                         if ($char === '>') {
                             $this->_parseError();
                             $this->_HTML_ADVANCE_TO(static::DataState);
                         } else {
                             if ($char === static::kEndOfFileMarker) {
                                 $this->_parseError();
                                 $this->_bufferCharacter('<');
                                 $this->_bufferCharacter('/');
                                 $this->_HTML_RECONSUME_IN(static::DataState);
                             } else {
                                 $this->_parseError();
                                 $this->_HTML_RECONSUME_IN(static::BogusCommentState);
                             }
                         }
                     }
                 }
                 break;
             case static::TagNameState:
                 if ($this->_isTokenizerWhitespace($char)) {
                     $this->_HTML_ADVANCE_TO(static::BeforeAttributeNameState);
                 } else {
                     if ($char === '/') {
                         $this->_HTML_ADVANCE_TO(static::SelfClosingStartTagState);
                     } else {
                         if ($char === '>') {
                             return $this->_emitAndResumeIn();
                         } else {
                             if (ctype_upper($char)) {
                                 $this->_Token->appendToName(strtolower($char));
                                 $this->_HTML_ADVANCE_TO(static::TagNameState);
                             } else {
                                 if ($char === static::kEndOfFileMarker) {
                                     $this->_parseError();
                                     $this->_HTML_RECONSUME_IN(static::DataState);
                                 } else {
                                     $this->_Token->appendToName($char);
                                     $this->_HTML_ADVANCE_TO(static::TagNameState);
                                 }
                             }
                         }
                     }
                 }
                 break;
             case static::RCDATALessThanSignState:
                 if ($char === '/') {
                     $this->_temporaryBuffer = '';
                     $this->_HTML_ADVANCE_TO(static::RCDATAEndTagOpenState);
                 } else {
                     $this->_bufferCharacter('<');
                     $this->_HTML_RECONSUME_IN(static::RCDATAState);
                 }
                 break;
             case static::RCDATAEndTagOpenState:
                 if (ctype_upper($char)) {
                     $this->_temporaryBuffer .= $char;
                     $this->_bufferedEndTagName .= strtolower($char);
                     $this->_HTML_ADVANCE_TO(static::RCDATAEndTagNameState);
                 } else {
                     if (ctype_lower($char)) {
                         $this->_temporaryBuffer .= $char;
                         $this->_bufferedEndTagName .= $char;
                         $this->_HTML_ADVANCE_TO(static::RCDATAEndTagNameState);
                     } else {
                         $this->_bufferCharacter('<');
                         $this->_bufferCharacter('/');
                         $this->_HTML_RECONSUME_IN(static::RCDATAState);
                     }
                 }
                 break;
             case static::RCDATAEndTagNameState:
                 if (ctype_upper($char)) {
                     $this->_temporaryBuffer .= $char;
                     $this->_bufferedEndTagName .= strtolower($char);
                     $this->_HTML_ADVANCE_TO(static::RCDATAEndTagNameState);
                 } else {
                     if (ctype_lower($char)) {
                         $this->_temporaryBuffer .= $char;
                         $this->_bufferedEndTagName .= $char;
                         $this->_HTML_ADVANCE_TO(static::RCDATAEndTagNameState);
                     } else {
                         if ($this->_isTokenizerWhitespace($char)) {
                             if ($this->_isAppropriateEndTag()) {
                                 $this->_temporaryBuffer .= $char;
                                 $result = $this->_FLUSH_AND_ADVANCE_TO(static::BeforeAttributeNameState);
                                 if ($result !== null) {
                                     return $result;
                                 }
                                 break;
                             }
                         } else {
                             if ($char === '/') {
                                 if ($this->_isAppropriateEndTag()) {
                                     $this->_temporaryBuffer .= $char;
                                     $result = $this->_FLUSH_AND_ADVANCE_TO(static::SelfClosingStartTagState);
                                     if ($result !== null) {
                                         return $result;
                                     }
                                     break;
                                 }
                             } else {
                                 if ($char === '>') {
                                     if ($this->_isAppropriateEndTag()) {
                                         $this->_temporaryBuffer .= $char;
                                         return $this->_flushEmitAndResumeIn($source, HTMLTokenizer::DataState);
                                     }
                                 }
                             }
                         }
                         $this->_bufferCharacter('<');
                         $this->_bufferCharacter('/');
                         $this->_Token->appendToCharacter($this->_temporaryBuffer);
                         $this->_bufferedEndTagName = '';
                         $this->_temporaryBuffer = '';
                         $this->_HTML_RECONSUME_IN(static::RCDATAState);
                     }
                 }
                 break;
             case static::RAWTEXTLessThanSignState:
                 if ($char === '/') {
                     $this->_temporaryBuffer = '';
                     $this->_HTML_ADVANCE_TO(static::RAWTEXTEndTagOpenState);
                 } else {
                     $this->_bufferCharacter('<');
                     $this->_HTML_RECONSUME_IN(static::RAWTEXTState);
                 }
                 break;
             case static::RAWTEXTEndTagOpenState:
                 if (ctype_upper($char)) {
                     $this->_temporaryBuffer .= $char;
                     $this->_bufferedEndTagName .= strtolower($char);
                     $this->_HTML_ADVANCE_TO(static::RAWTEXTEndTagNameState);
                 } else {
                     if (ctype_lower($char)) {
                         $this->_temporaryBuffer .= $char;
                         $this->_bufferedEndTagName .= $char;
                         $this->_HTML_ADVANCE_TO(static::RAWTEXTEndTagNameState);
                     } else {
                         $this->_bufferCharacter('<');
                         $this->_bufferCharacter('/');
                         $this->_HTML_RECONSUME_IN(static::RAWTEXTState);
                     }
                 }
                 break;
             case static::RAWTEXTEndTagNameState:
                 if (ctype_upper($char)) {
                     $this->_temporaryBuffer .= $char;
                     $this->_bufferedEndTagName .= strtolower($char);
                     $this->_HTML_ADVANCE_TO(static::RAWTEXTEndTagNameState);
                 } else {
                     if (ctype_lower($char)) {
                         $this->_temporaryBuffer .= $char;
                         $this->_bufferedEndTagName .= $char;
                         $this->_HTML_ADVANCE_TO(static::RAWTEXTEndTagNameState);
                     } else {
                         if ($this->_isTokenizerWhitespace($char)) {
                             if ($this->_isAppropriateEndTag()) {
                                 $this->_temporaryBuffer .= $char;
                                 $result = $this->_FLUSH_AND_ADVANCE_TO(static::BeforeAttributeNameState);
                                 if ($result !== null) {
                                     return $result;
                                 }
                                 break;
                             }
                         } else {
                             if ($char === '/') {
                                 if ($this->_isAppropriateEndTag()) {
                                     $this->_temporaryBuffer .= $char;
                                     $result = $this->_FLUSH_AND_ADVANCE_TO(static::SelfClosingStartTagState);
                                     if ($result !== null) {
                                         return $result;
                                     }
                                     break;
                                 }
                             } else {
                                 if ($char === '>') {
                                     if ($this->_isAppropriateEndTag()) {
                                         $this->_temporaryBuffer .= $char;
                                         return $this->_flushEmitAndResumeIn($source, HTMLTokenizer::DataState);
                                     }
                                 }
                             }
                         }
                         $this->_bufferCharacter('<');
                         $this->_bufferCharacter('/');
                         $this->_Token->appendToCharacter($this->_temporaryBuffer);
                         $this->_bufferedEndTagName = '';
                         $this->_temporaryBuffer = '';
                         $this->_HTML_RECONSUME_IN(static::RAWTEXTState);
                     }
                 }
                 break;
             case static::ScriptDataLessThanSignState:
                 if ($char === '/') {
                     $this->_temporaryBuffer = '';
                     $this->_HTML_ADVANCE_TO(static::ScriptDataEndTagOpenState);
                 } else {
                     if ($char === '!') {
                         $this->_bufferCharacter('<');
                         $this->_bufferCharacter('!');
                         $this->_HTML_ADVANCE_TO(static::ScriptDataEscapeStartState);
                     } else {
                         $this->_bufferCharacter('<');
                         $this->_HTML_RECONSUME_IN(static::ScriptDataState);
                     }
                 }
                 break;
             case static::ScriptDataEndTagOpenState:
                 if (ctype_upper($char)) {
                     $this->_temporaryBuffer .= $char;
                     $this->_bufferedEndTagName .= strtolower($char);
                     $this->_HTML_ADVANCE_TO(static::ScriptDataEndTagNameState);
                 } else {
                     if (ctype_lower($char)) {
                         $this->_temporaryBuffer .= $char;
                         $this->_bufferedEndTagName .= $char;
                         $this->_HTML_ADVANCE_TO(static::ScriptDataEndTagNameState);
                     } else {
                         $this->_bufferCharacter('<');
                         $this->_bufferCharacter('/');
                         $this->_HTML_RECONSUME_IN(static::ScriptDataState);
                     }
                 }
                 break;
             case static::ScriptDataEndTagNameState:
                 if (ctype_upper($char)) {
                     $this->_temporaryBuffer .= $char;
                     $this->_bufferedEndTagName .= strtolower($char);
                     $this->_HTML_ADVANCE_TO(static::ScriptDataEndTagNameState);
                 } else {
                     if (ctype_lower($char)) {
                         $this->_temporaryBuffer .= $char;
                         $this->_bufferedEndTagName .= $char;
                         $this->_HTML_ADVANCE_TO(static::ScriptDataEndTagNameState);
                     } else {
                         if ($this->_isTokenizerWhitespace($char)) {
                             if ($this->_isAppropriateEndTag()) {
                                 $this->_temporaryBuffer .= $char;
                                 $result = $this->_FLUSH_AND_ADVANCE_TO(static::BeforeAttributeNameState);
                                 if ($result !== null) {
                                     return $result;
                                 }
                                 break;
                             }
                         } else {
                             if ($char === '/') {
                                 if ($this->_isAppropriateEndTag()) {
                                     $this->_temporaryBuffer .= $char;
                                     $result = $this->_FLUSH_AND_ADVANCE_TO(static::SelfClosingStartTagState);
                                     if ($result !== null) {
                                         return $result;
                                     }
                                     break;
                                 }
                             } else {
                                 if ($char === '>') {
                                     if ($this->_isAppropriateEndTag()) {
                                         $this->_temporaryBuffer .= $char;
                                         return $this->_flushEmitAndResumeIn($source, HTMLTokenizer::DataState);
                                     }
                                 }
                             }
                         }
                         $this->_bufferCharacter('<');
                         $this->_bufferCharacter('/');
                         $this->_Token->appendToCharacter($this->_temporaryBuffer);
                         $this->_bufferedEndTagName = '';
                         $this->_temporaryBuffer = '';
                         $this->_HTML_RECONSUME_IN(static::ScriptDataState);
                     }
                 }
                 break;
             case static::ScriptDataEscapeStartState:
                 if ($char === '-') {
                     $this->_bufferCharacter($char);
                     $this->_HTML_ADVANCE_TO(static::ScriptDataEscapeStartDashState);
                 } else {
                     $this->_HTML_RECONSUME_IN(static::ScriptDataState);
                 }
                 break;
             case static::ScriptDataEscapeStartDashState:
                 if ($char === '-') {
                     $this->_bufferCharacter($char);
                     $this->_HTML_ADVANCE_TO(static::ScriptDataEscapedDashDashState);
                 } else {
                     $this->_HTML_RECONSUME_IN(static::ScriptDataState);
                 }
                 break;
             case static::ScriptDataEscapedState:
                 if ($char === '-') {
                     $this->_bufferCharacter($char);
                     $this->_HTML_ADVANCE_TO(static::ScriptDataEscapedDashState);
                 } else {
                     if ($char === '<') {
                         $this->_HTML_ADVANCE_TO(static::ScriptDataEscapedLessThanSignState);
                     } else {
                         if ($char === static::kEndOfFileMarker) {
                             $this->_parseError();
                             $this->_HTML_RECONSUME_IN(static::DataState);
                         } else {
                             $this->_bufferCharacter($char);
                             $this->_HTML_ADVANCE_TO(static::ScriptDataEscapedState);
                         }
                     }
                 }
                 break;
             case static::ScriptDataEscapedDashState:
                 if ($char === '-') {
                     $this->_bufferCharacter($char);
                     $this->_HTML_ADVANCE_TO(static::ScriptDataEscapedDashDashState);
                 } else {
                     if ($char === '<') {
                         $this->_HTML_ADVANCE_TO(static::ScriptDataEscapedLessThanSignState);
                     } else {
                         if ($char === static::kEndOfFileMarker) {
                             $this->_parseError();
                             $this->_HTML_RECONSUME_IN(static::DataState);
                         } else {
                             $this->_bufferCharacter($char);
                             $this->_HTML_ADVANCE_TO(static::ScriptDataEscapedState);
                         }
                     }
                 }
                 break;
             case static::ScriptDataEscapedDashDashState:
                 if ($char === '-') {
                     $this->_bufferCharacter($char);
                     $this->_HTML_ADVANCE_TO(static::ScriptDataEscapedDashDashState);
                 } else {
                     if ($char === '<') {
                         $this->_HTML_ADVANCE_TO(static::ScriptDataEscapedLessThanSignState);
                     } else {
                         if ($char === '>') {
                             $this->_bufferCharacter($char);
                             $this->_HTML_ADVANCE_TO(static::ScriptDataState);
                         } else {
                             if ($char === static::kEndOfFileMarker) {
                                 $this->_parseError();
                                 $this->_HTML_RECONSUME_IN(static::DataState);
                             } else {
                                 $this->_bufferCharacter($char);
                                 $this->_HTML_ADVANCE_TO(static::ScriptDataEscapedState);
                             }
                         }
                     }
                 }
                 break;
             case static::ScriptDataEscapedLessThanSignState:
                 if ($char === '/') {
                     $this->_temporaryBuffer = '';
                     $this->_HTML_ADVANCE_TO(static::ScriptDataEscapedEndTagOpenState);
                 } else {
                     if (ctype_upper($char)) {
                         $this->_bufferCharacter('<');
                         $this->_bufferCharacter($char);
                         $this->_temporaryBuffer = '';
                         $this->_temporaryBuffer = strtolower($char);
                         $this->_HTML_ADVANCE_TO(static::ScriptDataDoubleEscapeStartState);
                     } else {
                         if (ctype_lower($char)) {
                             $this->_bufferCharacter('<');
                             $this->_bufferCharacter($char);
                             $this->_temporaryBuffer = '';
                             $this->_temporaryBuffer .= $char;
                             $this->_HTML_ADVANCE_TO(static::ScriptDataDoubleEscapeStartState);
                         } else {
                             $this->_bufferCharacter('<');
                             $this->_HTML_RECONSUME_IN(static::ScriptDataEscapedState);
                         }
                     }
                 }
                 break;
             case static::ScriptDataEscapedEndTagOpenState:
                 if (ctype_upper($char)) {
                     $this->_temporaryBuffer .= $char;
                     $this->_bufferedEndTagName .= strtolower($char);
                     $this->_HTML_ADVANCE_TO(static::ScriptDataEscapedEndTagNameState);
                 } else {
                     if (ctype_lower($char)) {
                         $this->_temporaryBuffer .= $char;
                         $this->_bufferedEndTagName .= $char;
                         $this->_HTML_ADVANCE_TO(static::ScriptDataEscapedEndTagNameState);
                     } else {
                         $this->_bufferCharacter('<');
                         $this->_bufferCharacter('/');
                         $this->_HTML_RECONSUME_IN(static::ScriptDataEscapedState);
                     }
                 }
                 break;
             case static::ScriptDataEscapedEndTagNameState:
                 if (ctype_upper($char)) {
                     $this->_temporaryBuffer .= $char;
                     $this->_bufferedEndTagName .= strtolower($char);
                     $this->_HTML_ADVANCE_TO(static::ScriptDataEscapedEndTagNameState);
                 } else {
                     if (ctype_lower($char)) {
                         $this->_temporaryBuffer .= $char;
                         $this->_bufferedEndTagName .= $char;
                         $this->_HTML_ADVANCE_TO(static::ScriptDataEscapedEndTagNameState);
                     } else {
                         if ($this->_isTokenizerWhitespace($char)) {
                             if ($this->_isAppropriateEndTag()) {
                                 $this->_temporaryBuffer .= $char;
                                 // ScriptDataEscapeStartState called bufferCharacter, so `_FLUSH_AND_ADVANCE_TO` always returns true.
                                 return $this->_FLUSH_AND_ADVANCE_TO(static::BeforeAttributeNameState);
                             }
                         } else {
                             if ($char === '/') {
                                 if ($this->_isAppropriateEndTag()) {
                                     $this->_temporaryBuffer .= $char;
                                     // ScriptDataEscapeStartState called bufferCharacter, so `_FLUSH_AND_ADVANCE_TO` always returns true.
                                     return $this->_FLUSH_AND_ADVANCE_TO(static::SelfClosingStartTagState);
                                 }
                             } else {
                                 if ($char === '>') {
                                     if ($this->_isAppropriateEndTag()) {
                                         $this->_temporaryBuffer .= $char;
                                         $this->_temporaryBuffer .= $char;
                                         return $this->_flushEmitAndResumeIn($source, HTMLTokenizer::DataState);
                                     }
                                 }
                             }
                         }
                         $this->_bufferCharacter('<');
                         $this->_bufferCharacter('/');
                         $this->_Token->appendToCharacter($this->_temporaryBuffer);
                         $this->_bufferedEndTagName = '';
                         $this->_temporaryBuffer = '';
                         $this->_HTML_RECONSUME_IN(static::ScriptDataEscapedState);
                     }
                 }
                 break;
             case static::ScriptDataDoubleEscapeStartState:
                 if ($this->_isTokenizerWhitespace($char) || $char === '/' || $char === '>') {
                     $this->_bufferCharacter($char);
                     if ($this->_temporaryBufferIs(HTMLNames::scriptTag)) {
                         $this->_HTML_ADVANCE_TO(static::ScriptDataDoubleEscapedState);
                     } else {
                         $this->_HTML_ADVANCE_TO(static::ScriptDataEscapedState);
                     }
                 } else {
                     if (ctype_upper($char)) {
                         $this->_bufferCharacter($char);
                         $this->_temporaryBuffer .= strtolower($char);
                         $this->_HTML_ADVANCE_TO(static::ScriptDataDoubleEscapeStartState);
                     } else {
                         if (ctype_lower($char)) {
                             $this->_bufferCharacter($char);
                             $this->_temporaryBuffer .= $char;
                             $this->_HTML_ADVANCE_TO(static::ScriptDataDoubleEscapeStartState);
                         } else {
                             $this->_HTML_RECONSUME_IN(static::ScriptDataEscapedState);
                         }
                     }
                 }
                 break;
             case static::ScriptDataDoubleEscapedState:
                 if ($char === '-') {
                     $this->_bufferCharacter($char);
                     $this->_HTML_ADVANCE_TO(static::ScriptDataDoubleEscapedDashState);
                 } else {
                     if ($char === '<') {
                         $this->_bufferCharacter($char);
                         $this->_HTML_ADVANCE_TO(static::ScriptDataDoubleEscapedLessThanSignState);
                     } else {
                         if ($char === static::kEndOfFileMarker) {
                             $this->_parseError();
                             $this->_HTML_RECONSUME_IN(static::DataState);
                         } else {
                             $this->_bufferCharacter($char);
                             $this->_HTML_ADVANCE_TO(static::ScriptDataDoubleEscapedState);
                         }
                     }
                 }
                 break;
             case static::ScriptDataDoubleEscapedDashState:
                 if ($char === '-') {
                     $this->_bufferCharacter($char);
                     $this->_HTML_ADVANCE_TO(static::ScriptDataDoubleEscapedDashDashState);
                 } else {
                     if ($char === '<') {
                         $this->_bufferCharacter($char);
                         $this->_HTML_ADVANCE_TO(static::ScriptDataDoubleEscapedLessThanSignState);
                     } else {
                         if ($char === static::kEndOfFileMarker) {
                             $this->_parseError();
                             $this->_HTML_RECONSUME_IN(static::DataState);
                         } else {
                             $this->_bufferCharacter($char);
                             $this->_HTML_ADVANCE_TO(static::ScriptDataDoubleEscapedState);
                         }
                     }
                 }
                 break;
             case static::ScriptDataDoubleEscapedDashDashState:
                 if ($char === '-') {
                     $this->_bufferCharacter($char);
                     $this->_HTML_ADVANCE_TO(static::ScriptDataDoubleEscapedDashDashState);
                 } else {
                     if ($char === '<') {
                         $this->_bufferCharacter($char);
                         $this->_HTML_ADVANCE_TO(static::ScriptDataDoubleEscapedLessThanSignState);
                     } else {
                         if ($char === '>') {
                             $this->_bufferCharacter($char);
                             $this->_HTML_ADVANCE_TO(static::ScriptDataState);
                         } else {
                             if ($char === static::kEndOfFileMarker) {
                                 $this->_parseError();
                                 $this->_HTML_RECONSUME_IN(static::DataState);
                             } else {
                                 $this->_bufferCharacter($char);
                                 $this->_HTML_ADVANCE_TO(static::ScriptDataDoubleEscapedState);
                             }
                         }
                     }
                 }
                 break;
             case static::ScriptDataDoubleEscapedLessThanSignState:
                 if ($char === '/') {
                     $this->_bufferCharacter($char);
                     $this->_temporaryBuffer = '';
                     $this->_HTML_ADVANCE_TO(static::ScriptDataDoubleEscapeEndState);
                 } else {
                     $this->_HTML_RECONSUME_IN(static::ScriptDataDoubleEscapedState);
                 }
                 break;
             case static::ScriptDataDoubleEscapeEndState:
                 if ($this->_isTokenizerWhitespace($char) || $char === '/' || $char === '>') {
                     $this->_bufferCharacter($char);
                     if ($this->_temporaryBufferIs(HTMLNames::scriptTag)) {
                         $this->_HTML_ADVANCE_TO(static::ScriptDataEscapedState);
                     } else {
                         $this->_HTML_ADVANCE_TO(static::ScriptDataDoubleEscapedState);
                     }
                 } else {
                     if (ctype_upper($char)) {
                         $this->_bufferCharacter($char);
                         $this->_temporaryBuffer .= strtolower($char);
                         $this->_HTML_ADVANCE_TO(static::ScriptDataDoubleEscapeEndState);
                     } else {
                         if (ctype_lower($char)) {
                             $this->_bufferCharacter($char);
                             $this->_temporaryBuffer .= $char;
                             $this->_HTML_ADVANCE_TO(static::ScriptDataDoubleEscapeEndState);
                         } else {
                             $this->_HTML_RECONSUME_IN(static::ScriptDataDoubleEscapedState);
                         }
                     }
                 }
                 break;
             case static::BeforeAttributeNameState:
                 if ($this->_isTokenizerWhitespace($char)) {
                     $this->_HTML_ADVANCE_TO(static::BeforeAttributeNameState);
                 } else {
                     if ($char === '/') {
                         $this->_HTML_ADVANCE_TO(static::SelfClosingStartTagState);
                     } else {
                         if ($char === '>') {
                             return $this->_emitAndResumeIn();
                         } else {
                             if (ctype_upper($char)) {
                                 $this->_Token->addNewAttribute();
                                 $this->_Token->beginAttributeName($source->numberOfCharactersConsumed());
                                 $this->_Token->appendToAttributeName(strtolower($char));
                                 $this->_HTML_ADVANCE_TO(static::AttributeNameState);
                             } else {
                                 if ($char === static::kEndOfFileMarker) {
                                     $this->_parseError();
                                     $this->_HTML_RECONSUME_IN(static::DataState);
                                 } else {
                                     if ($char === '"' || $char === '\'' || $char === '<' || $char === '=') {
                                         $this->_parseError();
                                     }
                                     $this->_Token->addNewAttribute();
                                     $this->_Token->beginAttributeName($source->numberOfCharactersConsumed());
                                     $this->_Token->appendToAttributeName($char);
                                     $this->_HTML_ADVANCE_TO(static::AttributeNameState);
                                 }
                             }
                         }
                     }
                 }
                 break;
             case static::AttributeNameState:
                 if ($this->_isTokenizerWhitespace($char)) {
                     $this->_Token->endAttributeName($source->numberOfCharactersConsumed());
                     $this->_HTML_ADVANCE_TO(static::AfterAttributeNameState);
                 } else {
                     if ($char === '/') {
                         $this->_Token->endAttributeName($source->numberOfCharactersConsumed());
                         $this->_HTML_ADVANCE_TO(static::SelfClosingStartTagState);
                     } else {
                         if ($char === '=') {
                             $this->_Token->endAttributeName($source->numberOfCharactersConsumed());
                             $this->_HTML_ADVANCE_TO(static::BeforeAttributeValueState);
                         } else {
                             if ($char === '>') {
                                 $this->_Token->endAttributeName($source->numberOfCharactersConsumed());
                                 return $this->_emitAndResumeIn();
                             } else {
                                 if (ctype_upper($char)) {
                                     $this->_Token->appendToAttributeName(strtolower($char));
                                     $this->_HTML_ADVANCE_TO(static::AttributeNameState);
                                 } else {
                                     if ($char === static::kEndOfFileMarker) {
                                         $this->_parseError();
                                         $this->_Token->endAttributeName($source->numberOfCharactersConsumed());
                                         $this->_HTML_RECONSUME_IN(static::DataState);
                                     } else {
                                         if ($char === '"' || $char === '\'' || $char === '<' || $char === '=') {
                                             $this->_parseError();
                                         }
                                         $this->_Token->appendToAttributeName($char);
                                         $this->_HTML_ADVANCE_TO(static::AttributeNameState);
                                     }
                                 }
                             }
                         }
                     }
                 }
                 break;
             case static::AfterAttributeNameState:
                 if ($this->_isTokenizerWhitespace($char)) {
                     $this->_HTML_ADVANCE_TO(static::AfterAttributeNameState);
                 } else {
                     if ($char === '/') {
                         $this->_HTML_ADVANCE_TO(static::SelfClosingStartTagState);
                     } else {
                         if ($char === '=') {
                             $this->_HTML_ADVANCE_TO(static::BeforeAttributeValueState);
                         } else {
                             if ($char === '>') {
                                 return $this->_emitAndResumeIn();
                             } else {
                                 if (ctype_upper($char)) {
                                     $this->_Token->addNewAttribute();
                                     $this->_Token->beginAttributeName($source->numberOfCharactersConsumed());
                                     $this->_Token->appendToAttributeName(strtolower($char));
                                     $this->_HTML_ADVANCE_TO(static::AttributeNameState);
                                 } else {
                                     if ($char === static::kEndOfFileMarker) {
                                         $this->_parseError();
                                         $this->_HTML_RECONSUME_IN(static::DataState);
                                     } else {
                                         if ($char === '"' || $char === '\'' || $char === '<') {
                                             $this->_parseError();
                                         }
                                         $this->_Token->addNewAttribute();
                                         $this->_Token->beginAttributeName($source->numberOfCharactersConsumed());
                                         $this->_Token->appendToAttributeName($char);
                                         $this->_HTML_ADVANCE_TO(static::AttributeNameState);
                                     }
                                 }
                             }
                         }
                     }
                 }
                 break;
             case static::BeforeAttributeValueState:
                 if ($this->_isTokenizerWhitespace($char)) {
                     $this->_HTML_ADVANCE_TO(static::BeforeAttributeValueState);
                 } else {
                     if ($char === '"') {
                         $this->_Token->beginAttributeValue($source->numberOfCharactersConsumed() + 1);
                         $this->_HTML_ADVANCE_TO(static::AttributeValueDoubleQuotedState);
                     } else {
                         if ($char === '&') {
                             $this->_Token->beginAttributeValue($source->numberOfCharactersConsumed());
                             $this->_HTML_RECONSUME_IN(static::AttributeValueUnquotedState);
                         } else {
                             if ($char === '\'') {
                                 $this->_Token->beginAttributeValue($source->numberOfCharactersConsumed() + 1);
                                 $this->_HTML_ADVANCE_TO(static::AttributeValueSingleQuotedState);
                             } else {
                                 if ($char === '>') {
                                     $this->_parseError();
                                     return $this->_emitAndResumeIn();
                                 } else {
                                     if ($char === static::kEndOfFileMarker) {
                                         $this->_parseError();
                                         $this->_HTML_RECONSUME_IN(static::DataState);
                                     } else {
                                         if ($char === '<' || $char === '=' || $char === '`') {
                                             $this->_parseError();
                                         }
                                         $this->_Token->beginAttributeValue($source->numberOfCharactersConsumed());
                                         $this->_Token->appendToAttributeValue($char);
                                         $this->_HTML_ADVANCE_TO(static::AttributeValueUnquotedState);
                                     }
                                 }
                             }
                         }
                     }
                 }
                 break;
             case static::AttributeValueDoubleQuotedState:
                 if ($char === '"') {
                     $this->_Token->setDoubleQuoted();
                     $this->_Token->endAttributeValue($source->numberOfCharactersConsumed());
                     $this->_HTML_ADVANCE_TO(static::AfterAttributeValueQuotedState);
                 } else {
                     if ($char === '&') {
                         $this->_additionalAllowedCharacter = '"';
                         $this->_HTML_ADVANCE_TO(static::CharacterReferenceInAttributeValueState);
                     } else {
                         if ($char === static::kEndOfFileMarker) {
                             $this->_parseError();
                             $this->_Token->endAttributeValue($source->numberOfCharactersConsumed());
                             $this->_HTML_RECONSUME_IN(static::DataState);
                         } else {
                             $this->_Token->appendToAttributeValue($char);
                             $this->_HTML_ADVANCE_TO(static::AttributeValueDoubleQuotedState);
                         }
                     }
                 }
                 break;
             case static::AttributeValueSingleQuotedState:
                 if ($char === '\'') {
                     $this->_Token->setSingleQuoted();
                     $this->_Token->endAttributeValue($source->numberOfCharactersConsumed());
                     $this->_HTML_ADVANCE_TO(static::AfterAttributeValueQuotedState);
                 } else {
                     if ($char === '&') {
                         $this->_additionalAllowedCharacter = '\'';
                         $this->_HTML_ADVANCE_TO(static::CharacterReferenceInAttributeValueState);
                     } else {
                         if ($char === static::kEndOfFileMarker) {
                             $this->_parseError();
                             $this->_Token->endAttributeValue($source->numberOfCharactersConsumed());
                             $this->_HTML_RECONSUME_IN(static::DataState);
                         } else {
                             $this->_Token->appendToAttributeValue($char);
                             $this->_HTML_ADVANCE_TO(static::AttributeValueSingleQuotedState);
                         }
                     }
                 }
                 break;
             case static::AttributeValueUnquotedState:
                 if ($this->_isTokenizerWhitespace($char)) {
                     $this->_Token->endAttributeValue($source->numberOfCharactersConsumed());
                     $this->_HTML_ADVANCE_TO(static::BeforeAttributeNameState);
                 } else {
                     if ($char === '&') {
                         $this->_additionalAllowedCharacter = '>';
                         $this->_HTML_ADVANCE_TO(static::CharacterReferenceInAttributeValueState);
                     } else {
                         if ($char === '>') {
                             $this->_Token->endAttributeValue($source->numberOfCharactersConsumed());
                             return $this->_emitAndResumeIn();
                         } else {
                             if ($char === static::kEndOfFileMarker) {
                                 $this->_parseError();
                                 $this->_Token->endAttributeValue($source->numberOfCharactersConsumed());
                                 $this->_HTML_RECONSUME_IN(static::DataState);
                             } else {
                                 if ($char === '"' || $char === '\'' || $char === '<' || $char === '=' || $char === '`') {
                                     $this->_parseError();
                                 }
                                 $this->_Token->appendToAttributeValue($char);
                                 $this->_HTML_ADVANCE_TO(static::AttributeValueUnquotedState);
                             }
                         }
                     }
                 }
                 break;
             case static::CharacterReferenceInAttributeValueState:
                 // TODO Do not expand the reference, so skip parse Character references.
                 $this->_Token->appendToAttributeValue('&');
                 // We're supposed to switch back to the attribute value state that
                 // we were in when we were switched into this state. Rather than
                 // keeping track of this explictly, we observe that the previous
                 // state can be determined by $this->_additionalAllowedCharacter.
                 if ($this->_additionalAllowedCharacter === '"') {
                     $this->_HTML_SWITCH_TO(static::AttributeValueDoubleQuotedState);
                 } else {
                     if ($this->_additionalAllowedCharacter === '\'') {
                         $this->_HTML_SWITCH_TO(static::AttributeValueSingleQuotedState);
                     } else {
                         if ($this->_additionalAllowedCharacter === '>') {
                             $this->_HTML_SWITCH_TO(static::AttributeValueUnquotedState);
                         } else {
                             // ASSERT_NOT_REACHED();
                         }
                     }
                 }
                 break;
             case static::AfterAttributeValueQuotedState:
                 if ($this->_isTokenizerWhitespace($char)) {
                     $this->_HTML_ADVANCE_TO(static::BeforeAttributeNameState);
                 } else {
                     if ($char === '/') {
                         $this->_HTML_ADVANCE_TO(static::SelfClosingStartTagState);
                     } else {
                         if ($char === '>') {
                             return $this->_emitAndResumeIn();
                         } else {
                             if ($char === static::kEndOfFileMarker) {
                                 $this->_parseError();
                                 $this->_HTML_RECONSUME_IN(static::DataState);
                             } else {
                                 $this->_parseError();
                                 $this->_HTML_RECONSUME_IN(static::BeforeAttributeNameState);
                             }
                         }
                     }
                 }
                 break;
             case static::SelfClosingStartTagState:
                 if ($char === '>') {
                     $this->_Token->setSelfClosing();
                     return $this->_emitAndResumeIn();
                 } else {
                     if ($char === static::kEndOfFileMarker) {
                         $this->_parseError();
                         $this->_HTML_RECONSUME_IN(static::DataState);
                     } else {
                         $this->_parseError();
                         $this->_HTML_RECONSUME_IN(static::BeforeAttributeNameState);
                     }
                 }
                 break;
             case static::BogusCommentState:
                 $this->_Token->beginComment();
                 $this->_HTML_RECONSUME_IN(static::ContinueBogusCommentState);
                 break;
             case static::ContinueBogusCommentState:
                 if ($char === '>') {
                     return $this->_emitAndResumeIn();
                 } else {
                     if ($char === static::kEndOfFileMarker) {
                         return $this->_emitAndReconsumeIn($source, HTMLTokenizer::DataState);
                     } else {
                         $this->_Token->appendToComment($char);
                         $this->_HTML_ADVANCE_TO(static::ContinueBogusCommentState);
                     }
                 }
                 break;
             case static::MarkupDeclarationOpenState:
                 $dashDashString = '--';
                 $doctypeString = 'doctype';
                 $cdataString = '[CDATA[';
                 if ($char === '-') {
                     $result = $source->lookAhead($dashDashString);
                     if ($result === SegmentedString::DidMatch) {
                         $this->addState();
                         $this->_SegmentedString->read(strlen('--'));
                         $this->_Token->beginComment();
                         $this->_HTML_SWITCH_TO(static::CommentStartState);
                         continue;
                     } else {
                         if ($result === SegmentedString::NotEnoughCharacters) {
                             $this->addState();
                             return $this->_haveBufferedCharacterToken();
                         }
                     }
                 } else {
                     if ($char === 'D' || $char === 'd') {
                         $result = $this->_SegmentedString->lookAheadIgnoringCase($doctypeString);
                         if ($result === SegmentedString::DidMatch) {
                             $this->addState();
                             $this->_SegmentedString->read(strlen($doctypeString));
                             $this->_HTML_SWITCH_TO(static::DOCTYPEState);
                             continue;
                         } else {
                             if ($result === SegmentedString::NotEnoughCharacters) {
                                 $this->addState();
                                 return $this->_haveBufferedCharacterToken();
                             }
                         }
                     } else {
                         if ($char === '[' && $this->_shouldAllowCDATA()) {
                             $result = $source->lookAhead($cdataString);
                             if ($result === SegmentedString::DidMatch) {
                                 $this->addState();
                                 $this->_SegmentedString->read(strlen($cdataString));
                                 $this->_HTML_SWITCH_TO(static::CDATASectionState);
                                 continue;
                             } else {
                                 if ($result === SegmentedString::NotEnoughCharacters) {
                                     $this->addState();
                                     return $this->_haveBufferedCharacterToken();
                                 }
                             }
                         }
                     }
                 }
                 $this->_parseError();
                 $this->_HTML_RECONSUME_IN(static::BogusCommentState);
                 break;
             case static::CommentStartState:
                 if ($char === '-') {
                     $this->_HTML_ADVANCE_TO(static::CommentStartDashState);
                 } else {
                     if ($char === '>') {
                         $this->_parseError();
                         return $this->_emitAndResumeIn();
                     } else {
                         if ($char === static::kEndOfFileMarker) {
                             $this->_parseError();
                             return $this->_emitAndReconsumeIn($source, HTMLTokenizer::DataState);
                         } else {
                             $this->_Token->appendToComment($char);
                             $this->_HTML_ADVANCE_TO(static::CommentState);
                         }
                     }
                 }
                 break;
             case static::CommentStartDashState:
                 if ($char === '-') {
                     $this->_HTML_ADVANCE_TO(static::CommentEndState);
                 } else {
                     if ($char === '>') {
                         $this->_parseError();
                         return $this->_emitAndResumeIn();
                     } else {
                         if ($char === static::kEndOfFileMarker) {
                             $this->_parseError();
                             return $this->_emitAndReconsumeIn($source, HTMLTokenizer::DataState);
                         } else {
                             $this->_Token->appendToComment('-');
                             $this->_Token->appendToComment($char);
                             $this->_HTML_ADVANCE_TO(static::CommentState);
                         }
                     }
                 }
                 break;
             case static::CommentState:
                 if ($char === '-') {
                     $this->_HTML_ADVANCE_TO(static::CommentEndDashState);
                 } else {
                     if ($char === static::kEndOfFileMarker) {
                         $this->_parseError();
                         return $this->_emitAndReconsumeIn($source, HTMLTokenizer::DataState);
                     } else {
                         $this->_Token->appendToComment($char);
                         $this->_HTML_ADVANCE_TO(static::CommentState);
                     }
                 }
                 break;
             case static::CommentEndDashState:
                 if ($char === '-') {
                     $this->_HTML_ADVANCE_TO(static::CommentEndState);
                 } else {
                     if ($char === static::kEndOfFileMarker) {
                         $this->_parseError();
                         return $this->_emitAndReconsumeIn($source, HTMLTokenizer::DataState);
                     } else {
                         $this->_Token->appendToComment('-');
                         $this->_Token->appendToComment($char);
                         $this->_HTML_ADVANCE_TO(static::CommentState);
                     }
                 }
                 break;
             case static::CommentEndState:
                 if ($char === '>') {
                     return $this->_emitAndResumeIn();
                 } else {
                     if ($char === '!') {
                         $this->_parseError();
                         $this->_HTML_ADVANCE_TO(static::CommentEndBangState);
                     } else {
                         if ($char === '-') {
                             $this->_parseError();
                             $this->_Token->appendToComment('-');
                             $this->_HTML_ADVANCE_TO(static::CommentEndState);
                         } else {
                             if ($char === static::kEndOfFileMarker) {
                                 $this->_parseError(true);
                                 return $this->_emitAndReconsumeIn($source, HTMLTokenizer::DataState);
                             } else {
                                 $this->_parseError();
                                 $this->_Token->appendToComment('-');
                                 $this->_Token->appendToComment('-');
                                 $this->_Token->appendToComment($char);
                                 $this->_HTML_ADVANCE_TO(static::CommentState);
                             }
                         }
                     }
                 }
                 break;
             case static::CommentEndBangState:
                 if ($char === '-') {
                     $this->_Token->appendToComment('-');
                     $this->_Token->appendToComment('-');
                     $this->_Token->appendToComment('!');
                     $this->_HTML_ADVANCE_TO(static::CommentEndDashState);
                 } else {
                     if ($char === '>') {
                         return $this->_emitAndResumeIn();
                     } else {
                         if ($char === static::kEndOfFileMarker) {
                             $this->_parseError(true);
                             return $this->_emitAndReconsumeIn($source, HTMLTokenizer::DataState);
                         } else {
                             $this->_Token->appendToComment('-');
                             $this->_Token->appendToComment('-');
                             $this->_Token->appendToComment('!');
                             $this->_Token->appendToComment($char);
                             $this->_HTML_ADVANCE_TO(static::CommentState);
                         }
                     }
                 }
                 break;
             case static::DOCTYPEState:
                 if ($this->_isTokenizerWhitespace($char)) {
                     $this->_HTML_ADVANCE_TO(static::BeforeDOCTYPENameState);
                 } else {
                     if ($char === static::kEndOfFileMarker) {
                         $this->_parseError();
                         $this->_Token->beginDOCTYPE();
                         $this->_Token->setForceQuirks();
                         return $this->_emitAndReconsumeIn($source, HTMLTokenizer::DataState);
                     } else {
                         $this->_parseError();
                         $this->_HTML_RECONSUME_IN(static::BeforeDOCTYPENameState);
                     }
                 }
                 break;
             case static::BeforeDOCTYPENameState:
                 if ($this->_isTokenizerWhitespace($char)) {
                     $this->_HTML_ADVANCE_TO(static::BeforeDOCTYPENameState);
                 } else {
                     if (ctype_upper($char)) {
                         $this->_Token->beginDOCTYPE(strtolower($char));
                         $this->_HTML_ADVANCE_TO(static::DOCTYPENameState);
                     } else {
                         if ($char === '>') {
                             $this->_parseError();
                             $this->_Token->beginDOCTYPE();
                             $this->_Token->setForceQuirks();
                             return $this->_emitAndResumeIn();
                         } else {
                             if ($char === static::kEndOfFileMarker) {
                                 $this->_parseError(true);
                                 $this->_Token->beginDOCTYPE();
                                 $this->_Token->setForceQuirks();
                                 return $this->_emitAndReconsumeIn($source, HTMLTokenizer::DataState);
                             } else {
                                 $this->_Token->beginDOCTYPE($char);
                                 $this->_HTML_ADVANCE_TO(static::DOCTYPENameState);
                             }
                         }
                     }
                 }
                 break;
             case static::DOCTYPENameState:
                 if ($this->_isTokenizerWhitespace($char)) {
                     $this->_HTML_ADVANCE_TO(static::AfterDOCTYPENameState);
                 } else {
                     if ($char === '>') {
                         return $this->_emitAndResumeIn();
                     } else {
                         if (ctype_upper($char)) {
                             $this->_Token->appendToName(strtolower($char));
                             $this->_HTML_ADVANCE_TO(static::DOCTYPENameState);
                         } else {
                             if ($char === static::kEndOfFileMarker) {
                                 $this->_parseError(true);
                                 $this->_Token->setForceQuirks();
                                 return $this->_emitAndReconsumeIn($source, HTMLTokenizer::DataState);
                             } else {
                                 $this->_Token->appendToName($char);
                                 $this->_HTML_ADVANCE_TO(static::DOCTYPENameState);
                             }
                         }
                     }
                 }
                 break;
             case static::AfterDOCTYPENameState:
                 if ($this->_isTokenizerWhitespace($char)) {
                     $this->_HTML_ADVANCE_TO(static::AfterDOCTYPENameState);
                 } else {
                     if ($char === '>') {
                         return $this->_emitAndResumeIn();
                     } else {
                         if ($char === static::kEndOfFileMarker) {
                             $this->_parseError(true);
                             $this->_Token->setForceQuirks();
                             return $this->_emitAndReconsumeIn($source, HTMLTokenizer::DataState);
                         } else {
                             // DEFINE_STATIC_LOCAL(String, publicString, (ASCIILiteral("public")));
                             $publicString = 'public';
                             // DEFINE_STATIC_LOCAL(String, systemString, (ASCIILiteral("system")));
                             $systemString = 'system';
                             if ($char === 'P' || $char === 'p') {
                                 $result = $source->lookAheadIgnoringCase($publicString);
                                 if ($result === SegmentedString::DidMatch) {
                                     $this->addState();
                                     $this->_HTML_SWITCH_TO(static::AfterDOCTYPEPublicKeywordState);
                                     $this->_SegmentedString->read(strlen($publicString));
                                     continue;
                                 }
                                 // @todo
                                 //  else if ($result === SegmentedString::NotEnoughCharacters) {
                                 //  $this->addState();
                                 //  return $this->_haveBufferedCharacterToken();
                                 //  }
                             } else {
                                 if ($char === 'S' || $char === 's') {
                                     $result = $source->lookAheadIgnoringCase($systemString);
                                     if ($result === SegmentedString::DidMatch) {
                                         $this->addState();
                                         $this->_HTML_SWITCH_TO(static::AfterDOCTYPESystemKeywordState);
                                         $this->_SegmentedString->read(strlen($systemString));
                                         continue;
                                     }
                                     // @todo
                                     // else if ($result === SegmentedString::NotEnoughCharacters) {
                                     // $this->addState();
                                     // return $this->_haveBufferedCharacterToken();
                                     // }
                                 }
                             }
                             $this->_parseError();
                             $this->_Token->setForceQuirks();
                             $this->_HTML_ADVANCE_TO(static::BogusDOCTYPEState);
                         }
                     }
                 }
                 break;
             case static::AfterDOCTYPEPublicKeywordState:
                 if ($this->_isTokenizerWhitespace($char)) {
                     $this->_HTML_ADVANCE_TO(static::BeforeDOCTYPEPublicIdentifierState);
                 } else {
                     if ($char === '"') {
                         $this->_parseError();
                         $this->_Token->setPublicIdentifierToEmptyString();
                         $this->_HTML_ADVANCE_TO(static::DOCTYPEPublicIdentifierDoubleQuotedState);
                     } else {
                         if ($char === '\'') {
                             $this->_parseError();
                             $this->_Token->setPublicIdentifierToEmptyString();
                             $this->_HTML_ADVANCE_TO(static::DOCTYPEPublicIdentifierSingleQuotedState);
                         } else {
                             if ($char === '>') {
                                 $this->_parseError();
                                 $this->_Token->setForceQuirks();
                                 return $this->_emitAndResumeIn();
                             } else {
                                 if ($char === static::kEndOfFileMarker) {
                                     $this->_parseError(true);
                                     $this->_Token->setForceQuirks();
                                     return $this->_emitAndReconsumeIn($source, HTMLTokenizer::DataState);
                                 } else {
                                     $this->_parseError();
                                     $this->_Token->setForceQuirks();
                                     $this->_HTML_ADVANCE_TO(static::BogusDOCTYPEState);
                                 }
                             }
                         }
                     }
                 }
                 break;
             case static::BeforeDOCTYPEPublicIdentifierState:
                 if ($this->_isTokenizerWhitespace($char)) {
                     $this->_HTML_ADVANCE_TO(static::BeforeDOCTYPEPublicIdentifierState);
                 } else {
                     if ($char === '"') {
                         $this->_Token->setPublicIdentifierToEmptyString();
                         $this->_HTML_ADVANCE_TO(static::DOCTYPEPublicIdentifierDoubleQuotedState);
                     } else {
                         if ($char === '\'') {
                             $this->_Token->setPublicIdentifierToEmptyString();
                             $this->_HTML_ADVANCE_TO(static::DOCTYPEPublicIdentifierSingleQuotedState);
                         } else {
                             if ($char === '>') {
                                 $this->_parseError();
                                 $this->_Token->setForceQuirks();
                                 return $this->_emitAndResumeIn();
                             } else {
                                 if ($char === static::kEndOfFileMarker) {
                                     $this->_parseError(true);
                                     $this->_Token->setForceQuirks();
                                     return $this->_emitAndReconsumeIn($source, HTMLTokenizer::DataState);
                                 } else {
                                     $this->_parseError();
                                     $this->_Token->setForceQuirks();
                                     $this->_HTML_ADVANCE_TO(static::BogusDOCTYPEState);
                                 }
                             }
                         }
                     }
                 }
                 break;
             case static::DOCTYPEPublicIdentifierDoubleQuotedState:
                 if ($char === '"') {
                     $this->_HTML_ADVANCE_TO(static::AfterDOCTYPEPublicIdentifierState);
                 } else {
                     if ($char === '>') {
                         $this->_parseError();
                         $this->_Token->setForceQuirks();
                         return $this->_emitAndResumeIn();
                     } else {
                         if ($char === static::kEndOfFileMarker) {
                             $this->_parseError();
                             $this->_Token->setForceQuirks();
                             return $this->_emitAndReconsumeIn($source, HTMLTokenizer::DataState);
                         } else {
                             $this->_Token->appendToPublicIdentifier($char);
                             $this->_HTML_ADVANCE_TO(static::DOCTYPEPublicIdentifierDoubleQuotedState);
                         }
                     }
                 }
                 break;
             case static::DOCTYPEPublicIdentifierSingleQuotedState:
                 if ($char === '\'') {
                     $this->_HTML_ADVANCE_TO(static::AfterDOCTYPEPublicIdentifierState);
                 } else {
                     if ($char === '>') {
                         $this->_parseError();
                         $this->_Token->setForceQuirks();
                         return $this->_emitAndResumeIn();
                     } else {
                         if ($char === static::kEndOfFileMarker) {
                             $this->_parseError();
                             $this->_Token->setForceQuirks();
                             return $this->_emitAndReconsumeIn($source, HTMLTokenizer::DataState);
                         } else {
                             $this->_Token->appendToPublicIdentifier($char);
                             $this->_HTML_ADVANCE_TO(static::DOCTYPEPublicIdentifierSingleQuotedState);
                         }
                     }
                 }
                 break;
             case static::AfterDOCTYPEPublicIdentifierState:
                 if ($this->_isTokenizerWhitespace($char)) {
                     $this->_HTML_ADVANCE_TO(static::BetweenDOCTYPEPublicAndSystemIdentifiersState);
                 } else {
                     if ($char === '>') {
                         return $this->_emitAndResumeIn();
                     } else {
                         if ($char === '"') {
                             $this->_parseError();
                             $this->_Token->setSystemIdentifierToEmptyString();
                             $this->_HTML_ADVANCE_TO(static::DOCTYPESystemIdentifierDoubleQuotedState);
                         } else {
                             if ($char === '\'') {
                                 $this->_parseError();
                                 $this->_Token->setSystemIdentifierToEmptyString();
                                 $this->_HTML_ADVANCE_TO(static::DOCTYPESystemIdentifierSingleQuotedState);
                             } else {
                                 if ($char === static::kEndOfFileMarker) {
                                     $this->_parseError();
                                     $this->_Token->setForceQuirks();
                                     return $this->_emitAndReconsumeIn($source, HTMLTokenizer::DataState);
                                 } else {
                                     $this->_parseError();
                                     $this->_Token->setForceQuirks();
                                     $this->_HTML_ADVANCE_TO(static::BogusDOCTYPEState);
                                 }
                             }
                         }
                     }
                 }
                 break;
             case static::BetweenDOCTYPEPublicAndSystemIdentifiersState:
                 if ($this->_isTokenizerWhitespace($char)) {
                     $this->_HTML_ADVANCE_TO(static::BetweenDOCTYPEPublicAndSystemIdentifiersState);
                 } else {
                     if ($char === '>') {
                         return $this->_emitAndResumeIn();
                     } else {
                         if ($char === '"') {
                             $this->_Token->setSystemIdentifierToEmptyString();
                             $this->_HTML_ADVANCE_TO(static::DOCTYPESystemIdentifierDoubleQuotedState);
                         } else {
                             if ($char === '\'') {
                                 $this->_Token->setSystemIdentifierToEmptyString();
                                 $this->_HTML_ADVANCE_TO(static::DOCTYPESystemIdentifierSingleQuotedState);
                             } else {
                                 if ($char === static::kEndOfFileMarker) {
                                     $this->_parseError();
                                     $this->_Token->setForceQuirks();
                                     return $this->_emitAndReconsumeIn($source, HTMLTokenizer::DataState);
                                 } else {
                                     $this->_parseError();
                                     $this->_Token->setForceQuirks();
                                     $this->_HTML_ADVANCE_TO(static::BogusDOCTYPEState);
                                 }
                             }
                         }
                     }
                 }
                 break;
             case static::AfterDOCTYPESystemKeywordState:
                 if ($this->_isTokenizerWhitespace($char)) {
                     $this->_HTML_ADVANCE_TO(static::BeforeDOCTYPESystemIdentifierState);
                 } else {
                     if ($char === '"') {
                         $this->_parseError();
                         $this->_Token->setSystemIdentifierToEmptyString();
                         $this->_HTML_ADVANCE_TO(static::DOCTYPESystemIdentifierDoubleQuotedState);
                     } else {
                         if ($char === '\'') {
                             $this->_parseError();
                             $this->_Token->setSystemIdentifierToEmptyString();
                             $this->_HTML_ADVANCE_TO(static::DOCTYPESystemIdentifierSingleQuotedState);
                         } else {
                             if ($char === '>') {
                                 $this->_parseError();
                                 $this->_Token->setForceQuirks();
                                 return $this->_emitAndResumeIn();
                             } else {
                                 if ($char === static::kEndOfFileMarker) {
                                     $this->_parseError();
                                     $this->_Token->setForceQuirks();
                                     return $this->_emitAndReconsumeIn($source, HTMLTokenizer::DataState);
                                 } else {
                                     $this->_parseError();
                                     $this->_Token->setForceQuirks();
                                     $this->_HTML_ADVANCE_TO(static::BogusDOCTYPEState);
                                 }
                             }
                         }
                     }
                 }
                 break;
             case static::BeforeDOCTYPESystemIdentifierState:
                 if ($this->_isTokenizerWhitespace($char)) {
                     $this->_HTML_ADVANCE_TO(static::BeforeDOCTYPESystemIdentifierState);
                     continue;
                 }
                 if ($char === '"') {
                     $this->_Token->setSystemIdentifierToEmptyString();
                     $this->_HTML_ADVANCE_TO(static::DOCTYPESystemIdentifierDoubleQuotedState);
                 } else {
                     if ($char === '\'') {
                         $this->_Token->setSystemIdentifierToEmptyString();
                         $this->_HTML_ADVANCE_TO(static::DOCTYPESystemIdentifierSingleQuotedState);
                     } else {
                         if ($char === '>') {
                             $this->_parseError();
                             $this->_Token->setForceQuirks();
                             return $this->_emitAndResumeIn();
                         } else {
                             if ($char === static::kEndOfFileMarker) {
                                 $this->_parseError();
                                 $this->_Token->setForceQuirks();
                                 return $this->_emitAndReconsumeIn($source, HTMLTokenizer::DataState);
                             } else {
                                 $this->_parseError();
                                 $this->_Token->setForceQuirks();
                                 $this->_HTML_ADVANCE_TO(static::BogusDOCTYPEState);
                             }
                         }
                     }
                 }
                 break;
             case static::DOCTYPESystemIdentifierDoubleQuotedState:
                 if ($char === '"') {
                     $this->_HTML_ADVANCE_TO(static::AfterDOCTYPESystemIdentifierState);
                 } else {
                     if ($char === '>') {
                         $this->_parseError();
                         $this->_Token->setForceQuirks();
                         return $this->_emitAndResumeIn();
                     } else {
                         if ($char === static::kEndOfFileMarker) {
                             $this->_parseError();
                             $this->_Token->setForceQuirks();
                             return $this->_emitAndReconsumeIn($source, HTMLTokenizer::DataState);
                         } else {
                             $this->_Token->appendToSystemIdentifier($char);
                             $this->_HTML_ADVANCE_TO(static::DOCTYPESystemIdentifierDoubleQuotedState);
                         }
                     }
                 }
                 break;
             case static::DOCTYPESystemIdentifierSingleQuotedState:
                 if ($char === '\'') {
                     $this->_HTML_ADVANCE_TO(static::AfterDOCTYPESystemIdentifierState);
                 } else {
                     if ($char === '>') {
                         $this->_parseError();
                         $this->_Token->setForceQuirks();
                         return $this->_emitAndResumeIn();
                     } else {
                         if ($char === static::kEndOfFileMarker) {
                             $this->_parseError();
                             $this->_Token->setForceQuirks();
                             return $this->_emitAndReconsumeIn($source, HTMLTokenizer::DataState);
                         } else {
                             $this->_Token->appendToSystemIdentifier($char);
                             $this->_HTML_ADVANCE_TO(static::DOCTYPESystemIdentifierSingleQuotedState);
                         }
                     }
                 }
                 break;
             case static::AfterDOCTYPESystemIdentifierState:
                 if ($this->_isTokenizerWhitespace($char)) {
                     $this->_HTML_ADVANCE_TO(static::AfterDOCTYPESystemIdentifierState);
                 } else {
                     if ($char === '>') {
                         return $this->_emitAndResumeIn();
                     } else {
                         if ($char === static::kEndOfFileMarker) {
                             $this->_parseError();
                             $this->_Token->setForceQuirks();
                             return $this->_emitAndReconsumeIn($source, HTMLTokenizer::DataState);
                         } else {
                             $this->_parseError();
                             $this->_HTML_ADVANCE_TO(static::BogusDOCTYPEState);
                         }
                     }
                 }
                 break;
             case static::BogusDOCTYPEState:
                 if ($char === '>') {
                     return $this->_emitAndResumeIn();
                 } else {
                     if ($char === static::kEndOfFileMarker) {
                         return $this->_emitAndReconsumeIn($source, HTMLTokenizer::DataState);
                     }
                 }
                 $this->_HTML_ADVANCE_TO(static::BogusDOCTYPEState);
                 break;
             case static::CDATASectionState:
                 if ($char === ']') {
                     $this->_HTML_ADVANCE_TO(static::CDATASectionRightSquareBracketState);
                 } else {
                     if ($char === static::kEndOfFileMarker) {
                         $this->_HTML_RECONSUME_IN(static::DataState);
                     } else {
                         $this->_bufferCharacter($char);
                         $this->_HTML_ADVANCE_TO(static::CDATASectionState);
                     }
                 }
                 break;
             case static::CDATASectionRightSquareBracketState:
                 if ($char === ']') {
                     $this->_HTML_ADVANCE_TO(static::CDATASectionDoubleRightSquareBracketState);
                 } else {
                     $this->_bufferCharacter(']');
                     $this->_HTML_RECONSUME_IN(static::CDATASectionState);
                 }
                 break;
             case static::CDATASectionDoubleRightSquareBracketState:
                 if ($char === '>') {
                     $this->_HTML_ADVANCE_TO(static::DataState);
                 } else {
                     $this->_bufferCharacter(']');
                     $this->_bufferCharacter(']');
                     $this->_HTML_RECONSUME_IN(static::CDATASectionState);
                 }
                 break;
             default:
                 break 2;
         }
     }
     // ASSERT_NOT_REACHED
     return false;
 }