[c++, QT, boost] применение регулярки к потоку символов

Missi4ka

Кто-нибудь знает плюсовую библиотеку, где поддерживается работа с регулярками в таком стиле:
1) создаем сканнер из строки-регулярки
2) скармлеваем ему последовательно символы и после каждого символа проверяем состояние (сматчилось, отвергнуто или промежуточное).
Регулярки QT применятся только к строке. Тривиальное решение - читать символы в буффер и применять регулярку к буфферу делать не охота, ибо это от лукавого.
Бустовые регулярки применятся к паре итераторов, писать обертку для своего файла, да еще и удовлетворяющую концепции BidirectionalIterator - геморр. Тем более, что хочется читать символы самому в цикле и после каждого символа проверять состояние конечного автомата и делать то-то и то-то, а не делегировать чтение функции match.
Короче, нужна библиотека, где в плюсовом стиле реализовано построение автомата по регулярке и поддерживается работа с этим автоматом.

Dasar

Короче, нужна библиотека, где в плюсовом стиле реализовано построение автомата по регулярке и поддерживается работа с этим автоматом
можно попробовать взять какой-нибудь лексер, они как раз подобным и занимаются.

Missi4ka

Конечно, можно соорудить лексер (или парсер? в чем, кстати, разница?) для регулярок с помощью того же boost::spirit, но есть пара НО:
1) регулярка не известна на момент компиляции, её вводит пользователь, так что компилировать лексер придется во время выполнения, инструменты кодогенерации при сборке не помогут.
2) не очень хочется палить из пушки по воробьям, ибо нужно распознавать не произвольные грамматики, а всего лишь регекспы, а для них должен быть стандартный инструмент.
В конце-то концов, он и есть - библиотеки регулярок в boost и QT, только разработчики этих библиотек предоставили слишком грубый интерфейс к реализации регулярок: применимость к паре итераторов вместо того, чтобы дать в распоряжение пользовалетя собственно автомат. Я точно знаю, что есть реализации регекспов с доступом к автомату, одна такая реализация была написана моим товарищем в рамках проекта на его работе и потому является проприетарной. Наверняка такие же вещи есть и в свободном доступе.

Andbar

регулярка не известна на момент компиляции, её вводит пользователь
На неё ставятся какие-то ограничения? А то жадный *, по идее, сразу-же захватит весь поток и в этом случае разница между потоком и строкой сомнительна.

Missi4ka

Весь поток в буфер не захватит по-любому: я же сам кидаю очередной прочитанный символ в сканнер, а потом забываю про этот символ или же решаю сохранить этот символ в буфере для сохранения. В случае, если буффер уже переполнен, но сбрасываю буффер на диск или предпринимаю еще какие-то меры, благо есть возможность принять решение, так как чтением потока управляю я сам. А вот стнадартный интерфейс с парой итераторов (причем, двусторонних) или же вообще строкой на входе - не позволяет так поступать, ему вынь и положь всю входную строку целиком.
Насчет жадной звездочки или плюса - это отдельная песня, как избавиться от ненужной жадности. Например, можно потребовать от пользоватея, в частности, что необходимые для сохранения в выходном буфере фрагменты будут ограниченной длины, т.е. для них не будут применяться жадные звездочки и плюсы.
Все это нужно для распарсивания текстовых файлов, где есть записиси и поля. А разделители записей и полей суть строки, заданные с помощью регулярок (вводит пользователь). Сохранять разделители в выходном буфере нужно уметь, так как иногда разделитель является частью записи и не должен быть выкинут.

yroslavasako

Только мне кажется странным, что автор хочет однопроходного парсинга регулярки (потому что автомат)? Я по скудоумию не могу представить алгоритма, которому хоть раз не пришлось бы возвращаться назад.

Missi4ka

Понял, о чем речь: если прочитанная и запомненная до сих пор строчка вдруг на очередном символе не мачится, но имеет суффикс, который является префиксом строки, которая мачится, то нам нужно переходить к началу этого суффикса, а не к концу всей строки. Да, пожалуй, тут еще нужна возможность регулярок делать capturing, чтобы после match-а можно было спросить у автомата тот кусок текста, который, собственно, сматчился. При этом этот кусок должен еще и храниться в структуре данных сканнера, так как мы сами не храним никакого буффера.

Missi4ka

Да, такое ощущение, что под такие требования трудно найти готовое. Придется возиться со строковыми буферами.

rosali

ну если замять вопрос про всякие расширения языка регулярных выражений в духе look-behind, то совершенно точно есть алгоритм, который строит по регулярному выражению конечный автомат. то есть да этому автомату никогда не придется возвращаться назад по тексту. в этом в общем-то и был смысл математической теории регулярных выражений - пожертвовать алгоритмической полнотой, но получить линейность по тексту. а потом пришли инженеры и всё испортили :)
Оставить комментарий
Имя или ник:
Комментарий: