key_value_sequence.cpp 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  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. // The purpose of this example is to show how to parse arbitrary key/value
  6. // pairs delimited by some separator into a std::map. Parsing the URL query
  7. // format is the example we use to demonstrate how this can be done
  8. // (i.e. things like: key1=value1;key2=value2;...;keyN=valueN).
  9. //
  10. // For a more elaborate explanation see here: http://spirit.sourceforge.net/home/?p=371
  11. #include <boost/spirit/include/qi.hpp>
  12. #include <boost/fusion/include/std_pair.hpp>
  13. #include <iostream>
  14. #include <map>
  15. namespace client
  16. {
  17. namespace qi = boost::spirit::qi;
  18. typedef std::map<std::string, std::string> pairs_type;
  19. template <typename Iterator>
  20. struct key_value_sequence
  21. : qi::grammar<Iterator, pairs_type()>
  22. {
  23. key_value_sequence()
  24. : key_value_sequence::base_type(query)
  25. {
  26. query = pair >> *((qi::lit(';') | '&') >> pair);
  27. pair = key >> -('=' >> value);
  28. key = qi::char_("a-zA-Z_") >> *qi::char_("a-zA-Z_0-9");
  29. value = +qi::char_("a-zA-Z_0-9");
  30. }
  31. qi::rule<Iterator, pairs_type()> query;
  32. qi::rule<Iterator, std::pair<std::string, std::string>()> pair;
  33. qi::rule<Iterator, std::string()> key, value;
  34. };
  35. }
  36. ///////////////////////////////////////////////////////////////////////////////
  37. int main()
  38. {
  39. namespace qi = boost::spirit::qi;
  40. std::string input("key1=value1;key2;key3=value3");
  41. std::string::iterator begin = input.begin();
  42. std::string::iterator end = input.end();
  43. client::key_value_sequence<std::string::iterator> p;
  44. client::pairs_type m;
  45. if (!qi::parse(begin, end, p, m))
  46. {
  47. std::cout << "-------------------------------- \n";
  48. std::cout << "Parsing failed\n";
  49. std::cout << "-------------------------------- \n";
  50. }
  51. else
  52. {
  53. std::cout << "-------------------------------- \n";
  54. std::cout << "Parsing succeeded, found entries:\n";
  55. client::pairs_type::iterator end = m.end();
  56. for (client::pairs_type::iterator it = m.begin(); it != end; ++it)
  57. {
  58. std::cout << (*it).first;
  59. if (!(*it).second.empty())
  60. std::cout << "=" << (*it).second;
  61. std::cout << std::endl;
  62. }
  63. std::cout << "---------------------------------\n";
  64. }
  65. return 0;
  66. }