ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Четверг
28 ноября
315019 Топик полностью
fk0, легенда (14.03.2012 18:46 - 18:48, просмотров: 95) ответил fk0 на Попробуй дать оценку минимально возможному количеству состояний. Во-первых речь уже не о так называемом "недетерминированном конечном автомате" (Структуры данных и алгоритмы - Ахо, Хопкрофт, Ульман -- для справки). Потому, что он должен же как-то
Есть такой проект -- re2c. Генерирует из заданного описания прямой C-код ДКА (без таблиц) для разбора регулярных выражений с высокой скоростью. Я ему ради интереса задал регулярное выражение требующее разбора одного из 28 токенов. На выходе получил автомат с 74 состояниями. Да, полученный автомат "вообще не использует памяти". Кроме переменной своего состояния. 74 состояния в один байт уместятся. Но такой код вручную написать практически невозможно. И боюсь, re2c на порядок превосходит описываемые ранее поделки. И самое главное -- в реальном проекте число состояний будет уже слишком велико. Попробую простенький парсер ини задать в виде регулярного выражения. Пример: char *lex(char *input) { /*!re2c ("ONE" | "TWO" | "THREE" | "FOUR" | "FIVE" | "SIX" | "SEVEN" | "EIGHT" | "NINE" | "TEN" | "ELEVEN" | "TWELWE" | "THIRTEEN" | "FOURTEEN" | "FIFTEEN" | "SIXTEEN" | "SEVENTEEN" | "EIGHTEEN" | "NINETEEN" | "TWENTY" | "THIRTY" | "FORTY" | "FIFTY" | "SIXTY" | "SEVENTY" | "EIGHTY" | "NINETY" | "HUNDRED") { return 1; } */ } И результат: /* Generated by re2c 0.13.5 on Wed Mar 14 18:45:24 2012 */ #line 1 "re2c.c" char *lex(char *input) { #line 8 "<stdout>" { YYCTYPE yych; if ((YYLIMIT - YYCURSOR) < 9) YYFILL(9); yych = *YYCURSOR; switch (yych) { case 'E': goto yy7; case 'F': goto yy5; case 'H': goto yy9; case 'N': goto yy8; case 'O': goto yy3; case 'S': goto yy6; case 'T': goto yy4; default: goto yy2; } yy2: YYCURSOR = YYMARKER; goto yy16; yy3: yych = *++YYCURSOR; switch (yych) { case 'N': goto yy74; default: goto yy2; } yy4: yych = *++YYCURSOR; switch (yych) { case 'E': goto yy61; case 'H': goto yy59; case 'W': goto yy60; default: goto yy2; } yy5: yych = *++YYCURSOR; switch (yych) { case 'I': goto yy45; case 'O': goto yy46; default: goto yy2; } yy6: yych = *++YYCURSOR; switch (yych) { case 'E': goto yy33; case 'I': goto yy34; default: goto yy2; } yy7: yych = *++YYCURSOR; switch (yych) { case 'I': goto yy23; case 'L': goto yy24; default: goto yy2; } yy8: yych = *++YYCURSOR; switch (yych) { case 'I': goto yy17; default: goto yy2; } yy9: yych = *++YYCURSOR; switch (yych) { case 'U': goto yy10; default: goto yy2; } yy10: yych = *++YYCURSOR; switch (yych) { case 'N': goto yy11; default: goto yy2; } yy11: yych = *++YYCURSOR; switch (yych) { case 'D': goto yy12; default: goto yy2; } yy12: yych = *++YYCURSOR; switch (yych) { case 'R': goto yy13; default: goto yy2; } yy13: yych = *++YYCURSOR; switch (yych) { case 'E': goto yy14; default: goto yy2; } yy14: yych = *++YYCURSOR; switch (yych) { case 'D': goto yy15; default: goto yy2; } yy15: ++YYCURSOR; yy16: #line 11 "re2c.c" { return 1; } #line 109 "<stdout>" yy17: yych = *++YYCURSOR; switch (yych) { case 'N': goto yy18; default: goto yy2; } yy18: yych = *++YYCURSOR; switch (yych) { case 'E': goto yy19; default: goto yy2; } yy19: yych = *(YYMARKER = ++YYCURSOR); switch (yych) { case 'T': goto yy20; default: goto yy16; } yy20: yych = *++YYCURSOR; switch (yych) { case 'E': goto yy21; case 'Y': goto yy15; default: goto yy2; } yy21: yych = *++YYCURSOR; switch (yych) { case 'E': goto yy22; default: goto yy2; } yy22: yych = *++YYCURSOR; switch (yych) { case 'N': goto yy15; default: goto yy2; } yy23: yych = *++YYCURSOR; switch (yych) { case 'G': goto yy28; default: goto yy2; } yy24: yych = *++YYCURSOR; switch (yych) { case 'E': goto yy25; default: goto yy2; } yy25: yych = *++YYCURSOR; switch (yych) { case 'V': goto yy26; default: goto yy2; } yy26: yych = *++YYCURSOR; switch (yych) { case 'E': goto yy27; default: goto yy2; } yy27: yych = *++YYCURSOR; switch (yych) { case 'N': goto yy15; default: goto yy2; } yy28: yych = *++YYCURSOR; switch (yych) { case 'H': goto yy29; default: goto yy2; } yy29: yych = *++YYCURSOR; switch (yych) { case 'T': goto yy30; default: goto yy2; } yy30: yych = *(YYMARKER = ++YYCURSOR); switch (yych) { case 'E': goto yy31; case 'Y': goto yy15; default: goto yy16; } yy31: yych = *++YYCURSOR; switch (yych) { case 'E': goto yy32; default: goto yy2; } yy32: yych = *++YYCURSOR; switch (yych) { case 'N': goto yy15; default: goto yy2; } yy33: yych = *++YYCURSOR; switch (yych) { case 'V': goto yy39; default: goto yy2; } yy34: yych = *++YYCURSOR; switch (yych) { case 'X': goto yy35; default: goto yy2; } yy35: yych = *(YYMARKER = ++YYCURSOR); switch (yych) { case 'T': goto yy36; default: goto yy16; } yy36: yych = *++YYCURSOR; switch (yych) { case 'E': goto yy37; case 'Y': goto yy15; default: goto yy2; } yy37: yych = *++YYCURSOR; switch (yych) { case 'E': goto yy38; default: goto yy2; } yy38: yych = *++YYCURSOR; switch (yych) { case 'N': goto yy15; default: goto yy2; } yy39: yych = *++YYCURSOR; switch (yych) { case 'E': goto yy40; default: goto yy2; } yy40: yych = *++YYCURSOR; switch (yych) { case 'N': goto yy41; default: goto yy2; } yy41: yych = *(YYMARKER = ++YYCURSOR); switch (yych) { case 'T': goto yy42; default: goto yy16; } yy42: yych = *++YYCURSOR; switch (yych) { case 'E': goto yy43; case 'Y': goto yy15; default: goto yy2; } yy43: yych = *++YYCURSOR; switch (yych) { case 'E': goto yy44; default: goto yy2; } yy44: yych = *++YYCURSOR; switch (yych) { case 'N': goto yy15; default: goto yy2; } yy45: yych = *++YYCURSOR; switch (yych) { case 'F': goto yy55; case 'V': goto yy54; default: goto yy2; } yy46: yych = *++YYCURSOR; switch (yych) { case 'R': goto yy48; case 'U': goto yy47; default: goto yy2; } yy47: yych = *++YYCURSOR; switch (yych) { case 'R': goto yy50; default: goto yy2; } yy48: yych = *++YYCURSOR; switch (yych) { case 'T': goto yy49; default: goto yy2; } yy49: yych = *++YYCURSOR; switch (yych) { case 'Y': goto yy15; default: goto yy2; } yy50: yych = *(YYMARKER = ++YYCURSOR); switch (yych) { case 'T': goto yy51; default: goto yy16; } yy51: yych = *++YYCURSOR; switch (yych) { case 'E': goto yy52; default: goto yy2; } yy52: yych = *++YYCURSOR; switch (yych) { case 'E': goto yy53; default: goto yy2; } yy53: yych = *++YYCURSOR; switch (yych) { case 'N': goto yy15; default: goto yy2; } yy54: yych = *++YYCURSOR; switch (yych) { case 'E': goto yy15; default: goto yy2; } yy55: yych = *++YYCURSOR; switch (yych) { case 'T': goto yy56; default: goto yy2; } yy56: yych = *++YYCURSOR; switch (yych) { case 'E': goto yy57; case 'Y': goto yy15; default: goto yy2; } yy57: yych = *++YYCURSOR; switch (yych) { case 'E': goto yy58; default: goto yy2; } yy58: yych = *++YYCURSOR; switch (yych) { case 'N': goto yy15; default: goto yy2; } yy59: yych = *++YYCURSOR; switch (yych) { case 'I': goto yy68; case 'R': goto yy67; default: goto yy2; } yy60: yych = *++YYCURSOR; switch (yych) { case 'E': goto yy62; case 'O': goto yy15; default: goto yy2; } yy61: yych = *++YYCURSOR; switch (yych) { case 'N': goto yy15; default: goto yy2; } yy62: yych = *++YYCURSOR; switch (yych) { case 'L': goto yy64; case 'N': goto yy63; default: goto yy2; } yy63: yych = *++YYCURSOR; switch (yych) { case 'T': goto yy66; default: goto yy2; } yy64: yych = *++YYCURSOR; switch (yych) { case 'W': goto yy65; default: goto yy2; } yy65: yych = *++YYCURSOR; switch (yych) { case 'E': goto yy15; default: goto yy2; } yy66: yych = *++YYCURSOR; switch (yych) { case 'Y': goto yy15; default: goto yy2; } yy67: yych = *++YYCURSOR; switch (yych) { case 'E': goto yy73; default: goto yy2; } yy68: yych = *++YYCURSOR; switch (yych) { case 'R': goto yy69; default: goto yy2; } yy69: yych = *++YYCURSOR; switch (yych) { case 'T': goto yy70; default: goto yy2; } yy70: yych = *++YYCURSOR; switch (yych) { case 'E': goto yy71; case 'Y': goto yy15; default: goto yy2; } yy71: yych = *++YYCURSOR; switch (yych) { case 'E': goto yy72; default: goto yy2; } yy72: yych = *++YYCURSOR; switch (yych) { case 'N': goto yy15; default: goto yy2; } yy73: yych = *++YYCURSOR; switch (yych) { case 'E': goto yy15; default: goto yy2; } yy74: ++YYCURSOR; switch ((yych = *YYCURSOR)) { case 'E': goto yy15; default: goto yy2; } } #line 12 "re2c.c" }
[ZX]