Павиа написал(а):У него всего 1 текущее состояние
По стандарту RFC 3629 кодировки длина символа может составлять до 4 байт
[html]<a href="https://stijndewitt.com/2014/08/09/max-bytes-in-a-utf-8-char/">https://stijndewitt.com/2014/08/09/max-bytes-in-a-utf-8-char/</a>[/html]Это означает, что в автомате должно быть минимум 2 состояния (потому что ошибочные символы, например без последнего байта, должны заменяться на ОДИН замещающий символ).
CESU-8
Кроме того, обработка отдельных codepoint это ещё не всё, и должен быть желательно иметь второй ДКА-автомат, который позволяет разбирать последовательности codepoint-ов. Для русского языка это важно для обработки ударений и альтернативной кодировки для букв с диактриками.
http://unicode.org/faq/utf_bom.html#utf8-4
Кроме того, имелись в виду, наверное, состояния автомата, отличающиеся от начального (на это намекает слово "текущее" в словосочетании "текущее состояние"). Потому что автомат с одним состоянием только в этом одном состоянии и может находится. Поэтому Павиа, видимо имеет в виду, что у него в автомате два состояния - начальное и текущее. А я соответственно, что нужны состояния "начальное", "после первого байта", "после второго байта". Нужно ли состояние "после третьего байта" - это дискуссионный вопрос.
Если к коду Павиа присмотреться, у него там тоже байты не только нулевой и первый, но и второй есть.
[html]<pre>
function TFileSimvler.ReadNextChar: TSimvlerChar;
var B0, B1, B2:Byte;
begin
repeat
B0:=ReadByte;
until (B0 and $C0<>$D0); // UTF-8 .
if (B0 and $80)=$00 then
begin
Result:=TSimvlerChar(B0);
end
else <b><----- переход в первое состояние, отличное от начального</b>
if (B0 and $E0)=$C0 then
begin
B1:=ReadByte;
Result:=TSimvlerChar((B1 and $3F) + (B0 and $1F) shl 6);
end
else <b><----- переход во второе состояние, отличное от начального</b>
if (B0 and $F0)=$E0 then
begin
B1:=ReadByte;
B2:=ReadByte;
Result:=TSimvlerChar((B2 and $3F) + (B1 and $3F) shl 6 + (B0 and $1F) shl 12);
end;
Inc(FPosCol);
end;
</pre>[/html]
Строки, хранение и обработка
Символы с кодами от 128 кодируются 2-мя байтами, с кодами от 2048 — 3-мя, от 65536 — 4-мя.
0x00000000 — 0x0000007F: 0xxxxxxx
0x00000080 — 0x000007FF: 110xxxxx 10xxxxxx
0x00000800 — 0x0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx
0x00010000 — 0x001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
т.е. в первом байте мы смотрим на восьмой бит, а затем на шестой бит.
0x80 = 0b10000000
0xC0 = 0b11000000
0xE0 = 0b11100000
0xF0 = 0b11110000
Отредактировано Лис (2019-03-27 19:04:48)