key_value_sequence_ordered.cpp 2.6 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::vector. The difference to
  7. // the example 'key_value_sequence.cpp' is that we preserve the order of the
  8. // elements in the parsed seqeunce as well as possibly existing duplicates.
  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::vector<std::pair<std::string, std::string> > pairs_type;
  19. template <typename Iterator>
  20. struct key_value_sequence_ordered
  21. : qi::grammar<Iterator, pairs_type()>
  22. {
  23. key_value_sequence_ordered()
  24. : key_value_sequence_ordered::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("key2=value2;key1;key3=value3");
  41. std::string::iterator begin = input.begin();
  42. std::string::iterator end = input.end();
  43. client::key_value_sequence_ordered<std::string::iterator> p;
  44. client::pairs_type v;
  45. if (!qi::parse(begin, end, p, v))
  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 = v.end();
  56. for (client::pairs_type::iterator it = v.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. }