Boost Spirit Qi: Подходящий язык / инструмент для анализа / вырезания "многострочного" файла данных?

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

>>>process_type_A
//name(typeA_1)
//version(A.1.99)
//date(2016.01.01)
//property1 "pA11"
//property2 "pA12"
//etc_A_1 (thousand of lines - a lot are "multiline" and/or mulitline sub-records)
<<<process_type_A
>>>process_type_A
//name(typeA_2)
//version(A.2.99)
//date(2016.01.02)
//property1 "pA21"
//property2 "pA22"
//etc_A_2 (hundred or thousand of lines)
<<<process_type_A
>>>process_type_B
//name(typeB_1)
//version(B.1.99)
//date(2016.02.01)
//property1 "pB11"
//property2 "pB12"
//etc_B_1 (hundred or thousand of lines)
<<<process_type_B
>>>paramset_type_C
//>>paramlist
////name(typeC_1)
////version(C.1.99)
////date(2016.03.01)
////property1 "pC11"
////property2 "pC12"
////etc_C_1 (hundred or thousand of lines)
//<<paramlist
//>>paramlist
////name(typeC_2)
////version(C.2.99)
////date(2016.04.01)
////property1 "pC21"
////property2 "pC22"
////etc_C_2 (hundred or thousand of lines)
//<<paramlist
<<<paramset_type_C

Code:: Blocks
Boost 1.60.0
Компилятор GCC в Windows и Linux

2 ответа

Решение

Я думаю, что @Orient прав: здесь достаточно регулярного выражения с захватами.

Тем не менее, у Spirit есть преимущество, что он может прийти без зависимости от линкера. Вот несколько подходов (используя seek[] а также raw[]) для вдохновения:

Обратите внимание, что Spirit X3 (все еще экспериментальный) также имеет seek[] директива, и она будет компилятором намного быстрее.

Главный совет, который я бы дал по поводу Ци, заключается в том, что это очень мощный и гибкий инструмент для разбора. Вы можете определить довольно сложные, возможно, рекурсивные структуры, используя boost::variant, boost::optionalи т. д., и связать эти типы с qi правила и, казалось бы, волшебным образом делает правильные вещи, давая вам хороший AST для ваших данных.

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

qi должно отлично работать, если вы можете написать хорошую грамматику для ваших данных. Если вы не можете написать однозначную грамматику, вы можете использовать qi::eps чтобы сделать его разборчивым, но вы не хотите делать это слишком часто, IMO. Я не думаю, что "сотни или тысячи" предметов будут представлять какую-то конкретную проблему.

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

Другие вопросы по тегам