# definitions - wired into processor
# $S, $NameStart, $NameC, $Hex - per XML spec

# State Statename Fallbackstate {errormessage}

# Start
State Start InProlog {in prolog}
T < LTatStart !MarkLt
T $S InProlog

State LTatStart BustedProlog {}
T ? Push(TryXMLD,InProlog) !ColdStart
T ! MDOinProlog
T $NameStart StagGI !HotStart

State BustedProlog InProlog {}
T > InProlog
T $. BustedProlog

State InProlog BustedProlog {}
T < LTinProlog !MarkLt
T $S InProlog

State AfterDTD AfterDTD {after DTD}
T < LTafterDTD !MarkLt
T $S AfterDTD

# saw < in prolog
State LTinProlog LTinProlog {after <}
T ? Push(InPI,InProlog) !ColdStart
T ! MDOinProlog
T $NameStart StagGI !HotStart

# saw < after DTD in prolog
State LTafterDTD AfterDTD {}
T ? Push(InPI,AfterDTD) !ColdStart
T ! MDOafterDTD
T $NameStart StagGI !HotStart

# saw < in doc
State SawLT BustedMarkup {}
T ? Push(InPI,InDoc) !ColdStart
T ! MDO
T / ETAGO
T $NameStart StagGI !HotStart

# saw < in internal subset
State LTInSubset BustedDecl {}
T ! MDOInSubset
T ? Push(InPI,InSubset) !ColdStart

# saw <!
State MDOinProlog BustedMarkup {after <!}
T - Push(PComStart,InProlog)
T D Keyword(DOCTYPE,InDoctype,1)

State MDOafterDTD AfterDTD {}
T - Push(PComStart,AfterDTD)

# saw <!
State MDO BustedMarkup {}
T - Push(COMStartHalf,InDoc)
T [ StartCData1

# <! in internal subset
State MDOInSubset BustedDecl {after <!}
T N Keyword(NOTATION,NDecAfterKW,1)
T E EDec1
T A Keyword(ATTLIST,EndAttlKW,1)
T - ComInSub1
T [ MSect1

# Special state for matching keywords... 
State Keyword Start {}
T $. Keyword !InKW

# after <?
State InPI BustedMarkup {in PI}
T $NameStart PI2
State PI2  BustedMarkup {}
T $NameC PI2
T $S PI3 !EndSave
T ? PICMustHaveGT !EndSave
State PI3 BustedMarkup {}
T $S PI3
T $. PI4 !HotStart
T ? PICwantsGT !HotStart
State PI4 BustedMarkup {}
T ? PICwantsGT
T $. PI4

# require > in PIC
State PICMustHaveGT BustedMarkup {}
T > Pop() !ReportPI

# want > in PIC 
State PICwantsGT BustedMarkup {}
T > Pop() !ReportPI
T ? PICwantsGT
T $. PI4

# saw <!- 
State COMStartHalf BustedMarkup {after <!-}
T - InComment

# Comment in prolog; only difference is we don't start saving after
State PComStart BustedMarkup {}
T - InPComment

State ComInSub1 BustedDecl {after <!-}
T - InSubsetCom

# base comment body
State InComment InComment {in comment}
T - DashInComment
T $. InComment

# base comment body
State InPComment InComment {}
T - DashInPComment
T $. InPComment

# saw - in comment
State DashInComment InComment {}
T - DDInComment
T $. InComment

# saw - in comment
State DashInPComment InComment {}
T - DDInPComment
T $. InPComment

# saw -- in comment
State DDInComment InComment {}
T > Pop() !ColdStart

# saw -- in comment
State DDInPComment InComment {}
T > Pop()

State InSubsetCom BustedDecl {}
T - DashInSubsetCom
T $. InSubsetCom

State DashInSubsetCom InSubsetCom {}
T - DoubleDashInSubsetCom
T $. InSubsetCom

State DoubleDashInSubsetCom InSubsetCom {}
T > InSubset

# saw <![
State StartCData1 InCData {in <![CDATA[}
T C Keyword(CDATA,AfterCdataKW,1)
State AfterCdataKW InCData {}
T [ InCData !ColdStart

# in CDATA section
State InCData BustedMarkup {}
T ] EndCData1 !ReportText
T $. InCData

# ] in CDATA
State EndCData1 BustedMarkup {}
T ] EndCData2
T $. InCData !SaveExtra(])

# ]] in CDATA
State EndCData2 BustedMarkup {}
T ] EndCData2 !SaveExtra(]) !ReportText
T > InDoc !ReportText !ColdStart
T $. InCData !SaveExtra(]])

# after <!doctype
State InDoctype InDoctype {after <!DOCTYPE}
T $NameStart Push(GIGrabber,SawDTName) !HotStart
T $S InDoctype

# General state for grabbing a space-ended GI, saving it, and popping
State GIGrabber InDoctype {}
T $NameC GIGrabber
T $S Pop() !EndGI

# after doctype name
State SawDTName SawDTName {after DOCTYPE Name}
T S Push(System1,SawDTypeExternalID)
T P Push(Public1,SawDTypeExternalID)
T [ InSubset !ReportDoctype
T > AfterDTD
T $S SawDTName

# <!doctype foo p
State Public1 SawPublic {in PUBLIC}
T U Keyword(PUBLIC,AfterPublicKW,2)
State AfterPublicKW SawPublic {after PUBLIC}
T $S SawPublic

State SawPublic BustedDecl {}
T % Push(PERef,SawPublic) !MarkPC !ColdStart
T ' Push(SQPublic,AfterPublic) !ColdStart
T " Push(DQPublic,AfterPublic) !ColdStart
T $S SawPublic

State SQPublic BustedDecl {in PUBLIC ID}
T ' Pop() !EndSave
T $PubID SQPublic

State DQPublic BustedDecl {}
T " Pop() !EndSave
T $PubID DQPublic

State AfterPublic BustedDecl {after PUBLIC ID}
T $S SawPubID

State SawPubID InDoctype {}
T $S SawPubID
T % Push(PERef,SawPubID) !MarkPC !ColdStart
T ' Push(SQCData,SawSystemID) !ColdStart
T " Push(DQCData,SawSystemID) !ColdStart

State SawSystemID InDoctype {after SYSTEM ID}
T $. Pop() !StuffChar

# <!doctype foo S
State System1 SawSystem {in SYSTEM}
T Y Keyword(SYSTEM,AfterSystemKW,2)
State AfterSystemKW SawSystem {after SYSTEM}
T $S SawSystem

# <!doctype foo system 
State SawSystem BustedDecl {}
T % Push(PERef,SawSystem) !MarkPC !ColdStart
T ' Push(SQCData,SawSystemID) !ColdStart
T " Push(DQCData,SawSystemID) !ColdStart
T $S SawSystem

#
State SQCData BustedMarkup {}
T ' Pop() !EndSave
T $. SQCData

#
State DQCData BustedMarkup {}
T " Pop() !EndSave
T $. DQCData

# <!doctype foo system "whatever" 
State SawDTypeExternalID InDoctype {after SYSTEM ID}
T > AfterDTD !ReportDoctype
T [ InSubset !ReportDoctype
T $S SawDTypeExternalID

# saw [ for internal subset
State InSubset InSubset {in internal subset}
T < LTInSubset !MarkLt
T % Push(PERef,InSubset) !MarkPcAtTopLevel !ColdStart
T ] RSBInSubset
T $S InSubset

State RSBInSubset InSubset {}
T ] RSB2InSubset
T > AfterDTD
T $S AfterSubset
State RSB2InSubset InSubset {}
T > InSubset !LeaveMarkedSect

# in PE Ref
State PERef InSubset {in PE reference}
T $NameStart PERef2

State PERef2 InSubset {}
T $NameC PERef2
T ; Pop() !ReportReference

# After subset
State AfterSubset InDoc {after internal subset}
T > AfterDTD
T $S AfterSubset

# <!NOTATION
State NDecAfterKW BustedDecl {after <!NOTATION}
T $S NDecGotKW

# <!NOTATION, need name
State NDecGotKW BustedDecl {}
T $S NDecGotKW
T $NameStart NDecReadName !HotStart

# in <!NOTATION name
State NDecReadName BustedDecl {}
T $NameC NDecReadName
T $S NDecGotName !EndSave

# after name in <!NOTATION
State NDecGotName BustedDecl {}
T $S NDecGotName
T S Keyword(SYSTEM,NDecAfterSystem,1)
T P Keyword(PUBLIC,NDecAfterPublic,1)

# <!NOTATION whateever PUBLIC
State NDecAfterPublic BustedDecl {after PUBLIC}
T $S NDecGotPublic
State NDecGotPublic BustedDecl {}
T ' Push(SQPublic,NDecSawPubID) !ColdStart
T " Push(DQPublic,NDecSawPubID) !ColdStart
State NDecSawPubID BustedDecl {after PUBLIC ID}
T > InSubset !DeclareNotation
T $S NDecGotPubID
State NDecGotPubID BustedDecl {}
T > InSubset !DeclareNotation
T ' Push(SQCData,NDecSawSysID) !ColdStart
T " Push(DQCData,NDecSawSysID) !ColdStart

# <!NOTATION whatever SYSTEM
State NDecAfterSystem BustedDecl {after SYSTEM}
T $S NDecGotSystem !EndSave

State NDecGotSystem  BustedDecl {}
T ' Push(SQCData,NDecSawSysID) !ColdStart
T " Push(DQCData,NDecSawSysID) !ColdStart

State NDecSawSysID BustedDecl {after external ID}
T $S NDecAllDone
T > InSubset !DeclareNotation
State NDecAllDone BustedDecl {}
T > InSubset !DeclareNotation

# Trying for <![INCLUDE/IGNORE
State MSect1 BustedDecl {after <![}
T $S MSect1
T % Push(PERef,MSect1) !MarkPC !ColdStart
T I MSectI

State MSectI BustedDecl {after <[I}
T N Keyword(INCLUDE,MSectINCLUDE,2)
T G Keyword(IGNORE,MSectIGNORE,2)

State MSectINCLUDE BustedDecl {after <![INCLUDE}
T $S MSectINCLUDE
T [ InSubset !EnterIncludedMS

State MSectIGNORE BustedDecl {after <![IGNORE}
T $S MSectIGNORE
T [ InSubset !EnterIgnoredMS

State EndAttlKW BustedDecl {after <!ATTLIST}
T $S AfterAttlKW

# after <!attlist
State AfterAttlKW BustedDecl {}
T $S AfterAttlKW
T % Push(PERef,AfterAttlKW) !MarkPC !ColdStart
T $NameStart InAttlGI !HotStart

# in attlist GI
State InAttlGI BustedDecl {in element type in <!ATTLIST}
T $NameC InAttlGI
T $S InAttlist !EndGI
# T > InSubset !EndGI !ReportAttDecl !ReportAttlist

# Base Attlist state
State InAttlist BustedDecl {in <!ATTLIST}
T > InSubset !ReportAttlist
T % Push(PERef,InAttlist) !MarkPC !ColdStart
T $NameStart InAttName !HotStart
T $S InAttlist

# in attr name
State InAttName BustedDecl {in attribute name}
T $NameC InAttName
T $S AfterAttName !EndAttribute

# after attr name
#  We don't really care about the type, we'll just scoop it up as a string
State AfterAttName BustedDecl {after attribute name}
T ( StartTokenList !HotStart
T C Keyword(CDATA,AttrTypeCDATA,1) !HotStart
T E AttrTypeE !HotStart
T I AttrTypeI !HotStart
T N AttrTypeN !HotStart
T % Push(PERef,AfterAttName) !MarkPC !ColdStart
T $S AfterAttName

# Token list
State StartTokenList BustedDecl {in tokenized attribute value}
T % Push(PERef,StartTokenList) !MarkPC !ColdStart
T $S StartTokenList
T $NameC FirstToken

State FirstToken BustedDecl {}
T $NameC FirstToken
T $S AfterToken
T | BeforeToken
T ) AfterTokList !EndSave

State AfterToken BustedDecl {}
T % Push(PERef,AfterToken) !MarkPC !ColdStart
T $S AfterToken
T | BeforeToken
T ) AfterTokList !EndSave

State BeforeToken BustedDecl {}
T % Push(PERef,BeforeToken) !MarkPC !ColdStart
T $S BeforeToken
T $NameC InToken

State InToken BustedDecl {}
T $NameC InToken
T $S AfterToken
T | BeforeToken
T ) AfterTokList !EndSave

State AfterTokList BustedDecl {}
T $S AfterAttrType

State AttrTypeCDATA BustedDecl {after CDATA}
T $S AfterAttrType !EndSave

State AttrTypeE BustedDecl {in ENTIT(Y,IES)}
T N AttrTypeEn
State AttrTypeEn BustedDecl {}
T T AttrTypeEnt
State AttrTypeEnt BustedDecl {}
T I AttrTypeEnti
State AttrTypeEnti BustedDecl {}
T T AttrTypeEntit
State AttrTypeEntit BustedDecl {}
T I AttrTypeEntiti
T Y AttrTypeEntity
State AttrTypeEntity BustedDecl {}
T $S AfterAttrType !EndSave
State AttrTypeEntiti BustedDecl {}
T E AttrTypeEntitie
State AttrTypeEntitie BustedDecl {}
T S AttrTypeEntities
State AttrTypeEntities BustedDecl {}
T $S AfterAttrType !EndSave

State AttrTypeI BustedDecl {in ID(REF(S))}
T D AttrTypeId
State AttrTypeId BustedDecl {}
T $S AfterAttrType !EndSave
T R AttrTypeIdr
State AttrTypeIdr BustedDecl {}
T E AttrTypeIdre
State AttrTypeIdre BustedDecl {}
T F AttrTypeIdref
State AttrTypeIdref BustedDecl {}
T $S AfterAttrType !EndSave
T S AttrTypeIdrefs
State AttrTypeIdrefs BustedDecl {}
T $S AfterAttrType !EndSave

State AttrTypeN BustedDecl {in type keyword}
T O Keyword(NOTATION,AttrTypeNotation,2)
T M Keyword(NMTOKEN,AttrTypeNmtoken,2)

State AttrTypeNotation BustedDecl {after NOTATION}
T $S BeforeNotList

# notation list 
State BeforeNotList BustedDecl {}
T % Push(PERef,BeforeNotList) !MarkPC !ColdStart
T $S BeforeNotList
T ( StartNotList

State StartNotList BustedDecl {in NOTATION list}
T % Push(PERef,StartNotList) !MarkPC !ColdStart
T $S StartNotList
T $NameStart FirstNotName

State FirstNotName BustedDecl {}
T $NameC FirstNotName
T $S AfterNotName
T | BeforeNotName
T ) AfterAttrType !EndSave

State AfterNotName BustedDecl {}
T % Push(PERef,AfterNotName) !MarkPC !ColdStart
T $S AfterNotName
T | BeforeNotName
T ) AfterAttrType !EndSave

State BeforeNotName BustedDecl {}
T % Push(PERef,BeforeNotName) !MarkPC !ColdStart
T $S BeforeNotName
T $NameStart InNotName

State InNotName BustedDecl {}
T $NameC InNotName
T $S AfterNotName
T | BeforeNotName
T ) AfterAttrType !EndSave

State AttrTypeNmtoken BustedDecl {after NMTOKEN}
T $S AfterAttrType !EndSave
T S AttrTypeNmtokens
State AttrTypeNmtokens BustedDecl {}
T $S AfterAttrType !EndSave 

#after attrtype
# NB, may need ColdStart on '#' transition
State AfterAttrType BustedDecl {after attribute type}
T % Push(PERef,AfterAttrType) !MarkPC !ColdStart
T $S AfterAttrType
T # AttrDefHash !ColdStart
T " Push(DQADef,InAttlist) !ColdStart !EnterAttrVal
T ' Push(SQADef,InAttlist) !ColdStart !EnterAttrVal

State AttrDefHash BustedDecl {in attribute default}
T R Keyword(REQUIRED,AttrDefRequired,1)
T I Keyword(IMPLIED,AttrDefImplied,1)
T F Keyword(FIXED,AttrDefFixed,1)

# #required & #implied are static to us
State AttrDefRequired BustedDecl {after #REQUIRED}
T $S InAttlist !ReportDefKW !ReportAttDecl
T > InSubset !ReportDefKW !ReportAttDecl !ReportAttlist

State AttrDefImplied BustedDecl {after #IMPLIED}
T $S InAttlist !ReportDefKW !ReportAttDecl
T > InSubset !ReportDefKW !ReportAttDecl !ReportAttlist

State AttrDefFixed BustedDecl {after #FIXED}
T $S AfterFixed !ReportDefKW

State AfterFixed BustedDecl {}
T % Push(PERef,AfterFixed) !MarkPC !ColdStart
T $S AfterFixed
T ' Push(SQADef,InAttlist) !ColdStart !EnterAttrVal
T " Push(DQADef,InAttlist) !ColdStart !EnterAttrVal

# saw <!e in subset
State EDec1 BustedDecl {after <!E}
T N Keyword(ENTITY,AfterEntityKW,2)
T L Keyword(ELEMENT,AfterElementKW,2)

# DEBUG: 1st line for dumb processing, 2nd 2 for real element parsing
State AfterElementKW BustedDecl {after <!ELEMENT}
T $S InElDec

# After <!element 
State InElDec BustedDecl {}
T $S InElDec
T % Push(PERef,InElDec) !MarkPC !ColdStart
T $NameStart Push(GIGrabber,ElDecAfterGI) !HotStart

State ElDecAfterGI BustedDecl {after element type}
T $S ElDecAfterGI
T % Push(PERef,ElDecAfterGI) !MarkPC !ColdStart
T ( ElDecFirstPar
T E Keyword(EMPTY,AfterEMPTY,1)
T A Keyword(ANY,AfterANY,1)
#T ( Push(ElDecFirstPar,AfterDecl)

State AfterEMPTY BustedDecl {after EMPTY}
T $S AfterEMPTY
T > InSubset !DoEMPTY
State AfterANY  BustedDecl {after ANY}
T $S AfterANY
T > InSubset !DoANY

# <!ELEMENT (
State ElDecFirstPar BustedDecl {after <!ELEMENT (}
T $S ElDecFirstPar
T % Push(PERef,ElDecFirstPar) !MarkPC !ColdStart
T # Keyword(PCDATA,AfterPCDATA,0)
T ( Push(CPStart,AfterFirst) !StartCM !StartCP
T $NameC FirstType !HotStart !StartCM

# Done element content, might be a trailing repeat-count
State DoneElementContent BustedDecl {after element declaration}
T * ReallyDoneEC !MarkRep
T + ReallyDoneEC !MarkRep
T ? ReallyDoneEC !MarkRep
T $S ReallyDoneEC
T > InSubset

# Really done elmeent content, no repeat count
State ReallyDoneEC BustedDecl {}
T % Push(PERef,ReallyDoneEC) !MarkPC !ColdStart
T $S ReallyDoneEC
T > InSubset

# Saw ( of a (non-top-level) CP
State CPStart BustedMarkup {start of content particle}
T % Push(PERef,CPStart) !MarkPC !ColdStart
T ( Push(CPStart,AfterFirst) !StartCP
T $S CPStart
T $NameC FirstType !HotStart

# gather lead-off child type
State FirstType BustedDecl {}
T $NameC FirstType
T $S DoneFirst !EndGI
T * DoneFirst !EndGI !MarkRep
T ? DoneFirst !EndGI !MarkRep
T + DoneFirst !EndGI !MarkRep
T ) PopCP() !EndGI
T , SeqNeedNext !EndGI !MarkConnector
T | ChoiceNeedNext !EndGI !MarkConnector

# have seen first child () of content particle
State AfterFirst BustedMarkup {after first member of content particle}
T $S DoneFirst
T , SeqNeedNext !MarkConnector
T | ChoiceNeedNext !MarkConnector
T * DoneFirst !MarkRep
T + DoneFirst !MarkRep
T ? DoneFirst !MarkRep
T ) PopCP()

# finshed with first member of cp
State DoneFirst BustedMarkup {}
T % Push(PERef,DoneFirst) !MarkPC !ColdStart
T $S DoneFirst
T , SeqNeedNext !MarkConnector
T | ChoiceNeedNext !MarkConnector
T ) PopCP()

# after connector in a seq
State SeqNeedNext BustedMarkup {after ,}
T % Push(PERef,SeqNeedNext) !MarkPC !ColdStart
T $S SeqNeedNext
T $NameStart SeqType !HotStart
T ( Push(CPStart,AfterSeqMember) !StartCP

# child type in a sequence
State SeqType BustedMarkup {}
T $NameC SeqType
T $S DoneSeqMember !EndGI
T * DoneSeqMember !EndGI !MarkRep
T + DoneSeqMember !EndGI !MarkRep
T ? DoneSeqMember !EndGI !MarkRep
T ) PopCP() !EndGI
T , SeqNeedNext !EndGI

# after () child in a seq
State AfterSeqMember BustedMarkup {after )}
T $S DoneSeqMember
T , SeqNeedNext
T * DoneSeqMember !MarkRep
T ? DoneSeqMember !MarkRep
T + DoneSeqMember !MarkRep
T ) PopCP()

# all done with member of a seq
State DoneSeqMember BustedMarkup {after member of sequence}
T % Push(PERef,DoneSeqMember) !MarkPC !ColdStart
T $S DoneSeqMember
T , SeqNeedNext
T ) PopCP()

# after connector in a choice
State ChoiceNeedNext BustedMarkup {after |}
T % Push(PERef,ChoiceNeedNext) !MarkPC !ColdStart
T $S ChoiceNeedNext
T $NameStart ChoiceType !HotStart
T ( Push(CPStart,AfterChoiceMember) !StartCP

# child type in a choice
State ChoiceType BustedMarkup {}
T $NameC ChoiceType
T $S DoneChoiceMember !EndGI
T * DoneChoiceMember !EndGI !MarkRep
T + DoneChoiceMember !EndGI !MarkRep
T ? DoneChoiceMember !EndGI !MarkRep
T ) PopCP() !EndGI
T | ChoiceNeedNext !EndGI

# after () child in a Choice
State AfterChoiceMember BustedMarkup {after )}
T $S DoneChoiceMember
T | ChoiceNeedNext
T * DoneChoiceMember !MarkRep
T + DoneChoiceMember !MarkRep
T ? DoneChoiceMember !MarkRep
T ) PopCP()

# all done with member of a choice
State DoneChoiceMember BustedMarkup {after member of choice}
T % Push(PERef,DoneChoiceMember) !MarkPC !ColdStart
T $S DoneChoiceMember
T | ChoiceNeedNext
T ) PopCP()

# Saw (#PCDATA
State AfterPCDATA BustedDecl {after #PCDATA}
T % Push(PERef,AfterPCDATA) !MarkPC !ColdStart
T $S AfterPCDATA
T ) SimpleMixed
T | MixedNeedGI

# Saw (#PCDATA|
State MixedNeedGI BustedDecl {after (#PCDATA|}
T $S MixedNeedGI
T % Push(PERef,MixedNeedGI) !MarkPC !ColdStart
T $NameStart MixedGI !HotStart

State MixedGI BustedDecl {in element type}
T $NameC MixedGI
T $S MixedAfterGI !EndGI
T | MixedNeedGI !EndGI
T ) AfterMixed !EndGI

State MixedAfterGI BustedDecl {after element type}
T $S MixedAfterGI
T % Push(PERef,MixedAfterGI) !MarkPC !ColdStart
T | MixedNeedGI
T ) AfterMixed

State AfterMixed BustedDecl {after mixed declaration}
T * DoneMixed !DoMixed

State DoneMixed BustedDecl {}
T % Push(PERef,DoneMixed) !MarkPC !ColdStart
T $S DoneMixed
T > InSubset

# Saw (#PCDATA)
State SimpleMixed  BustedDecl {after (#PCDATA)}
T * DoneMixed !DoMixed
T $S DoneMixed !DoMixed
T > InSubset !DoMixed

State AfterEntityKW BustedDecl {after <!ENTITY}
T $S AfterEntDec

# After <!entity
State AfterEntDec BustedDecl {}
T % PCAfterEntDec
T $NameStart InEntName !HotStart
T $S AfterEntDec

# Percent sign after <!ENTITY - maybe PERef, maybe PE Decl signal
State PCAfterEntDec BustedDecl {after <!ENTITY %}
T $NameStart Push(PERef,AfterEntDec) !MarkPC !HotStart
T $S BeforeEntName !SignalPE

State BeforeEntName BustedDecl {}
T % Push(PERef,BeforeEntName) !MarkPC !ColdStart
T $S BeforeEntName
T $NameStart InEntName !HotStart

# In Entity Name
State InEntName BustedDecl {in entity name}
T $NameC InEntName
T $S AfterEntName !EndSave

# After Entity Name
State AfterEntName BustedDecl {after entity name}
T % Push(PERef,AfterEntName) !MarkPC !ColdStart
T ' Push(SQEntVal,AfterEVal) !ColdStart !EnterEntVal
T " Push(DQEntVal,AfterEVal) !ColdStart !EnterEntVal
T S Push(System1,SawEntExternalID)
T P Push(Public1,SawEntExternalID)
T $S AfterEntName

State DQEntVal BustedDecl {internal entity declaration}
T " Pop() !EndSave
T % Push(PERef,DQEntVal) !MarkPC !ColdStart
T & Push(SawAmp,DQEntVal) !MarkAmp
T $. DQEntVal

State SQEntVal BustedDecl {}
T ' Pop() !EndSave
T % Push(PERef,SQEntVal) !MarkPC !ColdStart
T & Push(SawAmp,SQEntVal) !MarkAmp
T $. SQEntVal

# AfterEVal
State AfterEVal BustedDecl {after enitity value}
T % Push(PERef,AfterEVal) !MarkPC !ColdStart
T > InSubset !ReportInternalEntity
T $S AfterEVal

# <!entity foo system "bar"
State SawEntExternalID BustedDecl {after entity SYSTEM ID}
T $S DoneEntExternalID
T > InSubset !ReportSystemTextEntity

State DoneEntExternalID BustedDecl {}
T % Push(PERef,DoneEntExternalID) !MarkPC !ColdStart
T N Keyword(NDATA,AfterNDATA,1)
T > InSubset !ReportSystemTextEntity
T $S DoneEntExternalID

# NDATA
State AfterNDATA BustedDecl {after NDATA}
T $S SawNDATA

# Saw NDATA
State SawNDATA BustedDecl {}
T % Push(PERef,SawNDATA) !MarkPC !ColdStart
T $NameStart InNotationName !HotStart
T $S SawNDATA

# Reading notation name after NDATA
State InNotationName BustedDecl {}
T $NameC InNotationName
T $S AfterNDATADecl
T > InSubset !EndSave !DeclareUnparsed

State AfterNDATADecl BustedDecl {after NDATA declaration}
T $S AfterNDATADecl
T > InSubset !EndSave !DeclareUnparsed

# saw </
State ETAGO BustedMarkup {after </}
T $NameStart EtagGI !HotStart

#9 GI in end-tag
State EtagGI BustedMarkup {in end-tag}
T > InDoc !EndGI !ReportETag
T $NameC EtagGI
T $S SawEtagGI !EndGI

#10 S after GI in end-tag
State SawEtagGI BustedMarkup {}
T > InDoc !ReportETag
T $S SawEtagGI

# in Start tag GI
State StagGI BustedMarkup {in element type}
T $NameC StagGI
T $S InStag !EndGI
T > InDoc !EndGI !ReportSTag
T / EmptyClose !EndGI

State EmptyClose BustedMarkup {after / in start-tag}
T > InDoc !ReportEmpty

# in tag after gi
State InStag BustedMarkup {in start-tag}
T > InDoc !ReportSTag
T / EmptyClose
T $S InStag
T $NameStart AttrName !HotStart

# Attr name
State AttrName BustedMarkup {}
T = Eq2 !EndAttribute
T $NameC AttrName
T $S Eq1 !EndAttribute

# ' ' before =
State Eq1 BustedMarkup {}
T = Eq2
T $S Eq1

# = in Eq
State Eq2 BustedMarkup {after AttrName= in start-tag}
T ' Push(SQAVal,InStag) !ColdStart !EnterAttrVal
T " Push(DQAVal,InStag) !ColdStart !EnterAttrVal
T $S Eq2

# in AttrValue, '-delimited
State SQAVal BustedMarkup {}
T < SQAVal !MarkLt
T ' Pop() !EndAttrVal
T & Push(SawAmp,SQAVal) !ReportText !MarkAmp !ColdStart
T $. SQAVal

# in Default AttrValue, '-delimited
State SQADef BustedDecl {}
T ' Pop() !EndAttrVal !ReportAttDecl
T & Push(SawAmp,SQAVal) !ReportText !MarkAmp !ColdStart
T $. SQADef

# in AttrValue, "-delimited
State DQAVal BustedMarkup {}
T < DQAVal !MarkLt
T " Pop() !EndAttrVal
T & Push(SawAmp,DQAVal) !ReportText !MarkAmp !ColdStart
T $. DQAVal

# in Default Attrval
State DQADef BustedDecl {}
T " Pop() !EndAttrVal !ReportAttDecl
T & Push(SawAmp,DQAVal) !ReportText !MarkAmp !ColdStart
T $. DQADef

# scanning in PCData
State InDoc InDoc {in character data}
T < SawLT !ReportText !MarkLt
T & Push(SawAmp,InDoc) !ReportText !MarkAmp !ColdStart
T $. InDoc
T ] RSBInDoc

# ] in doc
State RSBInDoc InDoc {}
T < SawLT !ReportText !MarkLt
T & Push(SawAmp,InDoc) !ReportText !MarkAmp !ColdStart
T ] RSB2InDoc
T $. InDoc

# ]] in doc
State RSB2InDoc InDoc {}
T < SawLT !ReportText !MarkLt
T & Push(SawAmp,InDoc) !ReportText !MarkAmp !ColdStart
T > InDoc !FloatingMSE
T ] RSB2InDoc
T $. InDoc

# After root element
State AfterRoot AfterRoot {after end of document}
T $S AfterRoot
T < LTAfterRoot

State LTAfterRoot BustedMarkup {< after document}
T ? Push(InPI,AfterRoot) !ColdStart
T ! ComStartAfter
State ComStartAfter BustedMarkup {}
T - Push(COMStartHalf,AfterRoot)

State SawAmp BustedEntity {after &}
T a AmpA
T g AmpG
T l AmpL
T q AmpQ
T # AmpHash
T $NameStart EntBody

# reading numeric char refs
State AmpHash BustedEntity {in &# reference}
T 0123456789 AmpHash
T x HexRef
T ; Pop() !HashRef

# hex char refs
State HexRef BustedEntity {in &#x reference}
T $Hex HexRef
T ; Pop() !HashRef

State BustedEntity InDoc {}
T ; Pop() !ColdStart
T $. BustedEntity

State EntBody BustedEntity {in entity name}
T ; Pop() !ReportReference
T $NameC EntBody

State AmpG BustedEntity {in entity reference}
T t AmpGt
T $NameC EntBody

State AmpGt BustedEntity {}
T ; Pop() !CharRef(>)
T $NameC EntBody

State AmpL BustedEntity {}
T t AmpLt
T $NameC EntBody

State AmpLt BustedEntity {}
T ; Pop() !CharRef(<)
T $NameC EntBody

State AmpQ BustedEntity {}
T u AmpQu
T $NameC EntBody

State AmpQu BustedEntity {}
T o AmpQuo
T $NameC EntBody

State AmpQuo BustedEntity {}
T t AmpQuot
T $NameC EntBody

State AmpQuot BustedEntity {}
T ; Pop() !CharRef(")
T $NameC EntBody

State AmpA BustedEntity {}
T m AmpAm
T p AmpAp
T $NameC EntBody

State AmpAp BustedEntity {}
T o AmpApo
T $NameC EntBody

State AmpApo BustedEntity {}
T s AmpApos
T $NameC EntBody

State AmpApos BustedEntity {}
T ; Pop() !CharRef(')
T $NameC EntBody

State AmpAm BustedEntity {}
T p AmpAmp
T $NameC EntBody

StateAmpAmp BustedEntity {}
T ; Pop() !CharRef(&)
T $NameC EntBody

# Breakage in markup - wait for ">"
State BustedMarkup InDoc {}
T > InDoc !ColdStart
T $. BustedMarkup

# Breakage in declaration in subset - wait for '>'
State BustedDecl InDoc {}
T > InSubset
T $. BustedDecl

# XML declaration is:
# XMLDecl ::= '<?xml' VersionInfo EncodingDecl? SDDecl? S? '?>'
# TextDecl ::= '<?xml' VersionInfo? EncodingDecl S? '?>'
# VersionInfo ::= S 'version' Eq ('"VersionNum"' | "'VersionNum'")
# Eq ::= S? '=' S?
# VersionNum ::= ([a-zA-Z0-9_.:] | '-')+
# EncodingDecl ::= S 'encoding' Eq '"' EncName '"' | "'" EncName "'" 
# EncName ::= [A-Za-z] ([A-Za-z0-9._] | '-')*
# SDDecl ::= S 'standalone' Eq "'" ('yes' | 'no') "'" 
#            | S 'standalone' Eq '"' ('yes' | 'no') '"' 
# we start after the <?, with saving on
State TryXMLD InDoc {trying for <?xml}
T x TryXMLD2
T $NameStart PI2
State TryXMLD2 InDoc {}
T m TryXMLD3
T $NameC PI2
T $S PI3 !EndSave
T ? PICMustHaveGT !EndSave
State TryXMLD3 InDoc {}
T l TryXMLD4
T $NameC PI2
T $S PI3 !EndSave
T ? PICMustHaveGT !EndSave
State TryXMLD4 InDoc {}
T $S XMLDs1 !EndSave
T $NameC PI2
State XMLDs1 InDoc {in XML declaration}
T v Keyword(version,AfterVersion,1)
T $S XMLDs1
State AfterVersion InDoc {}
T $S AfterVersion
T = AfterVersEq
State AfterVersEq InDoc {}
T $S AfterVersEq
T ' Keyword('1.0',GotVer,1)
T " Keyword("1.0",GotVer,1)
State GotVer InDoc {}
T $S DoneVer
T ? EndXMLD
State DoneVer InDoc {}
T $S DoneVer
T ? EndXMLD
T e Keyword(encoding,AfterEnc,1) !HotStart
T s Keyword(standalone,AfterStand,1) !HotStart
State AfterEnc InDoc {}
T $S AfterEnc2 !EndSave
T = AfterEncEq !EndSave
State AfterEnc2 InDoc {}
T $S AfterEnc2
T = AfterEncEq

State AfterEncEq InDoc {}
T $S AfterEncEq
T ' SQEncName !ColdStart
T " DQEncName !ColdStart

State SQEncName InDoc {}
T $EncName SQEncName
T ' AfterEncName !EndSave
State DQEncName InDoc {}
T $EncName DQEncName
T " AfterEncName !EndSave

State AfterEncName InDoc {}
T $S DoneEncName
T ? EndXMLD
State DoneEncName InDoc {}
T $S DoneEncName
T ? EndXMLD
T s Keyword(standalone,AfterStand,1) !HotStart

State AfterStand InDoc {}
T $S AfterStand2 !EndSave
T = AfterStandEq !EndSave
State AfterStand2 InDoc {}
T $S AfterStand2
T = AfterStandEq
State AfterStandEq InDoc {}
T $S AfterStandEq
T ' StandSQ !ColdStart
T " StandDQ !ColdStart

State StandSQ InDoc {}
T y Keyword('yes',AfterSDD,2)
T n Keyword('no',AfterSDD,2)
State StandDQ InDoc {}
T y Keyword("yes",AfterSDD,2) !HotStart
T n Keyword("no",AfterSDD,2) !HotStart

State AfterSDD InDoc {}
T ? EndXMLD !EndSave
T $S DoneSDD !EndSave

State DoneSDD InDoc {}
T $S DoneSDD
T ? EndXMLD

State EndXMLD InDoc {}
T > Pop() !GotXMLD