Использование UNIX для синтаксического и лексического анализа

       

Простейший пример Lex


Можно использовать Lex для извлечения слов из файла с последующей распечаткой их по одному в каждой строке. Это полезно при сортировке ввода для определения слова, чаще всего используемого в тексте. Нижеприведенный код Lex решает эту задачу:

word [A-Za-z][-A-Za-z']* eol \n %% {word} { printf ("%s\n", yytext);} {eol} ; . ; %%

Первым в структуре спецификаций Lex располагается набор определений. В этом примере я определил "word" как произвольную последовательность символов. После первого символа допускается наличие черточки или апострофа. Согласно определению, сокращенные и написанные через дефис слова рассматриваются как одиночные, не разделенные на отдельные компоненты. Как видим, определение регулярного выражения в качестве "word" довольно несложно.

Я также включаю определение конца строки. И таким образом получаю возможность отбрасывать символ конца строки. В противном случае, из-за того, что Lex тупо передает любые символы, которые не фильтруются потоком стандартного вывода, на экране появится множество посторонних новых строк. Аналогичным образом я объявляю любые другие игнорируемые непечатаемые символы. По такой схеме можно игнорировать, к примеру, знаки пунктуации.

После создания такого программного файла я обработал им черновик моей предыдущей главы. Первые 10 строк вывода приведены ниже:

Программа написана давайте сделаем ее быстрее после удаления всех ошибок

Ясно, что, подсчитывая слова, я должен отсортировать их и обработать с помощью uniq -с:


wordextract | sort | uniq -с

Результат будет получен весьма интересный, так как сортировка чувствительна к регистру и поэтому необходимо использовать tr для преобразования всего текста в нижний регистр перед сортировкой. Также необходимо отсортировать вывод по частоте использования слов. Десятью наиболее часто используемыми словами в предыдущей главе будут (английский вариант):

291 the 129 of 120 а 113 to 104 is 81 and 77 i 69 you 64 code 62 for

Здесь нет ничего удивительного. Я выполнил эти вычисления, используя конвейер. Более профессиональным использованием Lex была бы возможность преобразовать код Lex в одну программу С.

[ ] [ ] [ ]


[ZEBR_TAG_td ALign="Left" vAlign="TOP">


Содержание раздела