// 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 seqeunce as well as possibly existing duplicates. // // 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::vector > pairs_type; template struct key_value_sequence_ordered : qi::grammar { key_value_sequence_ordered() : key_value_sequence_ordered::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("key2=value2;key1;key3=value3"); std::string::iterator begin = input.begin(); std::string::iterator end = input.end(); client::key_value_sequence_ordered p; client::pairs_type v; if (!qi::parse(begin, end, p, v)) { 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 = v.end(); for (client::pairs_type::iterator it = v.begin(); it != end; ++it) { std::cout << (*it).first; if (!(*it).second.empty()) std::cout << "=" << (*it).second; std::cout << std::endl; } std::cout << "---------------------------------\n"; } return 0; }