• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //  Copyright (c) 2001-2010 Hartmut Kaiser
2 //
3 //  Distributed under the Boost Software License, Version 1.0. (See accompanying
4 //  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5 
6 // The purpose of this example is to show how to parse arbitrary key/value
7 // pairs delimited by some separator into a std::map. Parsing the URL query
8 // format is the example we use to demonstrate how this can be done
9 // (i.e. things like: key1=value1;key2=value2;...;keyN=valueN).
10 //
11 // For a more elaborate explanation see here: http://spirit.sourceforge.net/home/?p=371
12 
13 #include <boost/spirit/include/qi.hpp>
14 #include <boost/fusion/include/std_pair.hpp>
15 
16 #include <iostream>
17 #include <map>
18 
19 namespace client
20 {
21     namespace qi = boost::spirit::qi;
22 
23     typedef std::map<std::string, std::string> pairs_type;
24 
25     template <typename Iterator>
26     struct key_value_sequence
27       : qi::grammar<Iterator, pairs_type()>
28     {
key_value_sequenceclient::key_value_sequence29         key_value_sequence()
30           : key_value_sequence::base_type(query)
31         {
32             query =  pair >> *((qi::lit(';') | '&') >> pair);
33             pair  =  key >> -('=' >> value);
34             key   =  qi::char_("a-zA-Z_") >> *qi::char_("a-zA-Z_0-9");
35             value = +qi::char_("a-zA-Z_0-9");
36         }
37 
38         qi::rule<Iterator, pairs_type()> query;
39         qi::rule<Iterator, std::pair<std::string, std::string>()> pair;
40         qi::rule<Iterator, std::string()> key, value;
41     };
42 }
43 
44 ///////////////////////////////////////////////////////////////////////////////
main()45 int main()
46 {
47     namespace qi = boost::spirit::qi;
48 
49     std::string input("key1=value1;key2;key3=value3");
50     std::string::iterator begin = input.begin();
51     std::string::iterator end = input.end();
52 
53     client::key_value_sequence<std::string::iterator> p;
54     client::pairs_type m;
55 
56     if (!qi::parse(begin, end, p, m))
57     {
58         std::cout << "-------------------------------- \n";
59         std::cout << "Parsing failed\n";
60         std::cout << "-------------------------------- \n";
61     }
62     else
63     {
64         std::cout << "-------------------------------- \n";
65         std::cout << "Parsing succeeded, found entries:\n";
66         client::pairs_type::iterator end = m.end();
67         for (client::pairs_type::iterator it = m.begin(); it != end; ++it)
68         {
69             std::cout << (*it).first;
70             if (!(*it).second.empty())
71                 std::cout << "=" << (*it).second;
72             std::cout << std::endl;
73         }
74         std::cout << "---------------------------------\n";
75     }
76     return 0;
77 }
78 
79