info_grammar_spirit.cpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. // ----------------------------------------------------------------------------
  2. // Copyright (C) 2002-2006 Marcin Kalicinski
  3. //
  4. // Distributed under the Boost Software License, Version 1.0.
  5. // (See accompanying file LICENSE_1_0.txt or copy at
  6. // http://www.boost.org/LICENSE_1_0.txt)
  7. //
  8. // For more information, see www.boost.org
  9. // ----------------------------------------------------------------------------
  10. /* This is grammar of INFO file format written in form of boost::spirit rules.
  11. For simplicity, it does not parse #include directive. Note that INFO parser
  12. included in property_tree library does not use Spirit.
  13. */
  14. //#define BOOST_SPIRIT_DEBUG // uncomment to enable debug output
  15. #include <boost/spirit.hpp>
  16. struct info_grammar: public boost::spirit::grammar<info_grammar>
  17. {
  18. template<class Scanner>
  19. struct definition
  20. {
  21. boost::spirit::rule<typename boost::spirit::lexeme_scanner<Scanner>::type> chr, qchr, escape_seq;
  22. boost::spirit::rule<Scanner> string, qstring, cstring, key, value, entry, info;
  23. definition(const info_grammar &self)
  24. {
  25. using namespace boost::spirit;
  26. escape_seq = chset_p("0abfnrtv\"\'\\");
  27. chr = (anychar_p - space_p - '\\' - '{' - '}' - '#' - '"') | ('\\' >> escape_seq);
  28. qchr = (anychar_p - '"' - '\n' - '\\') | ('\\' >> escape_seq);
  29. string = lexeme_d[+chr];
  30. qstring = lexeme_d['"' >> *qchr >> '"'];
  31. cstring = lexeme_d['"' >> *qchr >> '"' >> '\\'];
  32. key = string | qstring;
  33. value = string | qstring | (+cstring >> qstring) | eps_p;
  34. entry = key >> value >> !('{' >> *entry >> '}');
  35. info = *entry >> end_p;
  36. // Debug nodes
  37. BOOST_SPIRIT_DEBUG_NODE(escape_seq);
  38. BOOST_SPIRIT_DEBUG_NODE(chr);
  39. BOOST_SPIRIT_DEBUG_NODE(qchr);
  40. BOOST_SPIRIT_DEBUG_NODE(string);
  41. BOOST_SPIRIT_DEBUG_NODE(qstring);
  42. BOOST_SPIRIT_DEBUG_NODE(key);
  43. BOOST_SPIRIT_DEBUG_NODE(value);
  44. BOOST_SPIRIT_DEBUG_NODE(entry);
  45. BOOST_SPIRIT_DEBUG_NODE(info);
  46. }
  47. const boost::spirit::rule<Scanner> &start() const
  48. {
  49. return info;
  50. }
  51. };
  52. };
  53. void info_parse(const char *s)
  54. {
  55. using namespace boost::spirit;
  56. // Parse and display result
  57. info_grammar g;
  58. parse_info<const char *> pi = parse(s, g, space_p | comment_p(";"));
  59. std::cout << "Parse result: " << (pi.hit ? "Success" : "Failure") << "\n";
  60. }
  61. int main()
  62. {
  63. // Sample data 1
  64. const char *data1 =
  65. "\n"
  66. "key1 data1\n"
  67. "{\n"
  68. "\tkey data\n"
  69. "}\n"
  70. "key2 \"data2 \" {\n"
  71. "\tkey data\n"
  72. "}\n"
  73. "key3 \"data\"\n"
  74. "\t \"3\" {\n"
  75. "\tkey data\n"
  76. "}\n"
  77. "\n"
  78. "\"key4\" data4\n"
  79. "{\n"
  80. "\tkey data\n"
  81. "}\n"
  82. "\"key.5\" \"data.5\" { \n"
  83. "\tkey data \n"
  84. "}\n"
  85. "\"key6\" \"data\"\n"
  86. "\t \"6\" {\n"
  87. "\tkey data\n"
  88. "}\n"
  89. " \n"
  90. "key1 data1\n"
  91. "{\n"
  92. "\tkey data\n"
  93. "}\n"
  94. "key2 \"data2 \" {\n"
  95. "\tkey data\n"
  96. "}\n"
  97. "key3 \"data\"\n"
  98. "\t \"3\" {\n"
  99. "\tkey data\n"
  100. "}\n"
  101. "\n"
  102. "\"key4\" data4\n"
  103. "{\n"
  104. "\tkey data\n"
  105. "}\n"
  106. "\"key.5\" \"data.5\" {\n"
  107. "\tkey data\n"
  108. "}\n"
  109. "\"key6\" \"data\"\n"
  110. "\t \"6\" {\n"
  111. "\tkey data\n"
  112. "}\n"
  113. "\\\\key\\t7 data7\\n\\\"data7\\\"\n"
  114. "{\n"
  115. "\tkey data\n"
  116. "}\n"
  117. "\"\\\\key\\t8\" \"data8\\n\\\"data8\\\"\"\n"
  118. "{\n"
  119. "\tkey data\n"
  120. "}\n"
  121. "\n";
  122. // Sample data 2
  123. const char *data2 =
  124. "key1\n"
  125. "key2\n"
  126. "key3\n"
  127. "key4\n";
  128. // Parse sample data
  129. info_parse(data1);
  130. info_parse(data2);
  131. }