-module(ys_parse). -export([ parse_doctypedecl/2, parse_content/2, parse_Misc/2, parse_element/2, parse_XMLDecl/2 ]). % -define(LINE_NUMBERS, true). % -ifdef(LINE_NUMBERS). % -define(bl(State), bump_line(State)). % bump_line(#{line := L} = State) -> State#{line := L + 1}. % -else. % -define(bl(State), State). % -endif. -include("yaccety_sax.hrl"). -define(APPEND(Thing, Acc), append(Thing, Acc)). -define(ACC(Stream, Pos, Len, Acc), ?APPEND(binary_part(Stream, Pos, Len), Acc)). -define(MATCH, Bytes, Stream, Pos, State). -define(MATCH1, Bytes1, Stream1, Pos1, State1). -define(MATCH2, Bytes2, Stream2, Pos2, State2). -define(MATCH3, Bytes3, Stream3, Pos3, State3). -define(MATCH4, Bytes4, Stream4, Pos4, State4). -define(MATCH5, Bytes5, Stream5, Pos5, State5). -define(MATCH6, Bytes6, Stream6, Pos6, State6). -define(MATCH7, Bytes7, Stream7, Pos7, State7). %-define(dbg(_), ok). %-define(dbg(Thing), io:format("~p~n", [{?LINE, Thing}])). -define(XML_NS, <<"http://www.w3.org/XML/1998/namespace">>). -define(XMLNS_NS, <<"http://www.w3.org/2000/xmlns/">>). -define(WS(Char), (Char == 16#20 orelse Char == 16#9 orelse Char == 16#A orelse Char == 16#D)). -compile({inline, [append/2, set_state_pos/2, to_binary/1, fatal_error/2]}). append(<<>>, Acc) -> Acc; append(Thing, []) -> Thing; append(Thing, Acc) -> [Acc, Thing]. cf(#ys_state{continuation = undefined} = State) -> {no_bytes, State}; cf(#ys_state{continuation = {CF, replacement}, tags = Tags}) -> {Bytes, State} = CF(replacement), {Bytes, State#ys_state{tags = Tags}}; cf(#ys_state{continuation = {CF, CS}} = State) -> case CF(CS) of {Bin, CS1} when is_binary(Bin) -> {Bin, State#ys_state{continuation = {CF, CS1}}}; eof -> _ = CF(close), {<<>>, State#ys_state{continuation = undefined}}; {error, Err} -> {error, {Err, State}} end. cf(_, #ys_state{continuation = undefined} = State, _) -> {no_bytes, State}; cf(Part, #ys_state{continuation = {CF, CS}} = State, {partial, BytesNeeded}) -> case CF(CS) of {Bin, CS1} when is_binary(Bin), byte_size(Bin) >= BytesNeeded -> RestBytes = binary_part(Bin, 0, BytesNeeded), <> = <>, {<>, Bin, BytesNeeded, State#ys_state{ continuation = {CF, CS1} }}; {Bin, CS1} when is_binary(Bin), byte_size(Bin) >= 0 -> cf( <>, State#ys_state{continuation = {CF, CS1}}, {partial, BytesNeeded - byte_size(Bin)} ); eof -> _ = CF(close), {<<>>, <<>>, 0, State#ys_state{continuation = undefined}}; {error, Err} -> {error, {Err, State}} end. -define(CHARPARTFUN(D), Acc1 = ?ACC(Stream, Pos, Len, Acc), {Char, Stream1, Pos1, State1} = cf(Bytes, State, {partial, D}), case Char of <<16#FFFE/utf8>> -> fatal_error({invalid_character, [Char]}, State1); <<16#FFFF/utf8>> -> fatal_error({invalid_character, [Char]}, State1); _ -> Acc2 = ?APPEND(Char, Acc1), <<_:Pos1/binary, Rest/bitstring>> = Stream1, ?FUNCTION_NAME(Rest, Stream1, Pos1, 0, State1, Acc2) end ). -define(CHARPARTFUNX(D), Acc1 = ?ACC(Stream, Pos, Len, Acc), {Char, Stream1, Pos1, State1} = cf(Bytes, State, {partial, D}), case Char of <<16#FFFE/utf8>> -> fatal_error({invalid_character, [Char]}, State1); <<16#FFFF/utf8>> -> fatal_error({invalid_character, [Char]}, State1); <<_/utf8>> -> Acc2 = ?APPEND(Char, Acc1), <<_:Pos1/binary, Rest/bitstring>> = Stream1, ?FUNCTION_NAME(Rest, Stream1, Pos1, 0, State1, Acc2, DTD, External) end ). -define(CHARPARTFUND(D), Acc1 = ?ACC(Stream, Pos, Len, Acc), {Char, Stream1, Pos1, State1} = cf(Bytes, State, {partial, D}), case Char of <<16#FFFE/utf8>> -> fatal_error({invalid_character, [Char]}, State1); <<16#FFFF/utf8>> -> fatal_error({invalid_character, [Char]}, State1); _ -> Acc2 = ?APPEND(Char, Acc1), <<_:Pos1/binary, Rest/bitstring>> = Stream1, ?FUNCTION_NAME(Rest, Stream1, Pos1, 0, State1, Acc2, DTD) end ). -define(NAMECHARPARTFUN(D), Acc1 = ?ACC(Stream, Pos, Len, Acc), {CodeChar, Stream1, Pos1, State1} = cf(Bytes, State, {partial, D}), case CodeChar of <> when Char == 16#B7; Char >= 16#C0, Char =< 16#D6; Char >= 16#D8, Char =< 16#F6; Char >= 16#F8, Char =< 16#37D; Char >= 16#37F, Char =< 16#7FF; Char >= 16#800, Char =< 16#1FFF; Char >= 16#200C, Char =< 16#200D; Char >= 16#203F, Char =< 16#2040; Char >= 16#2070, Char =< 16#218F; Char >= 16#2C00, Char =< 16#2FEF; Char >= 16#3001, Char =< 16#D7FF; Char >= 16#F900, Char =< 16#FDCF; Char >= 16#FDF0, Char =< 16#FFFD; Char >= 16#10000, Char =< 16#EFFFF -> Acc2 = ?APPEND(CodeChar, Acc1), <<_:Pos1/binary, Rest/bitstring>> = Stream1, ?FUNCTION_NAME(Rest, Stream1, Pos1, 0, State1, Acc2); _ -> fatal_error({invalid_character, [CodeChar]}, State1) end ). -define(FSTNAMECHARPARTFUN(D, Next), {CodeChar, Stream1, Pos1, State1} = cf(Bytes, State, {partial, D}), case CodeChar of <> when Char >= 16#C0, Char =< 16#D6; Char >= 16#D8, Char =< 16#F6; Char >= 16#F8, Char =< 16#2FF; Char >= 16#370, Char =< 16#37D; Char >= 16#37F, Char =< 16#7FF; Char >= 16#800, Char =< 16#1FFF; Char >= 16#200C, Char =< 16#200D; Char >= 16#2070, Char =< 16#218F; Char >= 16#2C00, Char =< 16#2FEF; Char >= 16#3001, Char =< 16#D7FF; Char >= 16#F900, Char =< 16#FDCF; Char >= 16#FDF0, Char =< 16#FFFD; Char >= 16#10000, Char =< 16#EFFFF -> <<_:Pos1/binary, Rest/bitstring>> = Stream1, Next(Rest, Stream1, Pos1, 0, State1, CodeChar); _ -> fatal_error({invalid_character, [CodeChar]}, State1) end ). -define(GET_PE(Func), Func(<<"%", Bytes/bitstring>>, Stream, Pos, State, DTD, true) -> {PERef, Bytes1, _, _, State1} = parse_PEReference(Bytes, Stream, Pos + 1, State), case resolve_parameter_entity(PERef, DTD, State1, true, true) of % Stripping whitespace added in replacement {replacement_text, <<" ", ReplacementText/bitstring>>} -> RTState = replacement_text_state(Bytes1, State1), {_, ?MATCH2} = maybe_consume_s(ReplacementText, ReplacementText, 0, RTState), Func(?MATCH2, DTD, true) end ). -define(GET_PE_ACC(Func), Func(<<"%", Bytes/bitstring>>, Stream, Pos, State, Acc, DTD, true) -> {PERef, Bytes1, _, _, State1} = parse_PEReference(Bytes, Stream, Pos + 1, State), case resolve_parameter_entity(PERef, DTD, State1, true, true) of % Stripping whitespace added in replacement {replacement_text, <<" ", ReplacementText/bitstring>>} -> RTState = replacement_text_state(Bytes1, State1), {_, ?MATCH2} = maybe_consume_s(ReplacementText, ReplacementText, 0, RTState), Func(?MATCH2, Acc, DTD, true) end ). %%---------------------------------------------------------------------- %% XML character range %% [2] Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | %% [#x10000-#x10FFFF] %% any Unicode character, excluding the surrogate blocks, FFFE, and FFFF. %%---------------------------------------------------------------------- -define(ONECHAR, ?FUNCTION_NAME(<<16#9/utf8, Rest/bitstring>>, Stream, Pos, Len, State, Acc) -> ?FUNCTION_NAME(Rest, Stream, Pos, Len + 1, State, Acc); ?FUNCTION_NAME(<<16#A/utf8, Rest/bitstring>>, Stream, Pos, Len, State, Acc) -> ?FUNCTION_NAME(Rest, Stream, Pos, Len + 1, State, Acc); ?FUNCTION_NAME(<<16#FFFE/utf8, _Rest/bitstring>>, _, _, _, State, _Acc) -> fatal_error({invalid_character, {?LINE, [16#FFFE]}}, State); ?FUNCTION_NAME(<<16#FFFF/utf8, _Rest/bitstring>>, _, _, _, State, _Acc) -> fatal_error({invalid_character, {?LINE, [16#FFFF]}}, State); ?FUNCTION_NAME(<>, Stream, Pos, Len, State, Acc) -> if Char < 16#20 -> fatal_error({invalid_character, {?LINE, [Char]}}, State); Char < 16#80 -> ?FUNCTION_NAME(Rest, Stream, Pos, Len + 1, State, Acc); Char < 16#800 -> ?FUNCTION_NAME(Rest, Stream, Pos, Len + 2, State, Acc); Char < 16#10000 -> ?FUNCTION_NAME(Rest, Stream, Pos, Len + 3, State, Acc); true -> ?FUNCTION_NAME(Rest, Stream, Pos, Len + 4, State, Acc) end; %% ?FUNCTION_NAME(<<>>, Stream, Pos, Len, State, Acc) -> Acc1 = ?ACC(Stream, Pos, Len, Acc), {Stream1, State1} = cf(State), ?FUNCTION_NAME(Stream1, Stream1, 0, 0, State1, Acc1); ?FUNCTION_NAME(Bytes = <<30:5, _:3>>, Stream, Pos, Len, State, Acc) -> ?CHARPARTFUN(3); ?FUNCTION_NAME(Bytes = <<30:5, _:3, 2:2, _:6>>, Stream, Pos, Len, State, Acc) -> ?CHARPARTFUN(2); ?FUNCTION_NAME(Bytes = <<14:4, _:4>>, Stream, Pos, Len, State, Acc) -> ?CHARPARTFUN(2); ?FUNCTION_NAME(Bytes = <<30:5, _:3, 2:2, _:6, 2:2, _:6>>, Stream, Pos, Len, State, Acc) -> ?CHARPARTFUN(1); ?FUNCTION_NAME(Bytes = <<14:4, _:4, 2:2, _:6>>, Stream, Pos, Len, State, Acc) -> ?CHARPARTFUN(1); ?FUNCTION_NAME(Bytes = <<6:3, _:5>>, Stream, Pos, Len, State, Acc) -> ?CHARPARTFUN(1); ?FUNCTION_NAME(Bytes, Stream, Pos, Len, State, Acc) -> Acc1 = ?ACC(Stream, Pos, Len, Acc), {to_binary(Acc1), Bytes, Stream, Pos + Len, State} ). -define(ONECHARX, ?FUNCTION_NAME(<<16#9/utf8, Rest/bitstring>>, Stream, Pos, Len, State, Acc, DTD, External) -> ?FUNCTION_NAME(Rest, Stream, Pos, Len + 1, State, Acc, DTD, External); ?FUNCTION_NAME(<<16#A/utf8, Rest/bitstring>>, Stream, Pos, Len, State, Acc, DTD, External) -> ?FUNCTION_NAME(Rest, Stream, Pos, Len + 1, State, Acc, DTD, External); ?FUNCTION_NAME(<<16#FFFE/utf8, _Rest/bitstring>>, _, _, _, State, _Acc, _DTD, _External) -> fatal_error({invalid_character, [16#FFFE]}, State) ; ?FUNCTION_NAME(<<16#FFFF/utf8, _Rest/bitstring>>, _, _, _, State, _Acc, _DTD, _External) -> fatal_error({invalid_character, [16#FFFF]}, State) ; ?FUNCTION_NAME(<>, Stream, Pos, Len, State, Acc, DTD, External) -> if Char < 16#20 -> fatal_error({invalid_character, [Char]}, State); Char < 16#80 -> ?FUNCTION_NAME(Rest, Stream, Pos, Len + 1, State, Acc, DTD, External); Char < 16#800 -> ?FUNCTION_NAME(Rest, Stream, Pos, Len + 2, State, Acc, DTD, External); Char < 16#10000 -> ?FUNCTION_NAME(Rest, Stream, Pos, Len + 3, State, Acc, DTD, External); true -> ?FUNCTION_NAME(Rest, Stream, Pos, Len + 4, State, Acc, DTD, External) end; ?FUNCTION_NAME(<<>>, Stream, Pos, Len, State, Acc, DTD, External) -> Acc1 = ?ACC(Stream, Pos, Len, Acc), {Stream1, State1} = cf(State), ?FUNCTION_NAME(Stream1, Stream1, 0, 0, State1, Acc1, DTD, External); ?FUNCTION_NAME(Bytes = <<30:5, _:3>>, Stream, Pos, Len, State, Acc, DTD, External) -> ?CHARPARTFUNX(3); ?FUNCTION_NAME(Bytes = <<30:5, _:3, 2:2, _:6>>, Stream, Pos, Len, State, Acc, DTD, External) -> ?CHARPARTFUNX(2); ?FUNCTION_NAME(Bytes = <<14:4, _:4>>, Stream, Pos, Len, State, Acc, DTD, External) -> ?CHARPARTFUNX(2); ?FUNCTION_NAME(Bytes = <<30:5, _:3, 2:2, _:6, 2:2, _:6>>, Stream, Pos, Len, State, Acc, DTD, External) -> ?CHARPARTFUNX(1); ?FUNCTION_NAME(Bytes = <<14:4, _:4, 2:2, _:6>>, Stream, Pos, Len, State, Acc, DTD, External) -> ?CHARPARTFUNX(1); ?FUNCTION_NAME(Bytes = <<6:3, _:5>>, Stream, Pos, Len, State, Acc, DTD, External) -> ?CHARPARTFUNX(1); ?FUNCTION_NAME(Bytes, Stream, Pos, Len, State, Acc, DTD, External) -> Acc1 = ?ACC(Stream, Pos, Len, Acc), {to_binary(Acc1), Bytes, Stream, Pos + Len, State, DTD, External} ). -define(ONECHARD, ?FUNCTION_NAME(<<16#9/utf8, Rest/bitstring>>, Stream, Pos, Len, State, Acc, DTD) -> ?FUNCTION_NAME(Rest, Stream, Pos, Len + 1, State, Acc, DTD); ?FUNCTION_NAME(<<16#A/utf8, Rest/bitstring>>, Stream, Pos, Len, State, Acc, DTD) -> ?FUNCTION_NAME(Rest, Stream, Pos, Len + 1, State, Acc, DTD); ?FUNCTION_NAME(<<16#FFFE/utf8, _Rest/bitstring>>, _, _, _, State, _Acc, _DTD) -> fatal_error({invalid_character, [16#FFFE]}, State) ; ?FUNCTION_NAME(<<16#FFFF/utf8, _Rest/bitstring>>, _, _, _, State, _Acc, _DTD) -> fatal_error({invalid_character, [16#FFFF]}, State) ; ?FUNCTION_NAME(<>, Stream, Pos, Len, State, Acc, DTD) -> if Char < 16#20 -> fatal_error({invalid_character, [Char]}, State); Char < 16#80 -> ?FUNCTION_NAME(Rest, Stream, Pos, Len + 1, State, Acc, DTD); Char < 16#800 -> ?FUNCTION_NAME(Rest, Stream, Pos, Len + 2, State, Acc, DTD); Char < 16#10000 -> ?FUNCTION_NAME(Rest, Stream, Pos, Len + 3, State, Acc, DTD); true -> ?FUNCTION_NAME(Rest, Stream, Pos, Len + 4, State, Acc, DTD) end; ?FUNCTION_NAME(<<>>, Stream, Pos, Len, State, Acc, DTD) -> Acc1 = ?ACC(Stream, Pos, Len, Acc), {Stream1, State1} = cf(State), ?FUNCTION_NAME(Stream1, Stream1, 0, 0, State1, Acc1, DTD); ?FUNCTION_NAME(Bytes = <<30:5, _:3>>, Stream, Pos, Len, State, Acc, DTD) -> ?CHARPARTFUND(3); ?FUNCTION_NAME(Bytes = <<30:5, _:3, 2:2, _:6>>, Stream, Pos, Len, State, Acc, DTD) -> ?CHARPARTFUND(2); ?FUNCTION_NAME(Bytes = <<14:4, _:4>>, Stream, Pos, Len, State, Acc, DTD) -> ?CHARPARTFUND(2); ?FUNCTION_NAME(Bytes = <<30:5, _:3, 2:2, _:6, 2:2, _:6>>, Stream, Pos, Len, State, Acc, DTD) -> ?CHARPARTFUND(1); ?FUNCTION_NAME(Bytes = <<14:4, _:4, 2:2, _:6>>, Stream, Pos, Len, State, Acc, DTD) -> ?CHARPARTFUND(1); ?FUNCTION_NAME(Bytes = <<6:3, _:5>>, Stream, Pos, Len, State, Acc, DTD) -> ?CHARPARTFUND(1); ?FUNCTION_NAME(Bytes, Stream, Pos, Len, State, Acc, DTD) -> Acc1 = ?ACC(Stream, Pos, Len, Acc), {to_binary(Acc1), Bytes, Stream, Pos + Len, State, DTD} ). %%---------------------------------------------------------------------- %% [4a] NameChar %% NameStartChar | "-" | "." | [0-9] | #xB7 | [#x0300-#x036F] | [#x203F-#x2040] %%---------------------------------------------------------------------- -define(ONENAMECHAR, ?FUNCTION_NAME(<>, Stream, Pos, Len, State, Acc) when Char == $-; Char == $.; Char >= $0, Char =< $9; Char == $:; Char >= $A, Char =< $Z; Char == $_; Char >= $a, Char =< $z -> ?FUNCTION_NAME(Rest, Stream, Pos, Len + 1, State, Acc); ?FUNCTION_NAME(<>, Stream, Pos, Len, State, Acc) when Char == 16#B7; Char >= 16#C0, Char =< 16#D6; Char >= 16#D8, Char =< 16#F6; Char >= 16#F8, Char =< 16#37D; Char >= 16#37F, Char =< 16#7FF -> ?FUNCTION_NAME(Rest, Stream, Pos, Len + 2, State, Acc); ?FUNCTION_NAME(<>, Stream, Pos, Len, State, Acc) when Char >= 16#800, Char =< 16#1FFF; Char >= 16#200C, Char =< 16#200D; Char >= 16#203F, Char =< 16#2040; Char >= 16#2070, Char =< 16#218F; Char >= 16#2C00, Char =< 16#2FEF; Char >= 16#3001, Char =< 16#D7FF; Char >= 16#F900, Char =< 16#FDCF; Char >= 16#FDF0, Char =< 16#FFFD -> ?FUNCTION_NAME(Rest, Stream, Pos, Len + 3, State, Acc); ?FUNCTION_NAME(<>, Stream, Pos, Len, State, Acc) when Char >= 16#10000, Char =< 16#EFFFF -> ?FUNCTION_NAME(Rest, Stream, Pos, Len + 4, State, Acc); ?FUNCTION_NAME(Bytes = <<30:5, _:3>>, Stream, Pos, Len, State, Acc) -> ?NAMECHARPARTFUN(3); ?FUNCTION_NAME(Bytes = <<30:5, _:3, 2:2, _:6>>, Stream, Pos, Len, State, Acc) -> ?NAMECHARPARTFUN(2); ?FUNCTION_NAME(Bytes = <<14:4, _:4>>, Stream, Pos, Len, State, Acc) -> ?NAMECHARPARTFUN(2); ?FUNCTION_NAME(Bytes = <<30:5, _:3, 2:2, _:6, 2:2, _:6>>, Stream, Pos, Len, State, Acc) -> ?NAMECHARPARTFUN(1); ?FUNCTION_NAME(Bytes = <<14:4, _:4, 2:2, _:6>>, Stream, Pos, Len, State, Acc) -> ?NAMECHARPARTFUN(1); ?FUNCTION_NAME(Bytes = <<6:3, _:5>>, Stream, Pos, Len, State, Acc) -> ?NAMECHARPARTFUN(1); ?FUNCTION_NAME(Bytes, Stream, Pos, Len, State, Acc) -> Acc1 = ?ACC(Stream, Pos, Len, Acc), {to_binary(Acc1), Bytes, Stream, Pos + Len, State} ). %%---------------------------------------------------------------------- %% [13] PubidChar ::= #x20 | #xD | #xA | [a-zA-Z0-9] | [-'()+,./:=?;!*#@$_%] %%---------------------------------------------------------------------- -define(ONEPUBIDCHAR, ?FUNCTION_NAME(<>, Stream, Pos, Len, State, Acc) when Char == 16#A; Char == 16#D; Char == 16#20; Char == 16#21; Char >= 16#23, Char =< 16#25; Char >= 16#27, Char =< 16#3B; Char == 16#3D; Char >= 16#3F, Char =< 16#5A; Char == 16#5F; Char >= 16#61, Char =< 16#7A -> ?FUNCTION_NAME(Rest, Stream, Pos, Len + 1, State, Acc); ?FUNCTION_NAME(<>, _, _, _, _State, _) -> fatal_error(invalid_pubid_character, Char) ). %%---------------------------------------------------------------------- %% Consume whitespace characters %% params: State %% returns: {NewPos, NewState} | {error, non_whitespace} %% [3] S ::= (#x20 | #x9 | #xD | #xA)+ %%---------------------------------------------------------------------- consume_s(<>, Stream, Pos, State) when Char == 16#20; Char == 16#9; Char == 16#D; Char == 16#A -> maybe_consume_s(Rest, Stream, Pos + 1, State, true); consume_s(<<>>, _, _, State) -> {Stream1, State1} = cf(State), consume_s(Stream1, Stream1, 0, State1); consume_s(_, _, _, State) -> fatal_error(missing_whitespace, State). consume_s(<<"%", Bytes/bitstring>>, Stream, Pos, State, DTD) -> {PERef, Bytes1, _, _, State1} = parse_PEReference(Bytes, Stream, Pos + 1, State), case resolve_parameter_entity(PERef, DTD, State1, true, true) of {replacement_text, ReplacementText} -> RTState = replacement_text_state(Bytes1, State1), consume_s(ReplacementText, ReplacementText, 0, RTState, DTD) end; consume_s(?MATCH, _DTD) -> consume_s(?MATCH). maybe_consume_s(?MATCH) -> maybe_consume_s(?MATCH, false). maybe_consume_s(<>, Stream, Pos, State, _) when Char == 16#20; Char == 16#9; Char == 16#D; Char == 16#A -> maybe_consume_s(Rest, Stream, Pos + 1, State, true); maybe_consume_s(<<>>, Stream, Pos, State, Found) -> case cf(State) of {no_bytes, State1} -> {Found, <<>>, Stream, Pos, State1}; {Stream1, State1} -> maybe_consume_s(Stream1, Stream1, 0, State1, Found) end; maybe_consume_s(Part, Stream, Pos, State, Found) -> {Found, Part, Stream, Pos, State}. maybe_consume_dtd_s(?MATCH, DTD) -> maybe_consume_dtd_s(?MATCH, DTD, false). maybe_consume_dtd_s(<>, Stream, Pos, State, DTD, _) when Char == 16#20; Char == 16#9; Char == 16#D; Char == 16#A -> maybe_consume_dtd_s(Rest, Stream, Pos + 1, State, DTD, true); maybe_consume_dtd_s(<<"%", Bytes/bitstring>>, Stream, Pos, State, DTD, Found) -> {PERef, Bytes1, _, _, State1} = parse_PEReference(Bytes, Stream, Pos + 1, State), case resolve_parameter_entity(PERef, DTD, State1, true, true) of {replacement_text, ReplacementText} -> RTState = replacement_text_state(Bytes1, State1), maybe_consume_dtd_s(ReplacementText, ReplacementText, 0, RTState, DTD, Found) end; maybe_consume_dtd_s(<<>>, Stream, Pos, State, DTD, Found) -> case cf(State) of {no_bytes, State1} -> {Found, <<>>, Stream, Pos, State1}; {Stream1, State1} -> maybe_consume_dtd_s(Stream1, Stream1, 0, State1, DTD, Found) end; maybe_consume_dtd_s(Part, Stream, Pos, State, _DTD, Found) -> {Found, Part, Stream, Pos, State}. %%---------------------------------------------------------------------- %% Parse Name (does not split prefix and local parts like NCName) %% params: State %% returns: {Name, NewState} %% [4] NameStartChar %% ":" | [A-Z] | "_" | [a-z] | [#xC0-#xD6] | [#xD8-#xF6] | [#xF8-#x2FF] | [#x370-#x37D] %% | [#x37F-#x1FFF] | [#x200C-#x200D] | [#x2070-#x218F] | [#x2C00-#x2FEF] %% | [#x3001-#xD7FF] | [#xF900-#xFDCF] | [#xFDF0-#xFFFD] | [#x10000-#xEFFFF] %% [5] Name ::= NameStartChar (NameChar)* %%---------------------------------------------------------------------- parse_Name(<>, Stream, Pos, State) -> if Char == $:; Char >= $A, Char =< $Z; Char == $_; Char >= $a, Char =< $z -> parse_Name(Rest, Stream, Pos, 1, State, []); Char >= 16#C0, Char =< 16#D6; Char >= 16#D8, Char =< 16#F6; Char >= 16#F8, Char =< 16#2FF; Char >= 16#370, Char =< 16#37D; Char >= 16#37F, Char =< 16#7FF -> parse_Name(Rest, Stream, Pos, 2, State, []); Char >= 16#800, Char =< 16#1FFF; Char >= 16#200C, Char =< 16#200D; Char >= 16#2070, Char =< 16#218F; Char >= 16#2C00, Char =< 16#2FEF; Char >= 16#3001, Char =< 16#D7FF; Char >= 16#F900, Char =< 16#FDCF; Char >= 16#FDF0, Char =< 16#FFFD -> parse_Name(Rest, Stream, Pos, 3, State, []); Char >= 16#10000, Char =< 16#EFFFF -> parse_Name(Rest, Stream, Pos, 4, State, []); true -> fatal_error(bad_name, {[Char], State}) end; parse_Name(<<>>, _, _, State) -> {Stream1, State1} = cf(State), parse_Name(Stream1, Stream1, 0, State1); parse_Name(Bytes = <<30:5, _:3>>, _, _, State) -> ?FSTNAMECHARPARTFUN(3, parse_Name); parse_Name(Bytes = <<30:5, _:3, 2:2, _:6>>, _, _, State) -> ?FSTNAMECHARPARTFUN(2, parse_Name); parse_Name(Bytes = <<14:4, _:4>>, _, _, State) -> ?FSTNAMECHARPARTFUN(2, parse_Name); parse_Name(Bytes = <<30:5, _:3, 2:2, _:6, 2:2, _:6>>, _, _, State) -> ?FSTNAMECHARPARTFUN(1, parse_Name); parse_Name(Bytes = <<14:4, _:4, 2:2, _:6>>, _, _, State) -> ?FSTNAMECHARPARTFUN(1, parse_Name); parse_Name(Bytes = <<6:3, _:5>>, _, _, State) -> ?FSTNAMECHARPARTFUN(1, parse_Name); parse_Name(Bytes, _, _, State) -> fatal_error(bad_name, {Bytes, State}). parse_Name(<<>>, Stream, Pos, Len, State, Acc) -> Acc1 = ?ACC(Stream, Pos, Len, Acc), {Stream1, State1} = cf(State), parse_Name(Stream1, Stream1, 0, 0, State1, Acc1); ?ONENAMECHAR. %%---------------------------------------------------------------------- %% [67] Reference ::= EntityRef | CharRef %% & char is removed %% [66] CharRef ::= '&#' [0-9]+ ';' | '&#x' [0-9a-fA-F]+ ';' %% [WFC: Legal Character] %% [68] EntityRef ::= '&' Name ';' %% [WFC: Entity Declared] %% [WFC: Parsed Entity] %% [WFC: No Recursion] %% can be EntityRef | CharRef %%---------------------------------------------------------------------- parse_Reference(<<>>, _, _, #ys_state{in_replacement = true} = State, _Type) -> fatal_error(unbalanced_reference, State); parse_Reference(<<>>, _, _, State, Type) -> {Stream1, State1} = cf(State), parse_Reference(Stream1, Stream1, 0, State1, Type); parse_Reference(<<$#>>, _, _, State, Type) -> {Stream1, State1} = cf(State), parse_Reference_lb(Stream1, Stream1, State1, Type); parse_Reference(<<$#, $x, Rest/bitstring>>, Stream, Pos, State, _Type) -> parse_Reference_hex(Rest, Stream, Pos + 2, 0, State, []); parse_Reference(<<$#, Rest/bitstring>>, Stream, Pos, State, _Type) -> parse_Reference_dec(Rest, Stream, Pos + 1, 0, State, []); parse_Reference(?MATCH, Type) -> parse_Reference_name(?MATCH, Type). parse_Reference_lb(<<>>, _, #ys_state{in_replacement = true} = State, _Type) -> fatal_error(unbalanced_reference, State); parse_Reference_lb(<<>>, _, State, Type) -> {Stream1, State1} = cf(State), parse_Reference_lb(Stream1, Stream1, State1, Type); parse_Reference_lb(<<$x, Rest/bitstring>>, Stream, State, _Type) -> parse_Reference_hex(Rest, Stream, 1, 0, State, []); parse_Reference_lb(Bytes, Stream, State, _Type) -> parse_Reference_dec(Bytes, Stream, 0, 0, State, []). % hex parse until ';' return char parse_Reference_hex(<<>>, _, _, _, #ys_state{in_replacement = true} = State, _) -> fatal_error(unbalanced_reference, State); parse_Reference_hex(<<>>, Stream, Pos, Len, State, Acc) -> Acc1 = ?ACC(Stream, Pos, Len, Acc), {Stream1, State1} = cf(State), parse_Reference_hex(Stream1, Stream1, 0, 0, State1, Acc1); parse_Reference_hex(<<$;, Rest/bitstring>>, Stream, Pos, Len, State, Acc) -> Acc1 = ?ACC(Stream, Pos, Len, Acc), try case binary_to_integer(to_binary(Acc1), 16) of Int when Int == 16#9; Int == 16#A; Int == 16#D; Int >= 16#20, Int =< 16#D7FF; Int >= 16#E000, Int =< 16#FFFD; Int >= 16#10000, Int =< 16#10FFFF -> {{hex, <>}, Rest, Stream, Pos + Len + 1, State} end catch _:_ -> fatal_error(bad_charref, State) end; parse_Reference_hex(<>, Stream, Pos, Len, State, Acc) when Char >= $0, Char =< $9; Char >= $a, Char =< $f; Char >= $A, Char =< $F -> parse_Reference_hex(Rest, Stream, Pos, Len + 1, State, Acc); parse_Reference_hex(_, _, _, _, State, _) -> fatal_error(bad_charref, State). % decimal parse until ';' return char parse_Reference_dec(<<>>, _, _, _, #ys_state{in_replacement = true} = State, _) -> fatal_error(unbalanced_reference, State); parse_Reference_dec(<<>>, Stream, Pos, Len, State, Acc) -> Acc1 = ?ACC(Stream, Pos, Len, Acc), {Stream1, State1} = cf(State), parse_Reference_dec(Stream1, Stream1, 0, 0, State1, Acc1); parse_Reference_dec(<<$;/utf8, Rest/bitstring>>, Stream, Pos, Len, State, Acc) -> Acc1 = ?ACC(Stream, Pos, Len, Acc), try case binary_to_integer(to_binary(Acc1)) of Int when Int == 16#9; Int == 16#A; Int == 16#D; Int >= 16#20, Int =< 16#D7FF; Int >= 16#E000, Int =< 16#FFFD; Int >= 16#10000, Int =< 16#10FFFF -> {{dec, <>}, Rest, Stream, Pos + Len + 1, State} end catch _:_ -> fatal_error(bad_charref, {Acc1, State}) end; parse_Reference_dec(<>, Stream, Pos, Len, State, Acc) when Char >= $0, Char =< $9 -> parse_Reference_dec(Rest, Stream, Pos, Len + 1, State, Acc); parse_Reference_dec(_, _, _, _, State, _) -> fatal_error(bad_charref, State). % Name parse until ';' return Name parse_Reference_name(?MATCH, Type) -> case parse_Name(?MATCH) of {Name, <<$;/utf8, Bytes1/bitstring>>, Stream1, Pos1, State1} -> NameValue = resolve_general_entity(Name, State1, Type), {NameValue, Bytes1, Stream1, Pos1 + 1, State1}; {_, _, _, _, State1} -> fatal_error(bad_charref, State1) end. %%---------------------------------------------------------------------- %% Parse a Comment, leading '' %%---------------------------------------------------------------------- parse_Comment(?MATCH) -> {Text, ?MATCH1} = parse_Comment(Bytes, Stream, Pos, 0, State, []), case State#ys_state.comments of _ when hd(State#ys_state.position) == dtd -> {{comment, Text}, ?MATCH1}; false -> State1; true -> yaccety_sax:event_comment(Text, set_state_pos(State1, Bytes1)) end. consume_Comment(?MATCH) -> {_, ?MATCH1} = parse_Comment(Bytes, Stream, Pos, 0, State, []), {?MATCH1}. parse_Comment(<<$\r, $\n, Rest/bitstring>>, Stream, Pos, Len, State, Acc) -> Acc1 = ?ACC(Stream, Pos, Len, Acc), Acc2 = ?APPEND(<<$\n>>, Acc1), ?FUNCTION_NAME(Rest, Stream, Pos + Len + 2, 0, State, Acc2); ?FUNCTION_NAME(<<$\r>>, Stream, Pos, Len, State, Acc) -> Acc1 = ?ACC(Stream, Pos, Len, Acc), Acc2 = ?APPEND(<<$\n>>, Acc1), case cf(State) of {<<$\n, Bytes1/bitstring>> = Stream1, State1} -> ?FUNCTION_NAME(Bytes1, Stream1, 1, 0, State1, Acc2); {Stream1, State1} -> ?FUNCTION_NAME(Stream1, Stream1, 0, 0, State1, Acc2) end; parse_Comment(<<$\r, Rest/bitstring>>, Stream, Pos, Len, State, Acc) -> Acc1 = ?ACC(Stream, Pos, Len, Acc), Acc2 = ?APPEND(<<$\n>>, Acc1), ?FUNCTION_NAME(Rest, Stream, Pos + Len + 1, 0, State, Acc2); parse_Comment(<<>>, _, _, _, #ys_state{in_replacement = true} = State, _) -> fatal_error(unbalanced_reference, State); parse_Comment(<<>>, Stream, Pos, Len, State, Acc) -> Acc1 = ?ACC(Stream, Pos, Len, Acc), {Stream1, State1} = cf(State), parse_Comment(Stream1, Stream1, 0, 0, State1, Acc1); parse_Comment(<<$-/utf8, $-/utf8, $>/utf8, Rest/bitstring>>, Stream, Pos, Len, State, Acc) -> Acc1 = ?ACC(Stream, Pos, Len, Acc), {Acc1, Rest, Stream, Pos + Len + 3, State}; parse_Comment(<<$-/utf8, $-/utf8>>, Stream, Pos, Len, State, Acc) -> Acc1 = ?ACC(Stream, Pos, Len, Acc), {Stream1, State1} = cf(State), parse_Comment_dashdash(Stream1, Stream1, State1, Acc1); parse_Comment(<<$-/utf8, $-/utf8, _/bitstring>>, _, _, _, State, _Acc) -> fatal_error(bad_comment, State); parse_Comment(<<$-/utf8>>, Stream, Pos, Len, State, Acc) -> Acc1 = ?ACC(Stream, Pos, Len, Acc), {Stream1, State1} = cf(State), parse_Comment_dash(Stream1, Stream1, State1, Acc1); ?ONECHAR. parse_Comment_dashdash(<<$>/utf8, Rest/bitstring>>, Stream, State, Acc) -> {Acc, Rest, Stream, 1, State}; parse_Comment_dashdash(_, _, State, _) -> fatal_error(bad_comment, State). parse_Comment_dash(<<$-/utf8, $>/utf8, Rest/bitstring>>, Stream, State, Acc) -> {Acc, Rest, Stream, 2, State}; parse_Comment_dash(<<$-/utf8>>, _, State, Acc) -> {Stream1, State1} = cf(State), parse_Comment_dashdash(Stream1, Stream1, State1, Acc); parse_Comment_dash(<<$-/utf8, _/bitstring>>, _, State, _Acc) -> fatal_error(bad_comment, State); parse_Comment_dash(Bytes, Stream, State, Acc) -> Acc1 = ?APPEND(<<$-/utf8>>, Acc), parse_Comment(Bytes, Stream, 0, 0, State, Acc1). %%---------------------------------------------------------------------- %% Parse a processing-instruction, leading '' Char*)))? '?>' %% [17] PITarget ::= Name - (('X' | 'x') ('M' | 'm') ('L' | 'l')) %%---------------------------------------------------------------------- check_pi_name(<>, State) when X == $x orelse X == $X, M == $m orelse M == $M, L == $l orelse L == $L -> fatal_error(bad_pi, State); check_pi_name(_, _) -> ok. parse_PI(?MATCH) -> {Name, ?MATCH1} = parse_NCName(?MATCH), ok = check_pi_name(Name, State1), {IsWs, ?MATCH2} = maybe_consume_s(?MATCH1), {Data, ?MATCH3} = parse_PI_data(Bytes2, Stream2, Pos2, 0, State2, []), case IsWs of false when Data =/= <<>> -> fatal_error(bad_pi, State); _ when State#ys_state.proc_inst == false -> State3; _ when hd(State#ys_state.position) == dtd -> {{pi, Name, Data}, ?MATCH3}; _ -> yaccety_sax:event_processingInstruction(Name, Data, set_state_pos(State3, Bytes3)) end. parse_PI_data(<<$\r, $\n, Rest/bitstring>>, Stream, Pos, Len, State, Acc) -> Acc1 = ?ACC(Stream, Pos, Len, Acc), Acc2 = ?APPEND(<<$\n>>, Acc1), ?FUNCTION_NAME(Rest, Stream, Pos + Len + 2, 0, State, Acc2); ?FUNCTION_NAME(<<$\r>>, Stream, Pos, Len, State, Acc) -> Acc1 = ?ACC(Stream, Pos, Len, Acc), Acc2 = ?APPEND(<<$\n>>, Acc1), case cf(State) of {<<$\n, Bytes1/bitstring>> = Stream1, State1} -> ?FUNCTION_NAME(Bytes1, Stream1, 1, 0, State1, Acc2); {Stream1, State1} -> ?FUNCTION_NAME(Stream1, Stream1, 0, 0, State1, Acc2) end; parse_PI_data(<<$\r, Rest/bitstring>>, Stream, Pos, Len, State, Acc) -> Acc1 = ?ACC(Stream, Pos, Len, Acc), Acc2 = ?APPEND(<<$\n>>, Acc1), ?FUNCTION_NAME(Rest, Stream, Pos + Len + 1, 0, State, Acc2); parse_PI_data(<<>>, _Stream, _Pos, _Len, #ys_state{in_replacement = true} = State, _Acc) -> fatal_error(unbalanced_reference, State); parse_PI_data(<<>>, Stream, Pos, Len, State, Acc) -> Acc1 = ?ACC(Stream, Pos, Len, Acc), {Stream1, State1} = cf(State), parse_PI_data(Stream1, Stream1, 0, 0, State1, Acc1); parse_PI_data(<<$?, $>, Rest/bitstring>>, Stream, Pos, Len, State, Acc) -> Acc1 = ?ACC(Stream, Pos, Len, Acc), {to_binary(Acc1), Rest, Stream, Pos + 2 + Len, State}; parse_PI_data(<<$?>>, Stream, Pos, Len, State, Acc) -> Acc1 = ?ACC(Stream, Pos, Len, Acc), {Stream1, State1} = cf(State), parse_PI_data_qm(Stream1, Stream1, State1, Acc1); ?ONECHAR. parse_PI_data_qm(<<$>/utf8, Rest/bitstring>>, Stream, State, Acc) -> {to_binary(Acc), Rest, Stream, 1, State}; parse_PI_data_qm(Bytes, Stream, State, Acc) -> Acc1 = ?APPEND(<<$?>>, Acc), parse_PI_data(Bytes, Stream, 0, 0, State, Acc1). %%---------------------------------------------------------------------- %% Parse character data. In content, everything that is not %% (element | Reference | CDSect | PI | Comment) %% params: State %% returns: {CharData, IsWs, NewState} %% [14] CharData ::= [^<&]* - ([^<&]* ']]>' [^<&]*) %%---------------------------------------------------------------------- parse_CharData(?MATCH) -> {{IsWs, Text}, Bytes1, _, _, State1} = parse_CharData_ws(Bytes, Stream, Pos, 0, State, []), IsIgnorable = false, IsCData = false, case State#ys_state.whitespace of false when IsWs == true -> set_state_pos(State1, Bytes1); _ -> yaccety_sax:event_characters( to_binary(Text), IsCData, IsIgnorable, IsWs, set_state_pos(State1, Bytes1) ) end. parse_CharData(?MATCH, Acc) -> {{IsWs, Text}, Bytes1, _, _, State1} = parse_CharData(Bytes, Stream, Pos, 0, State, Acc), IsIgnorable = false, IsCData = false, yaccety_sax:event_characters( to_binary(Text), IsCData, IsIgnorable, IsWs, set_state_pos(State1, Bytes1) ). parse_CharData( <<$\r, $\n, Rest/bitstring>>, Stream, Pos, Len, #ys_state{in_replacement = false} = State, Acc ) -> Acc1 = ?ACC(Stream, Pos, Len, Acc), Acc2 = ?APPEND(<<$\n>>, Acc1), parse_CharData(Rest, Stream, Pos + Len + 2, 0, State, Acc2); ?FUNCTION_NAME(<<$\r>>, Stream, Pos, Len, State, Acc) -> Acc1 = ?ACC(Stream, Pos, Len, Acc), Acc2 = ?APPEND(<<$\n>>, Acc1), case cf(State) of {<<$\n, Bytes1/bitstring>> = Stream1, State1} -> ?FUNCTION_NAME(Bytes1, Stream1, 1, 0, State1, Acc2); {Stream1, State1} -> ?FUNCTION_NAME(Stream1, Stream1, 0, 0, State1, Acc2) end; parse_CharData( <<$\r, Rest/bitstring>>, Stream, Pos, Len, #ys_state{in_replacement = false} = State, Acc ) -> Acc1 = ?ACC(Stream, Pos, Len, Acc), Acc2 = ?APPEND(<<$\n>>, Acc1), parse_CharData(Rest, Stream, Pos + Len + 1, 0, State, Acc2); parse_CharData(<<$\r, Rest/bitstring>>, Stream, Pos, Len, State, Acc) -> parse_CharData(Rest, Stream, Pos, Len + 1, State, Acc); parse_CharData(Bytes = <<$>, Stream, Pos, Len, State, Acc) -> Text = ?ACC(Stream, Pos, Len, Acc), {{false, Text}, Bytes, Stream, Pos + Len, State}; parse_CharData(<<$&/utf8, Rest/bitstring>>, Stream, Pos, Len, State, Acc) -> Acc1 = ?ACC(Stream, Pos, Len, Acc), case parse_Reference(Rest, Stream, Pos + Len + 1, State, text) of {{Name, {replacement_text, Ref}}, Bytes1, _, _, State1} -> RTState = replacement_text_state(Bytes1, State1, Name), ?FUNCTION_NAME(Ref, Ref, 0, 0, RTState, Acc1); {{Type, Ref}, ?MATCH1} when Type == gen; Type == dec; Type == hex -> Acc2 = ?APPEND(Ref, Acc1), ?FUNCTION_NAME(Bytes1, Stream1, Pos1, 0, State1, Acc2); {{Name, Ref}, Bytes1, _, _, State1} -> RTState = replacement_text_state(Bytes1, State1, Name), ?FUNCTION_NAME(Ref, Ref, 0, 0, RTState, Acc1) end; parse_CharData(<<"]]>"/utf8, _/bitstring>>, _, _, _, State, _Acc) -> fatal_error(bad_char_data, State); parse_CharData(<<"]]"/utf8>>, Stream, Pos, Len, State, Acc) -> Acc1 = ?ACC(Stream, Pos, Len, Acc), parse_CharData_bb(cf(State), Acc1); parse_CharData(<<"]"/utf8>>, Stream, Pos, Len, State, Acc) -> Acc1 = ?ACC(Stream, Pos, Len, Acc), parse_CharData_b(cf(State), Acc1); ?ONECHAR. parse_CharData_bb({<<$>, _/bitstring>>, State}, _Acc) -> fatal_error(bad_char_data, State); parse_CharData_bb({<<"]>", _/bitstring>>, State}, _Acc) -> fatal_error(bad_char_data, State); parse_CharData_bb({<<"]">>, State}, Acc) -> Acc1 = ?APPEND(<<"]">>, Acc), parse_CharData_bb(cf(State), Acc1); parse_CharData_bb({Bytes, State}, Acc) -> Acc1 = ?APPEND(<<"]]">>, Acc), parse_CharData(Bytes, Bytes, 0, 0, State, Acc1). parse_CharData_b({<<"]>", _/bitstring>>, State}, _Acc) -> fatal_error(bad_char_data, State); parse_CharData_b({<<"]">>, State}, Acc) -> parse_CharData_bb(cf(State), Acc); parse_CharData_b({Bytes, State}, Acc) -> Acc1 = ?APPEND(<<"]">>, Acc), parse_CharData(Bytes, Bytes, 0, 0, State, Acc1). parse_CharData_ws(<<$\s, $\s, $\s, $\s, Rest/bitstring>>, Stream, Pos, Len, State, Acc) -> parse_CharData_ws(Rest, Stream, Pos, Len + 4, State, Acc); parse_CharData_ws(<<$\t, $\t, $\t, $\t, Rest/bitstring>>, Stream, Pos, Len, State, Acc) -> parse_CharData_ws(Rest, Stream, Pos, Len + 4, State, Acc); parse_CharData_ws(<<$\s, $\s, $\s, Rest/bitstring>>, Stream, Pos, Len, State, Acc) -> parse_CharData_ws(Rest, Stream, Pos, Len + 3, State, Acc); parse_CharData_ws(<<$\t, $\t, $\t, Rest/bitstring>>, Stream, Pos, Len, State, Acc) -> parse_CharData_ws(Rest, Stream, Pos, Len + 3, State, Acc); parse_CharData_ws(<<$\s, $\s, Rest/bitstring>>, Stream, Pos, Len, State, Acc) -> parse_CharData_ws(Rest, Stream, Pos, Len + 2, State, Acc); parse_CharData_ws(<<$\t, $\t, Rest/bitstring>>, Stream, Pos, Len, State, Acc) -> parse_CharData_ws(Rest, Stream, Pos, Len + 2, State, Acc); parse_CharData_ws( <<$\r, $\n, Rest/bitstring>>, Stream, Pos, Len, #ys_state{in_replacement = false} = State, Acc ) -> Acc1 = ?ACC(Stream, Pos, Len, Acc), Acc2 = ?APPEND(<<$\n>>, Acc1), parse_CharData_ws(Rest, Stream, Pos + Len + 2, 0, State, Acc2); ?FUNCTION_NAME(<<$\r>>, Stream, Pos, Len, State, Acc) -> Acc1 = ?ACC(Stream, Pos, Len, Acc), Acc2 = ?APPEND(<<$\n>>, Acc1), case cf(State) of {<<$\n, Bytes1/bitstring>> = Stream1, State1} -> ?FUNCTION_NAME(Bytes1, Stream1, 1, 0, State1, Acc2); {Stream1, State1} -> ?FUNCTION_NAME(Stream1, Stream1, 0, 0, State1, Acc2) end; parse_CharData_ws( <<$\r, Rest/bitstring>>, Stream, Pos, Len, #ys_state{in_replacement = false} = State, Acc ) -> Acc1 = ?ACC(Stream, Pos, Len, Acc), Acc2 = ?APPEND(<<$\n>>, Acc1), parse_CharData_ws(Rest, Stream, Pos + 1, 0, State, Acc2); parse_CharData_ws(<<$\r, Rest/bitstring>>, Stream, Pos, Len, State, Acc) -> parse_CharData_ws(Rest, Stream, Pos, Len + 1, State, Acc); parse_CharData_ws(<>, Stream, Pos, Len, State, Acc) when ?WS(Char) -> parse_CharData_ws(Rest, Stream, Pos, Len + 1, State, Acc); parse_CharData_ws(Bytes = <<$<, _/bitstring>>, Stream, Pos, Len, State, Acc) -> Text = ?ACC(Stream, Pos, Len, Acc), {{true, Text}, Bytes, Stream, Pos + Len, State}; parse_CharData_ws(<<$&, Rest/bitstring>>, Stream, Pos, Len, State, Acc) -> Acc1 = ?ACC(Stream, Pos, Len, Acc), case parse_Reference(Rest, Stream, Pos + Len + 1, State, text) of {{Name, {replacement_text, Ref}}, Bytes1, _, _, State1} -> RTState = replacement_text_state(Bytes1, State1, Name), ?FUNCTION_NAME(Ref, Ref, 0, 0, RTState, Acc1); {{Type, <> = Ref}, ?MATCH1} when Type == dec orelse Type == hex, ?WS(Char) -> Acc2 = ?APPEND(Ref, Acc1), ?FUNCTION_NAME(Bytes1, Stream1, Pos1, 0, State1, Acc2); {{Type, Ref}, ?MATCH1} when Type == dec orelse Type == hex -> Acc2 = ?APPEND(Ref, Acc1), ?FUNCTION_NAME(Bytes1, Stream1, Pos1, 0, State1, Acc2); {{gen, Ref}, ?MATCH1} -> Acc2 = ?APPEND(Ref, Acc1), parse_CharData(Bytes1, Stream1, Pos1, 0, State1, Acc2); {{Name, Ref}, Bytes1, _, _, State1} -> RTState = replacement_text_state(Bytes1, State1, Name), ?FUNCTION_NAME(Ref, Ref, 0, 0, RTState, Acc1) end; parse_CharData_ws(<<>>, Stream, Pos, Len, State, Acc) -> Acc1 = ?ACC(Stream, Pos, Len, Acc), {Stream1, State1} = cf(State), parse_CharData_ws(Stream1, Stream1, 0, 0, State1, Acc1); parse_CharData_ws(Bytes, Stream, Pos, Len, State, Acc) -> parse_CharData(Bytes, Stream, Pos, Len, State, Acc). %%---------------------------------------------------------------------- %% [18] CDSect ::= CDStart CData CDEnd %% [19] CDStart ::= '' Char*)) %% [21] CDEnd ::= ']]>' %% Parse CDATA Section. '>, Stream, Pos, State) -> parse_CData(Rest, Stream, Pos + 6, State); parse_CDSect(<<"CDATA"/utf8>>, _, _, State) -> {Stream1, State1} = cf(State), parse_CDSect_bcdata(Stream1, State1); parse_CDSect(<<"CDAT"/utf8>>, _, _, State) -> {Stream1, State1} = cf(State), parse_CDSect_bcdat(Stream1, State1); parse_CDSect(<<"CDA"/utf8>>, _, _, State) -> {Stream1, State1} = cf(State), parse_CDSect_bcda(Stream1, State1); parse_CDSect(<<"CD"/utf8>>, _, _, State) -> {Stream1, State1} = cf(State), parse_CDSect_bcd(Stream1, State1); parse_CDSect(<<"C"/utf8>>, _, _, State) -> {Stream1, State1} = cf(State), parse_CDSect_bc(Stream1, State1); parse_CDSect(<<>>, _, _, State) -> {Stream1, State1} = cf(State), parse_CDSect(Stream1, Stream1, 0, State1); parse_CDSect(_, _, _, State) -> fatal_error(bad_cdata, State). parse_CDSect_bc(<<"DATA["/utf8, Rest/bitstring>> = Stream, State) -> parse_CData(Rest, Stream, 5, State); parse_CDSect_bc(<<"DATA"/utf8>>, State) -> {Stream1, State1} = cf(State), parse_CDSect_bcdata(Stream1, State1); parse_CDSect_bc(<<"DAT"/utf8>>, State) -> {Stream1, State1} = cf(State), parse_CDSect_bcdat(Stream1, State1); parse_CDSect_bc(<<"DA"/utf8>>, State) -> {Stream1, State1} = cf(State), parse_CDSect_bcda(Stream1, State1); parse_CDSect_bc(<<"D"/utf8>>, State) -> {Stream1, State1} = cf(State), parse_CDSect_bcd(Stream1, State1); parse_CDSect_bc(_, State) -> fatal_error(bad_cdata, State). parse_CDSect_bcd(<<"ATA["/utf8, Rest/bitstring>> = Stream, State) -> parse_CData(Rest, Stream, 4, State); parse_CDSect_bcd(<<"ATA"/utf8>>, State) -> {Stream1, State1} = cf(State), parse_CDSect_bcdata(Stream1, State1); parse_CDSect_bcd(<<"AT"/utf8>>, State) -> {Stream1, State1} = cf(State), parse_CDSect_bcdat(Stream1, State1); parse_CDSect_bcd(<<"A"/utf8>>, State) -> {Stream1, State1} = cf(State), parse_CDSect_bcda(Stream1, State1); parse_CDSect_bcd(_, State) -> fatal_error(bad_cdata, State). parse_CDSect_bcda(<<"TA["/utf8, Rest/bitstring>> = Stream, State) -> parse_CData(Rest, Stream, 3, State); parse_CDSect_bcda(<<"TA"/utf8>>, State) -> {Stream1, State1} = cf(State), parse_CDSect_bcdata(Stream1, State1); parse_CDSect_bcda(<<"T"/utf8>>, State) -> {Stream1, State1} = cf(State), parse_CDSect_bcdat(Stream1, State1); parse_CDSect_bcda(_, State) -> fatal_error(bad_cdata, State). parse_CDSect_bcdat(<<"A["/utf8, Rest/bitstring>> = Stream, State) -> parse_CData(Rest, Stream, 2, State); parse_CDSect_bcdat(<<"A"/utf8>>, State) -> {Stream1, State1} = cf(State), parse_CDSect_bcdata(Stream1, State1); parse_CDSect_bcdat(_, State) -> fatal_error(bad_cdata, State). parse_CDSect_bcdata(<<"["/utf8, Rest/bitstring>> = Stream, State) -> parse_CData(Rest, Stream, 1, State); parse_CDSect_bcdata(_, State) -> fatal_error(bad_cdata, State). parse_CData(Rest, Stream, Pos, State) -> {Text, Bytes1, _, _, State1} = parse_CData(Rest, Stream, Pos, 0, State, []), yaccety_sax:event_characters( to_binary(Text), true, false, false, set_state_pos(State1, Bytes1) ). parse_CData(<<$\r, $\n, Rest/bitstring>>, Stream, Pos, Len, State, Acc) -> Acc1 = ?ACC(Stream, Pos, Len, Acc), Acc2 = ?APPEND(<<$\n>>, Acc1), ?FUNCTION_NAME(Rest, Stream, Pos + Len + 2, 0, State, Acc2); ?FUNCTION_NAME(<<$\r>>, Stream, Pos, Len, State, Acc) -> Acc1 = ?ACC(Stream, Pos, Len, Acc), Acc2 = ?APPEND(<<$\n>>, Acc1), case cf(State) of {<<$\n, Bytes1/bitstring>> = Stream1, State1} -> ?FUNCTION_NAME(Bytes1, Stream1, 1, 0, State1, Acc2); {Stream1, State1} -> ?FUNCTION_NAME(Stream1, Stream1, 0, 0, State1, Acc2) end; parse_CData(<<$\r, Rest/bitstring>>, Stream, Pos, Len, State, Acc) -> Acc1 = ?ACC(Stream, Pos, Len, Acc), Acc2 = ?APPEND(<<$\n>>, Acc1), ?FUNCTION_NAME(Rest, Stream, Pos + Len + 1, 0, State, Acc2); parse_CData(<<"]]>"/utf8, Rest/bitstring>>, Stream, Pos, Len, State, Acc) -> Text = ?ACC(Stream, Pos, Len, Acc), {Text, Rest, Stream, Pos + Len + 3, State}; parse_CData(<<"]]"/utf8>>, Stream, Pos, Len, State, Acc) -> Acc1 = ?ACC(Stream, Pos, Len, Acc), {Stream1, State1} = cf(State), parse_CData_bb(Stream1, State1, Acc1); parse_CData(<<"]"/utf8>>, Stream, Pos, Len, State, Acc) -> Acc1 = ?ACC(Stream, Pos, Len, Acc), {Stream1, State1} = cf(State), parse_CData_b(Stream1, State1, Acc1); parse_CData(<<>>, _, _, _, #ys_state{in_replacement = true} = State, _) -> fatal_error(unbalanced_reference, State); ?ONECHAR. parse_CData_b(<<"]>"/utf8, Rest/bitstring>> = Stream, State, Acc) -> {Acc, Rest, Stream, 2, State}; parse_CData_b(<<"]"/utf8>>, State, Acc) -> {Stream1, State1} = cf(State), parse_CData_bb(Stream1, State1, Acc); parse_CData_b(<<>>, State, Acc) -> {Stream1, State1} = cf(State), parse_CData_b(Stream1, State1, Acc); parse_CData_b(Stream, State, Acc) -> Acc1 = ?APPEND(<<"]"/utf8>>, Acc), parse_CData(Stream, Stream, 0, 0, State, Acc1). parse_CData_bb(<<"]"/utf8, Rest/bitstring>>, State, Acc) -> Acc1 = ?APPEND(<<"]"/utf8>>, Acc), parse_CData_bb(Rest, State, Acc1); parse_CData_bb(<<">"/utf8, Rest/bitstring>> = Stream, State, Acc) -> {Acc, Rest, Stream, 1, State}; parse_CData_bb(<<>>, State, Acc) -> {Stream1, State1} = cf(State), parse_CData_bb(Stream1, State1, Acc); parse_CData_bb(Stream, State, Acc) -> Acc1 = ?APPEND(<<"]]"/utf8>>, Acc), parse_CData(Stream, Stream, 0, 0, State, Acc1). %%---------------------------------------------------------------------- %% [80] EncodingDecl ::= S 'encoding' Eq ('"' EncName '"' | "'" EncName "'" ) %%---------------------------------------------------------------------- parse_EncodingDecl(?MATCH) -> parse_EncodingDeclS(?MATCH). parse_EncodingDeclS(<<"encoding"/utf8, Rest/bitstring>>, Stream, Pos, State) -> parse_EncodingDecl_encoding(Rest, Stream, Pos + 8, State); parse_EncodingDeclS(<<"encodin"/utf8>>, _, _, State) -> parse_EncodingDecl_encodin(cf(State)); parse_EncodingDeclS(<<"encodi"/utf8>>, _, _, State) -> parse_EncodingDecl_encodi(cf(State)); parse_EncodingDeclS(<<"encod"/utf8>>, _, _, State) -> parse_EncodingDecl_encod(cf(State)); parse_EncodingDeclS(<<"enco"/utf8>>, _, _, State) -> parse_EncodingDecl_enco(cf(State)); parse_EncodingDeclS(<<"enc"/utf8>>, _, _, State) -> parse_EncodingDecl_enc(cf(State)); parse_EncodingDeclS(<<"en"/utf8>>, _, _, State) -> parse_EncodingDecl_en(cf(State)); parse_EncodingDeclS(<<"e"/utf8>>, _, _, State) -> parse_EncodingDecl_e(cf(State)); parse_EncodingDeclS(<<>>, _, _, State) -> {Stream1, State1} = cf(State), parse_EncodingDeclS(Stream1, Stream1, 0, State1); parse_EncodingDeclS(?MATCH) -> % no encoding {{<<"UTF-8">>, false}, ?MATCH}. parse_EncodingDecl_e({<<"ncoding"/utf8, Rest/bitstring>> = Stream, State}) -> parse_EncodingDecl_encoding(Rest, Stream, 7, State); parse_EncodingDecl_e({<<"ncodin"/utf8>>, State}) -> parse_EncodingDecl_encodin(cf(State)); parse_EncodingDecl_e({<<"ncodi"/utf8>>, State}) -> parse_EncodingDecl_encodi(cf(State)); parse_EncodingDecl_e({<<"ncod"/utf8>>, State}) -> parse_EncodingDecl_encod(cf(State)); parse_EncodingDecl_e({<<"nco"/utf8>>, State}) -> parse_EncodingDecl_enco(cf(State)); parse_EncodingDecl_e({<<"nc"/utf8>>, State}) -> parse_EncodingDecl_enc(cf(State)); parse_EncodingDecl_e({<<"n"/utf8>>, State}) -> parse_EncodingDecl_en(cf(State)); parse_EncodingDecl_e({_, State}) -> fatal_error(bad_encoding, State). parse_EncodingDecl_en({<<"coding"/utf8, Rest/bitstring>> = Stream, State}) -> parse_EncodingDecl_encoding(Rest, Stream, 6, State); parse_EncodingDecl_en({<<"codin"/utf8>>, State}) -> parse_EncodingDecl_encodin(cf(State)); parse_EncodingDecl_en({<<"codi"/utf8>>, State}) -> parse_EncodingDecl_encodi(cf(State)); parse_EncodingDecl_en({<<"cod"/utf8>>, State}) -> parse_EncodingDecl_encod(cf(State)); parse_EncodingDecl_en({<<"co"/utf8>>, State}) -> parse_EncodingDecl_enco(cf(State)); parse_EncodingDecl_en({<<"c"/utf8>>, State}) -> parse_EncodingDecl_enc(cf(State)); parse_EncodingDecl_en({_, State}) -> fatal_error(bad_encoding, State). parse_EncodingDecl_enc({<<"oding"/utf8, Rest/bitstring>> = Stream, State}) -> parse_EncodingDecl_encoding(Rest, Stream, 5, State); parse_EncodingDecl_enc({<<"odin"/utf8>>, State}) -> parse_EncodingDecl_encodin(cf(State)); parse_EncodingDecl_enc({<<"odi"/utf8>>, State}) -> parse_EncodingDecl_encodi(cf(State)); parse_EncodingDecl_enc({<<"od"/utf8>>, State}) -> parse_EncodingDecl_encod(cf(State)); parse_EncodingDecl_enc({<<"o"/utf8>>, State}) -> parse_EncodingDecl_enco(cf(State)); parse_EncodingDecl_enc({_, State}) -> fatal_error(bad_encoding, State). parse_EncodingDecl_enco({<<"ding"/utf8, Rest/bitstring>> = Stream, State}) -> parse_EncodingDecl_encoding(Rest, Stream, 4, State); parse_EncodingDecl_enco({<<"din"/utf8>>, State}) -> parse_EncodingDecl_encodin(cf(State)); parse_EncodingDecl_enco({<<"di"/utf8>>, State}) -> parse_EncodingDecl_encodi(cf(State)); parse_EncodingDecl_enco({<<"d"/utf8>>, State}) -> parse_EncodingDecl_encod(cf(State)); parse_EncodingDecl_enco({_, State}) -> fatal_error(bad_encoding, State). parse_EncodingDecl_encod({<<"ing"/utf8, Rest/bitstring>> = Stream, State}) -> parse_EncodingDecl_encoding(Rest, Stream, 3, State); parse_EncodingDecl_encod({<<"in"/utf8>>, State}) -> parse_EncodingDecl_encodin(cf(State)); parse_EncodingDecl_encod({<<"i"/utf8>>, State}) -> parse_EncodingDecl_encodi(cf(State)); parse_EncodingDecl_encod({_, State}) -> fatal_error(bad_encoding, State). parse_EncodingDecl_encodi({<<"ng"/utf8, Rest/bitstring>> = Stream, State}) -> parse_EncodingDecl_encoding(Rest, Stream, 2, State); parse_EncodingDecl_encodi({<<"n"/utf8>>, State}) -> parse_EncodingDecl_encodin(cf(State)); parse_EncodingDecl_encodi({_, State}) -> fatal_error(bad_encoding, State). parse_EncodingDecl_encodin({<<"g"/utf8, Rest/bitstring>> = Stream, State}) -> parse_EncodingDecl_encoding(Rest, Stream, 1, State); parse_EncodingDecl_encodin({_, State}) -> fatal_error(bad_encoding, State). parse_EncodingDecl_encoding(?MATCH) -> {?MATCH1} = parse_Eq(?MATCH), parse_EncodingDecl_EncName(?MATCH1). parse_EncodingDecl_EncName(<<$'/utf8, Rest/bitstring>>, Stream, Pos, State) -> parse_EncodingDecl_EncName_sq(Rest, Stream, Pos + 1, State); parse_EncodingDecl_EncName(<<$"/utf8, Rest/bitstring>>, Stream, Pos, State) -> parse_EncodingDecl_EncName_dq(Rest, Stream, Pos + 1, State); parse_EncodingDecl_EncName(_, _, _, State) -> fatal_error(bad_encoding, State). parse_EncodingDecl_EncName_sq(?MATCH) -> case parse_EncodingDecl_EncName_name(?MATCH) of {Name, <<$'/utf8, Rest/bitstring>>, Stream1, Pos1, State1} -> {{Name, true}, Rest, Stream1, Pos1 + 1, State1}; {_, _, _, _, State1} -> fatal_error(bad_encoding, State1) end. parse_EncodingDecl_EncName_dq(?MATCH) -> case parse_EncodingDecl_EncName_name(?MATCH) of {Name, <<$"/utf8, Rest/bitstring>>, Stream1, Pos1, State1} -> {{Name, true}, Rest, Stream1, Pos1 + 1, State1}; {_, _, _, _, State1} -> fatal_error(bad_encoding, State1) end. %%---------------------------------------------------------------------- %% [81] EncName ::= [A-Za-z] ([A-Za-z0-9._] | '-')* %% /* Encoding name contains only Latin characters */ %%---------------------------------------------------------------------- parse_EncodingDecl_EncName_name(<<>>, _, _, State) -> {Stream1, State1} = cf(State), parse_EncodingDecl_EncName_name(Stream1, Stream1, 0, State1); parse_EncodingDecl_EncName_name(<>, Stream, Pos, State) when Char >= $A andalso Char =< $Z; Char >= $a andalso Char =< $z -> parse_EncodingDecl_EncName_name_1(Rest, Stream, Pos, 1, State, []); parse_EncodingDecl_EncName_name(_, _, _, State) -> fatal_error(bad_char, State). parse_EncodingDecl_EncName_name_1(<<>>, Stream, Pos, Len, State, Acc) -> Acc1 = ?ACC(Stream, Pos, Len, Acc), {Stream1, State1} = cf(State), parse_EncodingDecl_EncName_name_1(Stream1, Stream1, 0, 0, State1, Acc1); parse_EncodingDecl_EncName_name_1(<>, Stream, Pos, Len, State, Acc) when Char >= $A andalso Char =< $Z; Char >= $a andalso Char =< $z; Char >= $0 andalso Char =< $9; Char == $.; Char == $_; Char == $- -> parse_EncodingDecl_EncName_name_1(Rest, Stream, Pos, Len + 1, State, Acc); parse_EncodingDecl_EncName_name_1(Bytes, Stream, Pos, Len, State, Acc) -> Acc1 = ?ACC(Stream, Pos, Len, Acc), {Acc1, Bytes, Stream, Pos + Len, State}. %%---------------------------------------------------------------------- %% [25] Eq ::= S? '=' S? %%---------------------------------------------------------------------- parse_Eq(?MATCH) -> {_Found, ?MATCH1} = maybe_consume_s(?MATCH), parse_Eq_1(?MATCH1). parse_Eq_1(<<$=/utf8, Rest/bitstring>>, Stream, Pos, State) -> {_Found, ?MATCH1} = maybe_consume_s(Rest, Stream, Pos + 1, State), {?MATCH1}; parse_Eq_1(_, _, _, State) -> fatal_error(bad_eq, State). %%---------------------------------------------------------------------- %% [26] VersionNum ::= '1.' [0-9]+ %%---------------------------------------------------------------------- parse_VersionNum_sq(<<$1/utf8, $./utf8, Rest/bitstring>>, Stream, Pos, State) -> parse_VersionNum_digit_sq(Rest, Stream, Pos + 2, 0, State, []); parse_VersionNum_sq(<<$1/utf8>>, _, _, State) -> {Stream1, State1} = cf(State), parse_VersionNum_1_sq(Stream1, State1); parse_VersionNum_sq(<<>>, _, _, State) -> {Stream1, State1} = cf(State), parse_VersionNum_sq(Stream1, Stream1, 0, State1); parse_VersionNum_sq(_, _, _, State) -> fatal_error(bad_version_num, State). parse_VersionNum_1_sq(<<$./utf8, Rest/bitstring>> = Stream, State) -> parse_VersionNum_digit_sq(Rest, Stream, 1, 0, State, []); parse_VersionNum_1_sq(_, State) -> fatal_error(bad_version_num, State). parse_VersionNum_digit_sq(<<>>, Stream, Pos, Len, State, Acc) -> Acc1 = ?ACC(Stream, Pos, Len, Acc), {Stream1, State1} = cf(State), parse_VersionNum_digit_sq(Stream1, Stream1, 0, 0, State1, Acc1); parse_VersionNum_digit_sq(<>, Stream, Pos, Len, State, Acc) when Char >= $0 andalso Char =< $9 -> parse_VersionNum_digit_sq(Rest, Stream, Pos, Len + 1, State, Acc); parse_VersionNum_digit_sq(<<$'/utf8, Rest/bitstring>>, Stream, Pos, Len, State, Acc) -> Acc1 = ?ACC(Stream, Pos, Len, Acc), {{version_to_number(Acc1, State), true}, Rest, Stream, Pos + Len + 1, State}; parse_VersionNum_digit_sq(_, _, _, _, State, _) -> fatal_error(bad_version_num, State). parse_VersionNum_dq(<<$1/utf8, $./utf8, Rest/bitstring>>, Stream, Pos, State) -> parse_VersionNum_digit_dq(Rest, Stream, Pos + 2, 0, State, []); parse_VersionNum_dq(<<$1/utf8>>, _, _, State) -> {Stream1, State1} = cf(State), parse_VersionNum_1_dq(Stream1, State1); parse_VersionNum_dq(<<>>, _, _, State) -> {Stream1, State1} = cf(State), parse_VersionNum_dq(Stream1, Stream1, 0, State1); parse_VersionNum_dq(_, _, _, State) -> fatal_error(bad_version_num, State). parse_VersionNum_1_dq(<<$./utf8, Rest/bitstring>> = Stream, State) -> parse_VersionNum_digit_dq(Rest, Stream, 1, 0, State, []); parse_VersionNum_1_dq(_, State) -> fatal_error(bad_version_num, State). parse_VersionNum_digit_dq(<<>>, Stream, Pos, Len, State, Acc) -> Acc1 = ?ACC(Stream, Pos, Len, Acc), {Stream1, State1} = cf(State), parse_VersionNum_digit_dq(Stream1, Stream1, 0, 0, State1, Acc1); parse_VersionNum_digit_dq(<>, Stream, Pos, Len, State, Acc) when Char >= $0 andalso Char =< $9 -> parse_VersionNum_digit_dq(Rest, Stream, Pos, Len + 1, State, Acc); parse_VersionNum_digit_dq(<<$\"/utf8, Rest/bitstring>>, Stream, Pos, Len, State, Acc) -> Acc1 = ?ACC(Stream, Pos, Len, Acc), {{version_to_number(Acc1, State), true}, Rest, Stream, Pos + Len + 1, State}; parse_VersionNum_digit_dq(_, _, _, _, State, _) -> fatal_error(bad_version_num, State). version_to_number(Acc, State) -> case to_binary([<<"1."/utf8>> | Acc]) of <<"1."/utf8>> -> fatal_error(bad_version_num, State); Bin -> Bin end. %%---------------------------------------------------------------------- %% [24] VersionInfo ::= S 'version' Eq ("'" VersionNum "'" | '"' VersionNum '"') %%---------------------------------------------------------------------- parse_VersionInfo(?MATCH) -> {Found, ?MATCH1} = maybe_consume_s(?MATCH), case Found of true -> parse_VersionInfoS(?MATCH1); false -> {{<<>>, false}, ?MATCH1} end. parse_VersionInfo_version(?MATCH) -> case parse_Eq(?MATCH) of {<<$'/utf8, Bytes1/bitstring>>, Stream1, Pos1, State1} -> parse_VersionNum_sq(Bytes1, Stream1, Pos1 + 1, State1); {<<$\"/utf8, Bytes1/bitstring>>, Stream1, Pos1, State1} -> parse_VersionNum_dq(Bytes1, Stream1, Pos1 + 1, State1); {_, _, _, State1} -> fatal_error(bad_version, State1) end. parse_VersionInfoS(<<"version"/utf8, Rest/bitstring>>, Stream, Pos, State) -> parse_VersionInfo_version(Rest, Stream, Pos + 7, State); parse_VersionInfoS(<<"versio"/utf8>>, _, _, State) -> parse_VersionInfo_versio(cf(State)); parse_VersionInfoS(<<"versi"/utf8>>, _, _, State) -> parse_VersionInfo_versi(cf(State)); parse_VersionInfoS(<<"vers"/utf8>>, _, _, State) -> parse_VersionInfo_vers(cf(State)); parse_VersionInfoS(<<"ver"/utf8>>, _, _, State) -> parse_VersionInfo_ver(cf(State)); parse_VersionInfoS(<<"ve"/utf8>>, _, _, State) -> parse_VersionInfo_ve(cf(State)); parse_VersionInfoS(<<"v"/utf8>>, _, _, State) -> parse_VersionInfo_v(cf(State)); parse_VersionInfoS(<<>>, _, _, State) -> {Stream1, State1} = cf(State), parse_VersionInfoS(Stream1, Stream1, 0, State1); parse_VersionInfoS(?MATCH) -> {{<<>>, false}, ?MATCH}. parse_VersionInfo_v({<<"ersion"/utf8, Rest/bitstring>> = Stream, State}) -> parse_VersionInfo_version(Rest, Stream, 6, State); parse_VersionInfo_v({<<"ersio"/utf8>>, State}) -> parse_VersionInfo_versio(cf(State)); parse_VersionInfo_v({<<"ersi"/utf8>>, State}) -> parse_VersionInfo_versi(cf(State)); parse_VersionInfo_v({<<"ers"/utf8>>, State}) -> parse_VersionInfo_vers(cf(State)); parse_VersionInfo_v({<<"er"/utf8>>, State}) -> parse_VersionInfo_ver(cf(State)); parse_VersionInfo_v({<<"e"/utf8>>, State}) -> parse_VersionInfo_ve(cf(State)); parse_VersionInfo_v({_, State}) -> fatal_error(bad_version_num, State). parse_VersionInfo_ve({<<"rsion"/utf8, Rest/bitstring>> = Stream, State}) -> parse_VersionInfo_version(Rest, Stream, 5, State); parse_VersionInfo_ve({<<"rsio"/utf8>>, State}) -> parse_VersionInfo_versio(cf(State)); parse_VersionInfo_ve({<<"rsi"/utf8>>, State}) -> parse_VersionInfo_versi(cf(State)); parse_VersionInfo_ve({<<"rs"/utf8>>, State}) -> parse_VersionInfo_vers(cf(State)); parse_VersionInfo_ve({<<"r"/utf8>>, State}) -> parse_VersionInfo_ver(cf(State)); parse_VersionInfo_ve({_, State}) -> fatal_error(bad_version_num, State). parse_VersionInfo_ver({<<"sion"/utf8, Rest/bitstring>> = Stream, State}) -> parse_VersionInfo_version(Rest, Stream, 4, State); parse_VersionInfo_ver({<<"sio"/utf8>>, State}) -> parse_VersionInfo_versio(cf(State)); parse_VersionInfo_ver({<<"si"/utf8>>, State}) -> parse_VersionInfo_versi(cf(State)); parse_VersionInfo_ver({<<"s"/utf8>>, State}) -> parse_VersionInfo_vers(cf(State)); parse_VersionInfo_ver({_, State}) -> fatal_error(bad_version_num, State). parse_VersionInfo_vers({<<"ion"/utf8, Rest/bitstring>> = Stream, State}) -> parse_VersionInfo_version(Rest, Stream, 3, State); parse_VersionInfo_vers({<<"io"/utf8>>, State}) -> parse_VersionInfo_versio(cf(State)); parse_VersionInfo_vers({<<"i"/utf8>>, State}) -> parse_VersionInfo_versi(cf(State)); parse_VersionInfo_vers({_, State}) -> fatal_error(bad_version_num, State). parse_VersionInfo_versi({<<"on"/utf8, Rest/bitstring>> = Stream, State}) -> parse_VersionInfo_version(Rest, Stream, 2, State); parse_VersionInfo_versi({<<"o"/utf8>>, State}) -> parse_VersionInfo_versio(cf(State)); parse_VersionInfo_versi({_, State}) -> fatal_error(bad_version_num, State). parse_VersionInfo_versio({<<"n"/utf8, Rest/bitstring>> = Stream, State}) -> parse_VersionInfo_version(Rest, Stream, 1, State); parse_VersionInfo_versio({_, State}) -> fatal_error(bad_version_num, State). %%---------------------------------------------------------------------- %% [32] SDDecl ::= S 'standalone' Eq (("'" ('yes' | 'no') "'") | ('"' ('yes' | 'no') '"')) %% leading space is trimmed already %%---------------------------------------------------------------------- parse_SDDecl_standalone(?MATCH) -> {?MATCH1} = parse_Eq(?MATCH), parse_SDDecl_standalone_yesno(?MATCH1). parse_SDDecl_standalone_yesno(<<$'/utf8, Rest/bitstring>>, Stream, Pos, State) -> parse_SDDecl_standalone_yesno_sq(Rest, Stream, Pos + 1, State); parse_SDDecl_standalone_yesno(<<$"/utf8, Rest/bitstring>>, Stream, Pos, State) -> parse_SDDecl_standalone_yesno_dq(Rest, Stream, Pos + 1, State); parse_SDDecl_standalone_yesno(<<>>, _, _, State) -> {Stream1, State1} = cf(State), parse_SDDecl_standalone_yesno(Stream1, Stream1, 0, State1); parse_SDDecl_standalone_yesno(_, _, _, State) -> fatal_error(bad_standalone, State). parse_SDDecl_standalone_yesno_sq(<<"no'"/utf8, Rest/bitstring>>, Stream, Pos, State) -> {{false, true}, Rest, Stream, Pos + 3, State}; parse_SDDecl_standalone_yesno_sq(<<"no"/utf8>>, _, _, State) -> parse_SDDecl_standalone_yesno_sq_no(cf(State)); parse_SDDecl_standalone_yesno_sq(<<"n"/utf8>>, _, _, State) -> parse_SDDecl_standalone_yesno_sq_n(cf(State)); parse_SDDecl_standalone_yesno_sq(<<"yes'"/utf8, Rest/bitstring>>, Stream, Pos, State) -> {{true, true}, Rest, Stream, Pos + 4, State}; parse_SDDecl_standalone_yesno_sq(<<"yes"/utf8>>, _, _, State) -> parse_SDDecl_standalone_yesno_sq_yes(cf(State)); parse_SDDecl_standalone_yesno_sq(<<"ye"/utf8>>, _, _, State) -> parse_SDDecl_standalone_yesno_sq_ye(cf(State)); parse_SDDecl_standalone_yesno_sq(<<"y"/utf8>>, _, _, State) -> parse_SDDecl_standalone_yesno_sq_y(cf(State)); parse_SDDecl_standalone_yesno_sq(<<>>, _, _, State) -> {Stream1, State1} = cf(State), parse_SDDecl_standalone_yesno_sq(Stream1, Stream1, 0, State1). parse_SDDecl_standalone_yesno_sq_y({<<"es'"/utf8, Rest/bitstring>> = Stream, State}) -> {{true, true}, Rest, Stream, 3, State}; parse_SDDecl_standalone_yesno_sq_y({<<"es"/utf8>>, State}) -> parse_SDDecl_standalone_yesno_sq_yes(cf(State)); parse_SDDecl_standalone_yesno_sq_y({<<"e"/utf8>>, State}) -> parse_SDDecl_standalone_yesno_sq_ye(cf(State)); parse_SDDecl_standalone_yesno_sq_y({_, State}) -> fatal_error(bad_standalone, State). parse_SDDecl_standalone_yesno_sq_ye({<<"s'"/utf8, Rest/bitstring>> = Stream, State}) -> {{true, true}, Rest, Stream, 2, State}; parse_SDDecl_standalone_yesno_sq_ye({<<"s"/utf8>>, State}) -> parse_SDDecl_standalone_yesno_sq_yes(cf(State)); parse_SDDecl_standalone_yesno_sq_ye({_, State}) -> fatal_error(bad_standalone, State). parse_SDDecl_standalone_yesno_sq_yes({<<"'"/utf8, Rest/bitstring>> = Stream, State}) -> {{true, true}, Rest, Stream, 1, State}; parse_SDDecl_standalone_yesno_sq_yes({_, State}) -> fatal_error(bad_standalone, State). parse_SDDecl_standalone_yesno_dq(<<"no\""/utf8, Rest/bitstring>>, Stream, Pos, State) -> {{false, true}, Rest, Stream, Pos + 3, State}; parse_SDDecl_standalone_yesno_dq(<<"no"/utf8>>, _, _, State) -> parse_SDDecl_standalone_yesno_dq_no(cf(State)); parse_SDDecl_standalone_yesno_dq(<<"n"/utf8>>, _, _, State) -> parse_SDDecl_standalone_yesno_dq_n(cf(State)); parse_SDDecl_standalone_yesno_dq(<<"yes\""/utf8, Rest/bitstring>>, Stream, Pos, State) -> {{true, true}, Rest, Stream, Pos + 4, State}; parse_SDDecl_standalone_yesno_dq(<<"yes"/utf8>>, _, _, State) -> parse_SDDecl_standalone_yesno_dq_yes(cf(State)); parse_SDDecl_standalone_yesno_dq(<<"ye"/utf8>>, _, _, State) -> parse_SDDecl_standalone_yesno_dq_ye(cf(State)); parse_SDDecl_standalone_yesno_dq(<<"y"/utf8>>, _, _, State) -> parse_SDDecl_standalone_yesno_dq_y(cf(State)); parse_SDDecl_standalone_yesno_dq(<<>>, _, _, State) -> {Stream1, State1} = cf(State), parse_SDDecl_standalone_yesno_dq(Stream1, Stream1, 0, State1). parse_SDDecl_standalone_yesno_sq_n({<<"o'"/utf8, Rest/bitstring>> = Stream, State}) -> {{false, true}, Rest, Stream, 2, State}; parse_SDDecl_standalone_yesno_sq_n({<<"o"/utf8>>, State}) -> parse_SDDecl_standalone_yesno_sq_no(cf(State)); parse_SDDecl_standalone_yesno_sq_n({_, State}) -> fatal_error(bad_standalone, State). parse_SDDecl_standalone_yesno_sq_no({<<"'"/utf8, Rest/bitstring>> = Stream, State}) -> {{false, true}, Rest, Stream, 1, State}; parse_SDDecl_standalone_yesno_sq_no({_, State}) -> fatal_error(bad_standalone, State). parse_SDDecl_standalone_yesno_dq_n({<<"o\""/utf8, Rest/bitstring>> = Stream, State}) -> {{false, true}, Rest, Stream, 2, State}; parse_SDDecl_standalone_yesno_dq_n({<<"o"/utf8>>, State}) -> parse_SDDecl_standalone_yesno_dq_no(cf(State)); parse_SDDecl_standalone_yesno_dq_n({_, State}) -> fatal_error(bad_standalone, State). parse_SDDecl_standalone_yesno_dq_no({<<"\""/utf8, Rest/bitstring>> = Stream, State}) -> {{false, true}, Rest, Stream, 1, State}; parse_SDDecl_standalone_yesno_dq_no({_, State}) -> fatal_error(bad_standalone, State). parse_SDDecl_standalone_yesno_dq_y({<<"es\""/utf8, Rest/bitstring>> = Stream, State}) -> {{true, true}, Rest, Stream, 3, State}; parse_SDDecl_standalone_yesno_dq_y({<<"es"/utf8>>, State}) -> parse_SDDecl_standalone_yesno_dq_yes(cf(State)); parse_SDDecl_standalone_yesno_dq_y({<<"e"/utf8>>, State}) -> parse_SDDecl_standalone_yesno_dq_ye(cf(State)); parse_SDDecl_standalone_yesno_dq_y({_, State}) -> fatal_error(bad_standalone, State). parse_SDDecl_standalone_yesno_dq_ye({<<"s\""/utf8, Rest/bitstring>> = Stream, State}) -> {{true, true}, Rest, Stream, 2, State}; parse_SDDecl_standalone_yesno_dq_ye({<<"s"/utf8>>, State}) -> parse_SDDecl_standalone_yesno_dq_yes(cf(State)); parse_SDDecl_standalone_yesno_dq_ye({_, State}) -> fatal_error(bad_standalone, State). parse_SDDecl_standalone_yesno_dq_yes({<<"\""/utf8, Rest/bitstring>> = Stream, State}) -> {{true, true}, Rest, Stream, 1, State}; parse_SDDecl_standalone_yesno_dq_yes({_, State}) -> fatal_error(bad_standalone, State). parse_SDDecl(<<"standalone"/utf8, Rest/bitstring>>, Stream, Pos, State) -> parse_SDDecl_standalone(Rest, Stream, Pos + 10, State); parse_SDDecl(<<"standalon"/utf8>>, _, _, State) -> parse_SDDecl_standalon(cf(State)); parse_SDDecl(<<"standalo"/utf8>>, _, _, State) -> parse_SDDecl_standalo(cf(State)); parse_SDDecl(<<"standal"/utf8>>, _, _, State) -> parse_SDDecl_standal(cf(State)); parse_SDDecl(<<"standa"/utf8>>, _, _, State) -> parse_SDDecl_standa(cf(State)); parse_SDDecl(<<"stand"/utf8>>, _, _, State) -> parse_SDDecl_stand(cf(State)); parse_SDDecl(<<"stan"/utf8>>, _, _, State) -> parse_SDDecl_stan(cf(State)); parse_SDDecl(<<"sta"/utf8>>, _, _, State) -> parse_SDDecl_sta(cf(State)); parse_SDDecl(<<"st"/utf8>>, _, _, State) -> parse_SDDecl_st(cf(State)); parse_SDDecl(<<"s"/utf8>>, _, _, State) -> parse_SDDecl_s(cf(State)); parse_SDDecl(<<>>, _, _, State) -> {Stream1, State1} = cf(State), parse_SDDecl(Stream1, Stream1, 0, State1); parse_SDDecl(?MATCH) -> {{false, false}, ?MATCH}. parse_SDDecl_s({<<"tandalone"/utf8, Rest/bitstring>> = Stream, State}) -> parse_SDDecl_standalone(Rest, Stream, 9, State); parse_SDDecl_s({<<"tandalon"/utf8>>, State}) -> parse_SDDecl_standalon(cf(State)); parse_SDDecl_s({<<"tandalo"/utf8>>, State}) -> parse_SDDecl_standalo(cf(State)); parse_SDDecl_s({<<"tandal"/utf8>>, State}) -> parse_SDDecl_standal(cf(State)); parse_SDDecl_s({<<"tanda"/utf8>>, State}) -> parse_SDDecl_standa(cf(State)); parse_SDDecl_s({<<"tand"/utf8>>, State}) -> parse_SDDecl_stand(cf(State)); parse_SDDecl_s({<<"tan"/utf8>>, State}) -> parse_SDDecl_stan(cf(State)); parse_SDDecl_s({<<"ta"/utf8>>, State}) -> parse_SDDecl_sta(cf(State)); parse_SDDecl_s({<<"t"/utf8>>, State}) -> parse_SDDecl_st(cf(State)); parse_SDDecl_s({_, State}) -> fatal_error(bad_standalone, State). parse_SDDecl_st({<<"andalone"/utf8, Rest/bitstring>> = Stream, State}) -> parse_SDDecl_standalone(Rest, Stream, 8, State); parse_SDDecl_st({<<"andalon"/utf8>>, State}) -> parse_SDDecl_standalon(cf(State)); parse_SDDecl_st({<<"andalo"/utf8>>, State}) -> parse_SDDecl_standalo(cf(State)); parse_SDDecl_st({<<"andal"/utf8>>, State}) -> parse_SDDecl_standal(cf(State)); parse_SDDecl_st({<<"anda"/utf8>>, State}) -> parse_SDDecl_standa(cf(State)); parse_SDDecl_st({<<"and"/utf8>>, State}) -> parse_SDDecl_stand(cf(State)); parse_SDDecl_st({<<"an"/utf8>>, State}) -> parse_SDDecl_stan(cf(State)); parse_SDDecl_st({<<"a"/utf8>>, State}) -> parse_SDDecl_sta(cf(State)); parse_SDDecl_st({_, State}) -> fatal_error(bad_standalone, State). parse_SDDecl_sta({<<"ndalone"/utf8, Rest/bitstring>> = Stream, State}) -> parse_SDDecl_standalone(Rest, Stream, 7, State); parse_SDDecl_sta({<<"ndalon"/utf8>>, State}) -> parse_SDDecl_standalon(cf(State)); parse_SDDecl_sta({<<"ndalo"/utf8>>, State}) -> parse_SDDecl_standalo(cf(State)); parse_SDDecl_sta({<<"ndal"/utf8>>, State}) -> parse_SDDecl_standal(cf(State)); parse_SDDecl_sta({<<"nda"/utf8>>, State}) -> parse_SDDecl_standa(cf(State)); parse_SDDecl_sta({<<"nd"/utf8>>, State}) -> parse_SDDecl_stand(cf(State)); parse_SDDecl_sta({<<"n"/utf8>>, State}) -> parse_SDDecl_stan(cf(State)); parse_SDDecl_sta({_, State}) -> fatal_error(bad_standalone, State). parse_SDDecl_stan({<<"dalone"/utf8, Rest/bitstring>> = Stream, State}) -> parse_SDDecl_standalone(Rest, Stream, 6, State); parse_SDDecl_stan({<<"dalon"/utf8>>, State}) -> parse_SDDecl_standalon(cf(State)); parse_SDDecl_stan({<<"dalo"/utf8>>, State}) -> parse_SDDecl_standalo(cf(State)); parse_SDDecl_stan({<<"dal"/utf8>>, State}) -> parse_SDDecl_standal(cf(State)); parse_SDDecl_stan({<<"da"/utf8>>, State}) -> parse_SDDecl_standa(cf(State)); parse_SDDecl_stan({<<"d"/utf8>>, State}) -> parse_SDDecl_stand(cf(State)); parse_SDDecl_stan({_, State}) -> fatal_error(bad_standalone, State). parse_SDDecl_stand({<<"alone"/utf8, Rest/bitstring>> = Stream, State}) -> parse_SDDecl_standalone(Rest, Stream, 5, State); parse_SDDecl_stand({<<"alon"/utf8>>, State}) -> parse_SDDecl_standalon(cf(State)); parse_SDDecl_stand({<<"alo"/utf8>>, State}) -> parse_SDDecl_standalo(cf(State)); parse_SDDecl_stand({<<"al"/utf8>>, State}) -> parse_SDDecl_standal(cf(State)); parse_SDDecl_stand({<<"a"/utf8>>, State}) -> parse_SDDecl_standa(cf(State)); parse_SDDecl_stand({_, State}) -> fatal_error(bad_standalone, State). parse_SDDecl_standa({<<"lone"/utf8, Rest/bitstring>> = Stream, State}) -> parse_SDDecl_standalone(Rest, Stream, 4, State); parse_SDDecl_standa({<<"lon"/utf8>>, State}) -> parse_SDDecl_standalon(cf(State)); parse_SDDecl_standa({<<"lo"/utf8>>, State}) -> parse_SDDecl_standalo(cf(State)); parse_SDDecl_standa({<<"l"/utf8>>, State}) -> parse_SDDecl_standal(cf(State)); parse_SDDecl_standa({_, State}) -> fatal_error(bad_standalone, State). parse_SDDecl_standal({<<"one"/utf8, Rest/bitstring>> = Stream, State}) -> parse_SDDecl_standalone(Rest, Stream, 3, State); parse_SDDecl_standal({<<"on"/utf8>>, State}) -> parse_SDDecl_standalon(cf(State)); parse_SDDecl_standal({<<"o"/utf8>>, State}) -> parse_SDDecl_standalo(cf(State)); parse_SDDecl_standal({_, State}) -> fatal_error(bad_standalone, State). parse_SDDecl_standalo({<<"ne"/utf8, Rest/bitstring>> = Stream, State}) -> parse_SDDecl_standalone(Rest, Stream, 2, State); parse_SDDecl_standalo({<<"n"/utf8>>, State}) -> parse_SDDecl_standalon(cf(State)); parse_SDDecl_standalo({_, State}) -> fatal_error(bad_standalone, State). parse_SDDecl_standalon({<<"e"/utf8, Rest/bitstring>> = Stream, State}) -> parse_SDDecl_standalone(Rest, Stream, 1, State); parse_SDDecl_standalon({_, State}) -> fatal_error(bad_standalone, State). %%---------------------------------------------------------------------- %% [23] XMLDecl ::= '' %%---------------------------------------------------------------------- parse_XMLDecl_ltqxml(?MATCH) -> {{Version, true}, ?MATCH1} = parse_VersionInfo(?MATCH), {IsWs2, ?MATCH2} = maybe_consume_s(?MATCH1), {{Encoding, EncSet}, ?MATCH3} = parse_EncodingDecl(?MATCH2), {{Standalone1, SaSet1}, ?MATCH6} = case IsWs2 of true when EncSet -> {IsWs4, ?MATCH4} = maybe_consume_s(?MATCH3), {{Standalone, SaSet}, ?MATCH5} = parse_SDDecl(?MATCH4), case IsWs4 of false when SaSet -> fatal_error(missing_ws, State); _ -> {{Standalone, SaSet}, ?MATCH5} end; true -> parse_SDDecl(?MATCH3); false when EncSet -> fatal_error(missing_ws, State); false -> {IsWs4, ?MATCH4} = maybe_consume_s(?MATCH3), {{Standalone, SaSet}, ?MATCH5} = parse_SDDecl(?MATCH4), case IsWs4 of false when SaSet -> fatal_error(missing_ws, State); _ -> {{Standalone, SaSet}, ?MATCH5} end end, {_, ?MATCH7} = maybe_consume_s(?MATCH6), {Bytes8, _, _, State8} = parse_XMLDecl_end(?MATCH7), State9 = set_next_parser_position(misc_pre_dtd, State8), yaccety_sax:event_startDocument( Version, Encoding, EncSet, Standalone1, SaSet1, set_state_pos(State9, Bytes8) ). parse_XMLDecl_end(<<"?>"/utf8, Rest/bitstring>>, Stream, Pos, State) -> {Rest, Stream, Pos + 2, State}; parse_XMLDecl_end(<<"?"/utf8>>, _, _, State) -> parse_XMLDecl_end_q(cf(State)); parse_XMLDecl_end(Bytes, _, _, State) -> fatal_error(bad_xmldecl, {Bytes, State}). parse_XMLDecl_end_q({<<$>/utf8, Rest/bitstring>> = Stream, State}) -> {Rest, Stream, 1, State}; parse_XMLDecl_end_q({_, State}) -> fatal_error(bad_xmldecl, State). parse_XMLDecl(Stream, State) -> parse_XMLDecl(Stream, Stream, 0, State). parse_XMLDecl(<<">, Stream, Pos, State) -> parse_XMLDecl_ltqxml(Rest, Stream, Pos + 5, State); parse_XMLDecl(<<">, _, _, State) -> parse_XMLDecl_ltqxm(cf(State)); parse_XMLDecl(<<">, _, _, State) -> parse_XMLDecl_ltqx(cf(State)); parse_XMLDecl(<<">, _, _, State) -> parse_XMLDecl_ltq(cf(State)); parse_XMLDecl(<<"<">>, _, _, State) -> parse_XMLDecl_lt(cf(State)); parse_XMLDecl(<<>>, _, _, State) -> {Stream1, State1} = cf(State), parse_XMLDecl(Stream1, Stream1, 0, State1); parse_XMLDecl(Bytes, _, _, State) -> % default declaration State1 = set_next_parser_position(misc_pre_dtd, State), yaccety_sax:event_startDocument( <<"1.0">>, <<"UTF-8">>, false, false, false, set_state_pos(State1, Bytes) ). parse_XMLDecl_lt({<<"?xml"/utf8, Rest/bitstring>> = Stream, State}) -> parse_XMLDecl_ltqxml(Rest, Stream, 4, State); parse_XMLDecl_lt({<<"?xm"/utf8>>, State}) -> parse_XMLDecl_ltqxm(cf(State)); parse_XMLDecl_lt({<<"?x"/utf8>>, State}) -> parse_XMLDecl_ltqx(cf(State)); parse_XMLDecl_lt({<<"?"/utf8>>, State}) -> parse_XMLDecl_ltq(cf(State)); parse_XMLDecl_lt({Bytes, State}) -> % default declaration, came in with one byte, so assuming a prepend is okay here. State1 = set_next_parser_position(misc_pre_dtd, State), yaccety_sax:event_startDocument( <<"1.0">>, <<"UTF-8">>, false, false, false, set_state_pos(State1, <<"<", Bytes/bitstring>>) ). parse_XMLDecl_ltq({<<"xml"/utf8, Rest/bitstring>> = Stream, State}) -> parse_XMLDecl_ltqxml(Rest, Stream, 3, State); parse_XMLDecl_ltq({<<"xm"/utf8>>, State}) -> parse_XMLDecl_ltqxm(cf(State)); parse_XMLDecl_ltq({<<"x"/utf8>>, State}) -> parse_XMLDecl_ltqx(cf(State)); parse_XMLDecl_ltq({Bytes, State}) -> % default declaration, came in with one byte, so assuming a prepend is okay here. State1 = set_next_parser_position(misc_pre_dtd, State), yaccety_sax:event_startDocument( <<"1.0">>, <<"UTF-8">>, false, false, false, set_state_pos(State1, <<">) ). parse_XMLDecl_ltqx({<<"ml"/utf8, Rest/bitstring>> = Stream, State}) -> parse_XMLDecl_ltqxml(Rest, Stream, 2, State); parse_XMLDecl_ltqx({<<"m"/utf8>>, State}) -> parse_XMLDecl_ltqxm(cf(State)); parse_XMLDecl_ltqx({_, State}) -> fatal_error(bad_xmldecl, State). parse_XMLDecl_ltqxm({<<"l"/utf8, Rest/bitstring>> = Stream, State}) -> parse_XMLDecl_ltqxml(Rest, Stream, 1, State); parse_XMLDecl_ltqxm({_, State}) -> fatal_error(bad_xmldecl, State). %%---------------------------------------------------------------------- %% [27] Misc ::= Comment | PI | S %%---------------------------------------------------------------------- parse_Misc(Stream, State) -> parse_Misc(Stream, Stream, 0, State). parse_Misc(<<"