6bea365c51
[SVN r58589]
84 lines
2.9 KiB
C++
84 lines
2.9 KiB
C++
// 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 <boost/spirit/include/qi.hpp>
|
|
#include <boost/fusion/include/std_pair.hpp>
|
|
|
|
#include <iostream>
|
|
#include <map>
|
|
|
|
namespace client
|
|
{
|
|
namespace qi = boost::spirit::qi;
|
|
|
|
typedef std::pair<std::string, boost::optional<std::string> > pair_type;
|
|
typedef std::vector<pair_type> pairs_type;
|
|
|
|
template <typename Iterator>
|
|
struct key_value_sequence_empty_value
|
|
: qi::grammar<Iterator, pairs_type()>
|
|
{
|
|
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<Iterator, pairs_type()> query;
|
|
qi::rule<Iterator, pair_type()> pair;
|
|
qi::rule<Iterator, std::string()> 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<std::string::iterator> 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<std::string>((*it).second);
|
|
std::cout << std::endl;
|
|
}
|
|
std::cout << "---------------------------------\n";
|
|
}
|
|
return 0;
|
|
}
|
|
|