[Из песочницы] Ленточный конвейер для линейных данных

Пять лет назад мне довелось проектировать одну программу, обрабатывающую текст с управляющими командами. Количество этапов обработки было весьма существенным — 6–7 обработчиков последовательно могли пропускать через себя довольно большие объёмы данных, как бывает иногда в конвейерах Unix. Чтобы аккуратно выполнить поставленную задачу я разработал общий метод, который может пригодиться и в других местах. Идея, лежащая в основе этой статьи, действительно очень напоминает конвейеры Unix, но имеется несколько существенных отличий: конвейер Unix работает асинхронно, в разных процессах, в то время, как здесь требуется реализовать обработку в рамках одной программы, и распараллеливание может быть нежелательно; возможна передача любых данных, не обязательно текстовых, но которые можно охарактеризовать термином «линейные». Под линейными данными я буду понимать последовательность объектов, допускающую переход к следующему (если он имеется). Примерами могут служить: бинарный файл, текст из символов UTF-8, последовательность лексем, команд. Сложная программа, обрабатывающая линейные данные, такая как транслятор, обычно выполняет несколько преобразований. Вот пример: чтение файла по байтам, декодирование в UTF-8, препроцессор, лексический анализ, синтаксический анализ. Ни для кого не секрет, что в этом случае нет необходимости хранить данные целиком в памяти. Гораздо эффективнее, считывать файл порциями, которые сразу же проходят через все этапы преобразования, не задерживаясь в памяти. Преобразователи выстраиваются в виде «конвейера», каждый следующий получает данные от предыдущего. Преобразователь также может менять тип данных, например, у лексера буквы на входе, на выходе — лексемы. У меня нет реализации этих алгоритмов, достойной публикации, поэтому я ограничусь общей идеей и схемой реализации. Примерные схемы даны на C++, в них используется виртуальное и множественное наследование, а также шаблоны. Читать дальше →

© Habrahabr.ru