Форум программистов, компьютерный форум, киберфорум
Boost C++
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.75/8: Рейтинг темы: голосов - 8, средняя оценка - 4.75
0 / 0 / 0
Регистрация: 14.09.2014
Сообщений: 3

Boost::Spirit. Разбор конфигурационного файла

14.09.2014, 16:16. Показов 1680. Ответов 1
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Есть конфигурационный файл, содержащий текстовое описание данных.
Каждая запись конфигурационного файла состоит из полей.

Формальное описание:

поле ::= простое_поле | структурное_поле | список

простое_поле ::= -ключ значение (пример: -LENGTH 300 или -VISIBILE "show"|"hide")

значение ::= {любой символ} (все символы, включая пробел, дефис и перевод на новую строку)

структурное поле ::= -ключ поле1 ... полеN (пример: -DATETIME -DAY 20140101 -TIME 120000)

список ::= -BEGIN ключ поле1 .. полеN -END ключ
Пример списка:

-BEGIN POLYGON -COLOR "red"|"green" -POINT -POSX 100 -POSZ 300 -POSY 100 -POINT -POSX 200 -POSY 200 -END POLIGON

Пробел или перевод на новую строку может быть в любом месте записи:

-
DATETIME - DAY 20140101 -TIME
120000

Структурные поля имеют произвольный порядок следования, не все поля могут присутствовать, например:

-DATETIME -TIME 120000 -DAY 20140101 или
-DATETIME -DAY 20140101

Внутри списка последовательность полей имеет семантическую значимость, то есть первая точка имеет
координаты -POSX 100 -POSY 100 -POSZ 300, а вторая -POSX 200 -POSY 200.

Каждая запись имеет обязательный ключ (TYPE), который определяет возможные поля, которые могут присутствовать,
например:

-TYPE POINT -COLOR RGB(0,200,100) -NAME 'name' -POSY 100 -POSX 200
-TYPE LINE -NAME 'name' -BEGIN POINTS -POSX 200 -POSY 200 -POSX 400 -POSY 400 -END POINTS -COLOR "blue"
-TYPE CIRCLE -CENTER -POSZ 400. -POSX 300. -COLOR "yellow" -NAME 'name'
При встрече неизвестного обязательно ключа или неизвестного ключа в простом или структурном поле
надо пропускать все последующие символы до следующего известного "-ключ значение".

При встрече неизвестного ключа внутри списка надо пропустить все символы, включая -END ключ.


Подскажите пожалуйста шаблон разбора подобных файлов с помощью Boost::Spirit.

Добавлено через 10 часов 44 минуты
Вопрос попроще.

Пытаюсь адаптировать под свои нужды boost/libs/spirit/repository/example/qi/keywords.cpp

В нем из заданной строки формируется структура:

C++
1
2
3
4
5
6
7
struct person {
    std::string name;
    int age;
    double size;
};
 
person Bill;
Вместо приведенного в примере правила разбора:

C++
1
2
3
4
5
       no_constraint_person_rule %=
            kwd("name")['=' > parse_string ]
          / kwd("age")   ['=' > int_]
          / kwd("size")   ['=' > double_ > 'm']
          ;
пишу свой вариант:

C++
1
2
3
4
5
        my_constraint_person_rule %=
            kwd("-name")[my_parse_string ]
          / kwd("-age")   [int_]
          / kwd("-size")   [double_]
          ;
Как видно, в названии параметров я добавил дефис, убрал ненужный мне
знак равенства и в параметре size удалил окончание 'm'.

Кроме того, разбор строки

C++
1
         parse_string   %= '"'> *(char_-'"') > '"';

заменил на свой вариант

C++
1
         my_parse_string   %= +(char_-' ');
То есть, мои строки не находятся в кавычках и нужен хотя бы один символ.

Вызываю разбор строки:

C++
1
2
3
4
5
6
7
8
        Bill.name = "";
        Bill.age = -1;
        Bill.size = -1.;
 
        test_phrase_parser_attr(
                         "-age 1 -size 2.3 -name Bill"
                        ,my_constraint_person_rule
                        ,Bill);
Все в порядке: согласно примеру выводится строка:
Person : Bill, 1, 2.3
Пробую переставить параметры местами:

C++
1
2
3
4
        test_phrase_parser_attr(
                         "-size 2.3 -age 1 -name Bill"
                        ,my_constraint_person_rule
                        ,Bill);
Как и в первом случае, получаю правильные значения.

А вот если ставлю на первое место параметр name, то происходит ошибка:

C++
1
2
3
4
        test_phrase_parser_attr(
                         "-name Bill -age 1 -size 2.3"
                        ,my_constraint_person_rule
                        ,Bill);
Person : Bill-age1-size2.3, -1, -1
То есть разбор правильно нашел имя первого параметра (name), стал искать значение имени,
но не остановился на первом пробеле, а прошел до конца строки. В результате другие параметры
не получили значений.

Пробую в качестве ограничителя имени поставить символ 'l':

C++
1
         my_parse_string   %= +(char_-'l');
Результат:

Person : Bi, -1, -1

По идее все правильно: разбор имени закончился как только встретился первый символ 'l',
а остальные параметры не разобраны, потому что встретился второй символ 'l'.

Меняю вызов:

C++
1
2
3
4
        test_phrase_parser_attr(
                         "-name Bil -age 1 -size 2.3"
                        ,my_constraint_person_rule
                        ,Bill);
и ожидаю, что строка будет разобрана до конца.

Не тут-то было, результат аналогичен предыдущему:

Person : Bi, -1, -1
Если пропустить "символ окончания строки":

C++
1
2
3
4
5
        my_constraint_person_rule %=
            kwd("-name")[my_parse_string > 'l']
          / kwd("-age")   [int_]
          / kwd("-size")   [double_]
          ;
то все разбирается правильно:

Person : Bi, 1, 2.3

Но у меня-то параметры разделяет пробел, а не 'l'.

--------

Собственно вопрос один: где я напутал в правиле разбора строки {my_parse_string %= +(char_-' ')} ?

Чувствую, что ответ простой, но я - новичок и похоже еще не знаю самых элементарных вещей.


Если это имеет значение, использую Boost 1.56.0, Mingw 4.6. Пробовал Mingw 4.8: при компиляции выдал
кучу предупреждений, при выполнении выдал ошибку, но самое существенное я успел углядеть - пробел
в правиле разбора строки так же не воспринимается.
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
14.09.2014, 16:16
Ответы с готовыми решениями:

Метапрограммирование в boost::proto (boost::spirit)
В библиотеке boost:: proto есть такой код calculator<proto::terminal<placeholder<0> >::type> const _1; ...

boost::spirit
Пишу парсер на спирите. Задаюсь вопросом как нормально сделать примерно такое lexeme Где _val - вектор стрингов. А _1 имеет...

Производительность boost::spirit::qi
#include <iostream> #include <sstream> #include <chrono> #include <boost/spirit/include/qi.hpp> #include...

1
0 / 0 / 0
Регистрация: 14.09.2014
Сообщений: 3
17.09.2014, 05:57  [ТС]
Переход на нанотехнологии не состоялся. Вернулся к сохе и топору.
Применение пары вложенных хэш-таблиц решило все проблемы.
Вопрос закрыт. Всем спасибо.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
17.09.2014, 05:57
Помогаю со студенческими работами здесь

Чтение и сохранение данных из конфигурационного файла
Привет всем!! Есть программа на C с конфигурационным файлом!!! Надо сделать так чтобы при старте программы конфиг файл читался один раз,...

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

Создание конфигурационного файла
Добрый день, форумчане! Такая проблема: надо создать свой конфигурационный файл для задания в нем имени сервера и номера порта для...

Защита конфигурационного файла
Есть файл config.php в котором содержатся реквизиты к mysql. К нему закрыт доступ "извне" через .htaccess. Как можно закрыть к...

backup конфигурационного файла
не могу создать backup конфигурационного файла. Cisco 871 и ПК под Win XP. роутер подключен до ПК через патч-корд до ЛАН-порта. на ПК...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
2
Ответ Создать тему
Новые блоги и статьи
http://iceja.net/ сервер решения полиномов
iceja 18.01.2026
Выкатила http:/ / iceja. net/ сервер решения полиномов (находит действительные корни полиномов методом Штурма). На сайте документация по API, но скажу прямо VPS слабенький и 200 000 полиномов. . .
Первый деплой
lagorue 16.01.2026
Не спеша развернул своё 1ое приложение в kubernetes. А дальше мне интересно создать 1фронтэнд приложения и 2 бэкэнд приложения развернуть 2 деплоя в кубере получится 2 сервиса и что-бы они. . .
Расчёт переходных процессов в цепи постоянного тока
igorrr37 16.01.2026
/ * Дана цепь постоянного тока с R, L, C, k(ключ), U, E, J. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа, решает её и находит: токи, напряжения и их 1 и 2 производные при t = 0;. . .
Восстановить юзерскрипты Greasemonkey из бэкапа браузера
damix 15.01.2026
Если восстановить из бэкапа профиль Firefox после переустановки винды, то список юзерскриптов в Greasemonkey будет пустым. Но восстановить их можно так. Для этого понадобится консольная утилита. . .
Изучаю kubernetes
lagorue 13.01.2026
А пригодятся-ли мне знания kubernetes в России?
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru