boost.spirit. Поиск пустых значений.
От: VAbrutski  
Дата: 25.01.08 09:08
Оценка:
Ранее spirit не пользовался. Почитал документации на сайте, почитал форум, найти решения пока не смог. Хотя задачка весьма простая.

Нужно разобрать строку. Это набор определений разделенных ';'.
Определения могу быть разного вида. ',24' или ',,25,-100' или '(1:3)50,2' и может просто отсуствовать т.е. ''.
В самом простом случае, нужно разбирать строку вида
strIndices = ";;;,28;;,32;";
Для такого простого случая, для начала я определил простенькую граматику


struct indices : public grammar<indices>
    {
    indices():lnkAdvWidth(AdvWidth)                                {
    };
    vector<double> AdvWidth;
    vector<double> &lnkAdvWidth;

        template <typename ScannerT>
        struct definition
        {
            definition(indices const& self)
            {
                GlyphIndices = !GlyphMapping >> *(';' >> GlyphMapping);

                GlyphMapping = (',' >> AdvanceWidth) | AdvanceWidth;

                AdvanceWidth = real_p[push_back_a(self.lnkAdvWidth)];
            }
            rule<ScannerT> GlyphIndices, GlyphMapping, AdvanceWidth;
            rule<ScannerT> const&
            start() const { return GlyphIndices; }
        };
    };


Ну и соотвественно использование в виде

indices ind;
parse_info<> info = parse(strIndices.c_str(), ind, space_p);


В таком варианте все хорошо, получаю вектор [28,32]. Но мне нужно также знать о тех местах где значение было пропущено. т.е. например иметь вектор вида [0,0,0,28,0,32], ну или люую другую информацию, лишь бы знать к какому определению относяться найденные данные.
Соотвественно нужно как то отыскивать и пустые вхождения тоже.

Возможно spirit не самый удачный выбор для данной задачи, тогда пожалуйста подскажите то лучше?

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

GlyphIndices   = *1GlyphMapping *( ";" *1GlyphMapping ) 
GlyphMapping   = *1([ClusterMapping] GlyphIndex) [GlyphMetrics] 
ClusterMapping = "(" ClusterCodeUnitCount [":" ClusterGlyphCount] ")" 
ClusterCodeUnitCount = 1*DIGIT 
ClusterGlyphCount    = 1*DIGIT 
GlyphIndex     = *DIGIT 
GlyphMetrics   = "," *1AdvanceWidth ["," *1uOffset ["," vOffset]] 
AdvanceWidth   = ["+"] RealNum 
uOffset        = ["+" | "-"] RealNum 
vOffset        = ["+" | "-"] RealNum 
RealNum        = ((1*DIGIT ["." 1*DIGIT]) | ("." 1*DIGIT)) [Exponent] 
Exponent       = *1( ("E"|"e") ("+"|"-") 1*DIGIT )


Заранее спасибо. Проект практически написан, осталось вот разобрать такие строчки и тут немного встал в ступор, т.к. раньше не пользовался этой либой.
Re: boost.spirit. Поиск пустых значений.
От: jazzer Россия Skype: enerjazzer
Дата: 25.01.08 09:26
Оценка: 3 (1)
Здравствуйте, VAbrutski, Вы писали:

VA>В таком варианте все хорошо, получаю вектор [28,32]. Но мне нужно также знать о тех местах где значение было пропущено. т.е. например иметь вектор вида [0,0,0,28,0,32]


Если мне не изменяет память, есть парсер, который срабатывает всегда, и называется он, кажется, eps_p.
Соответственно тебе нужно нечто вроде
  AdvanceWidth = real_p[ push_back_a(self.lnkAdvWidth) ]
                | eps_p[ push_back_a(0) ];
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[2]: boost.spirit. Поиск пустых значений.
От: VAbrutski  
Дата: 25.01.08 10:22
Оценка:
Здравствуйте, jazzer, Вы писали:

J>Здравствуйте, VAbrutski, Вы писали:


VA>>В таком варианте все хорошо, получаю вектор [28,32]. Но мне нужно также знать о тех местах где значение было пропущено. т.е. например иметь вектор вида [0,0,0,28,0,32]


J>Если мне не изменяет память, есть парсер, который срабатывает всегда, и называется он, кажется, eps_p.

J>Соответственно тебе нужно нечто вроде
J>
J>  AdvanceWidth = real_p[ push_back_a(self.lnkAdvWidth) ]
J>                | eps_p[ push_back_a(0) ];
J>

Спасибо. Вроде то что нужно. Только что-то не выходит собственно выполнить какой либо действие по обнаружению пустого вхождения? Например тот же push_back_a.
push_back_a(0) сделать нельзя, т.к. параметром является как раз вектор куда вставлять.

Вобще судя по документации, можно выполнить функцию f eps_p[f], только не пойму какая игнатура должна быть.
Re[3]: boost.spirit. Поиск пустых значений.
От: jazzer Россия Skype: enerjazzer
Дата: 25.01.08 10:25
Оценка:
Здравствуйте, VAbrutski, Вы писали:

VA>push_back_a(0) сделать нельзя, т.к. параметром является как раз вектор куда вставлять.


А, ну да, надо push_back_a(self.lnkAdvWidth, 0)

http://boost.org/libs/spirit/doc/predefined_actors.html
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[4]: boost.spirit. Поиск пустых значений.
От: VAbrutski  
Дата: 25.01.08 10:37
Оценка:
Здравствуйте, jazzer, Вы писали:

J>Здравствуйте, VAbrutski, Вы писали:


VA>>push_back_a(0) сделать нельзя, т.к. параметром является как раз вектор куда вставлять.


J>А, ну да, надо push_back_a(self.lnkAdvWidth, 0)


J>http://boost.org/libs/spirit/doc/predefined_actors.html


Точно Спасибо буду пробовать.
Re[4]: boost.spirit. Поиск пустых значений.
От: VAbrutski  
Дата: 25.01.08 13:20
Оценка:
Здравствуйте, jazzer, Вы писали:

J>Здравствуйте, VAbrutski, Вы писали:


VA>>push_back_a(0) сделать нельзя, т.к. параметром является как раз вектор куда вставлять.


J>А, ну да, надо push_back_a(self.lnkAdvWidth, 0)


J>http://boost.org/libs/spirit/doc/predefined_actors.html


Столкнулся с еще одной небольшой загвоздкой, как по одному обноружению "пустого" вхождения выполнить несколько действий, например несколько push_back_a в разные массивы?


попробовал в порядке бреда, через запятую их указать:
eps_p[push_back_a, push_back_a ,push_back_a]

Но отрабатывает только последний.
Re[5]: boost.spirit. Поиск пустых значений.
От: Аноним  
Дата: 25.01.08 14:50
Оценка:
VA>Столкнулся с еще одной небольшой загвоздкой, как по одному обноружению "пустого" вхождения выполнить несколько действий, например несколько push_back_a в разные массивы?


VA>попробовал в порядке бреда, через запятую их указать:

VA> eps_p[push_back_a, push_back_a ,push_back_a]

VA>Но отрабатывает только последний.


eps_p[push_back_a][push_back_a][push_back_a]
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.