Вам не нужно открывать все атрибуты, значительно упрощая типы атрибутов.
Для сопоставления строкового литерала без предоставления его в качестве ключа (который по-видимому, вы все равно не хотите, потому что вы игнорируете это в действии semanti c), используйте x3::lit("aaa")
вместо x3::string("aaa")
. В выражении x3 голое "aaa"
будет автоматически интерпретироваться как x3::lit("aaa")
(из-за x3::as_parser
).
Более того, вы обращаетесь к at_c<2>
, подразумевая, что вы не x3::blank
тоже не подвергается. Почему не просто x3::omit[x3::blank]
? Еще лучше рассмотреть возможность использования шкипера и иметь это неявное значение.
В action
вы используете x3::_val
, что зависит от атрибута объявленного правила (нет x3 :: правило в поле зрения?) ИЛИ фактическая привязанная ссылка (вы ничего не передаете x3::parse
).
Поскольку ваше действие связывается с аргументом синтаксического анализатора, кажется, вы хотели его атрибут, который можно запросить с помощью x3::_attr()
.
Кажется, что вы можете вообще обойтись без semanti c действий, см. ниже
Исправление идей:
Это сочетает в себе все вышеперечисленное:
Посмотреть Live On Coliru
#include <boost/spirit/home/x3.hpp>
#include <iostream>
namespace x3 = boost::spirit::x3;
int main() {
auto parser_gen = [=](std::string const a, auto&& p) {
return x3::skip(x3::blank)[ x3::lit(a) >> p ];
};
for (std::string const bar : { "aaa 42", "aaa99", }) {
int a;
if (parse(begin(bar), end(bar), parser_gen("aaa", x3::uint_), a)) {
std::cout << "Parsed " << a << "\n";
} else {
std::cout << "Failed\n";
}
}
}
Печать
Parsed 42
Parsed 99
Посмотреть Live On Coliru
namespace {
template <typename P>
auto label_gen(P p) {
return x3::omit[ x3::lexeme[ x3::as_parser(p) >> (&x3::punct | !x3::graph) ] ];
}
template <typename L, typename P> auto parser_gen(L l, P p) {
return x3::skip(x3::blank)[ label_gen(l) >> p ];
}
}
Теперь печатается на один матч меньше:
Parsed 42
Failed
БОНУС: Выполнение Полезный материал
Итак, я думаю, вы хотели объединить несколько из этих пар метка / значение полезным способом, возможно, объясняя действия. Теперь вы можете взять страницу из этого ответа: Boost Spirit x3: разобрать в структуры .
На самом деле, я воздержусь от воспроизведения кода из этого примера здесь, но я думаю, что это может примените к вашему случаю использования очень хорошо.