Ранее 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 )
Заранее спасибо. Проект практически написан, осталось вот разобрать такие строчки и тут немного встал в ступор, т.к. раньше не пользовался этой либой.
Здравствуйте, 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, Вы писали:
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], только не пойму какая игнатура должна быть.
Здравствуйте, VAbrutski, Вы писали:
VA>push_back_a(0) сделать нельзя, т.к. параметром является как раз вектор куда вставлять.
А, ну да, надо push_back_a(self.lnkAdvWidth, 0)
http://boost.org/libs/spirit/doc/predefined_actors.html
Здравствуйте, 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
Точно
Спасибо
буду пробовать.
Здравствуйте, 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]
Но отрабатывает только последний.
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]