На этот вопрос был дан ответ до . Тем не менее, существует целый ряд проблем с вашим опубликованным кодом, поэтому я исправляю их один за другим, чтобы избавить вас от ненужного просмотра страниц сообщений об ошибках.
Рабочий код (плюс проверка вывода ) здесь, на liveworkspace.org .
Примечания:
boost::bind
, phoenix::bind
, std::bind
phoenix::lambda<>
или phoenix::function<>
указатель функции или полиморфный вызываемый объект (согласно документации), я рекомендовал бы phoenix::bind
(в данном конкретном случае), который я ниже qi::char_
ест все символы . В сочетании со шкипером это привело к сбою синтаксического анализа, потому что (очевидно) цифры в значении также были съедены +qi::char_
. Я покажу вам одно из многих решений, основанное на qi::lexeme[+qi::graph]
qi::lexeme
для «обхода» шкипера (т. Е. Чтобы предотвратить + qi :: graph, чтобы разрезать пробелы, потому что шкипер, ну, пропустил он) qi::parse
не берет шкипера; используйте qi::phrase_parse
для этого (причина, по которой она появилась , заключается в том, что любые конечные «вариативные» аргументы связаны с открытыми атрибутами синтаксического анализатора, которые в этом случае не указаны, и, следовательно, qi::unused_type
). test.begin()
и test.end()
прямо на qi::phrase_parse
, вам нужно четко указать, что вы хотите использовать итераторы const. Более типичным решением было бы ввести явно типизированные переменные (first
и last
, например.)
#define BOOST_SPIRIT_USE_PHOENIX_V3
#include
#include
#include
namespace qi = boost::spirit::qi;
namespace phx = boost::phoenix;
typedef qi::symbols constants_dictionary;
template struct parser : qi::grammar
{
parser(constants_dictionary &dict) : parser::base_type(start)
{
start = qi::lit("@") >> (qi::lexeme [+qi::graph] >> qi::uint_)
[ phx::bind(dict.add, qi::_1, qi::_2) ]
;
}
qi::rule start;
};
int main() {
constants_dictionary dict;
parser prsr(dict);
const std::string test = "@foo 3";
if (qi::phrase_parse(test.begin(), test.end(), prsr, qi::space))
{
std::cout << "check: " << dict.at("foo") << "\n";
}
}