// Copyright (c) 2001-2010 Hartmut Kaiser // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // The purpose of this example is to show how to parse arbitrary key/value // pairs delimited by some separator into a std::vector. The difference to // the example 'key_value_sequence.cpp' is that we preserve the order of the // elements in the parsed sequence as well as possibly existing duplicates. // In addition to the example 'key_value_sequence_ordered.cpp' we allow for // empty values, i.e. the grammar allows to distinguish between 'key=;' and // 'key;", where the first stores an empty string as the value, while the // second does not initialize the optional holding the value. // // For a more elaborate explanation see here: http://spirit.sourceforge.net/home/?p=371 #include #include #include #include namespace client { namespace qi = boost::spirit::qi; typedef std::pair > pair_type; typedef std::vector pairs_type; template struct key_value_sequence_empty_value : qi::grammar { key_value_sequence_empty_value() : key_value_sequence_empty_value::base_type(query) { query = pair >> *((qi::lit(';') | '&') >> pair); pair = key >> -('=' >> -value); key = qi::char_("a-zA-Z_") >> *qi::char_("a-zA-Z_0-9"); value = +qi::char_("a-zA-Z_0-9"); } qi::rule query; qi::rule pair; qi::rule key, value; }; } /////////////////////////////////////////////////////////////////////////////// int main() { namespace qi = boost::spirit::qi; std::string input("key1=value1;key2;key3=value3;key4="); std::string::iterator begin = input.begin(); std::string::iterator end = input.end(); client::key_value_sequence_empty_value p; client::pairs_type m; if (!qi::parse(begin, end, p, m)) { std::cout << "-------------------------------- \n"; std::cout << "Parsing failed\n"; std::cout << "-------------------------------- \n"; } else { std::cout << "-------------------------------- \n"; std::cout << "Parsing succeeded, found entries:\n"; client::pairs_type::iterator end = m.end(); for (client::pairs_type::iterator it = m.begin(); it != end; ++it) { std::cout << (*it).first; if ((*it).second) std::cout << "=" << boost::get((*it).second); std::cout << std::endl; } std::cout << "---------------------------------\n"; } return 0; }