123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152 |
- // ----------------------------------------------------------------------------
- // Copyright (C) 2002-2006 Marcin Kalicinski
- //
- // 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)
- //
- // For more information, see www.boost.org
- // ----------------------------------------------------------------------------
- /* This is grammar of INFO file format written in form of boost::spirit rules.
- For simplicity, it does not parse #include directive. Note that INFO parser
- included in property_tree library does not use Spirit.
- */
- //#define BOOST_SPIRIT_DEBUG // uncomment to enable debug output
- #include <boost/spirit.hpp>
- struct info_grammar: public boost::spirit::grammar<info_grammar>
- {
-
- template<class Scanner>
- struct definition
- {
-
- boost::spirit::rule<typename boost::spirit::lexeme_scanner<Scanner>::type> chr, qchr, escape_seq;
- boost::spirit::rule<Scanner> string, qstring, cstring, key, value, entry, info;
- definition(const info_grammar &self)
- {
- using namespace boost::spirit;
- escape_seq = chset_p("0abfnrtv\"\'\\");
- chr = (anychar_p - space_p - '\\' - '{' - '}' - '#' - '"') | ('\\' >> escape_seq);
- qchr = (anychar_p - '"' - '\n' - '\\') | ('\\' >> escape_seq);
- string = lexeme_d[+chr];
- qstring = lexeme_d['"' >> *qchr >> '"'];
- cstring = lexeme_d['"' >> *qchr >> '"' >> '\\'];
- key = string | qstring;
- value = string | qstring | (+cstring >> qstring) | eps_p;
- entry = key >> value >> !('{' >> *entry >> '}');
- info = *entry >> end_p;
- // Debug nodes
- BOOST_SPIRIT_DEBUG_NODE(escape_seq);
- BOOST_SPIRIT_DEBUG_NODE(chr);
- BOOST_SPIRIT_DEBUG_NODE(qchr);
- BOOST_SPIRIT_DEBUG_NODE(string);
- BOOST_SPIRIT_DEBUG_NODE(qstring);
- BOOST_SPIRIT_DEBUG_NODE(key);
- BOOST_SPIRIT_DEBUG_NODE(value);
- BOOST_SPIRIT_DEBUG_NODE(entry);
- BOOST_SPIRIT_DEBUG_NODE(info);
- }
- const boost::spirit::rule<Scanner> &start() const
- {
- return info;
- }
- };
- };
- void info_parse(const char *s)
- {
- using namespace boost::spirit;
- // Parse and display result
- info_grammar g;
- parse_info<const char *> pi = parse(s, g, space_p | comment_p(";"));
- std::cout << "Parse result: " << (pi.hit ? "Success" : "Failure") << "\n";
-
- }
- int main()
- {
- // Sample data 1
- const char *data1 =
- "\n"
- "key1 data1\n"
- "{\n"
- "\tkey data\n"
- "}\n"
- "key2 \"data2 \" {\n"
- "\tkey data\n"
- "}\n"
- "key3 \"data\"\n"
- "\t \"3\" {\n"
- "\tkey data\n"
- "}\n"
- "\n"
- "\"key4\" data4\n"
- "{\n"
- "\tkey data\n"
- "}\n"
- "\"key.5\" \"data.5\" { \n"
- "\tkey data \n"
- "}\n"
- "\"key6\" \"data\"\n"
- "\t \"6\" {\n"
- "\tkey data\n"
- "}\n"
- " \n"
- "key1 data1\n"
- "{\n"
- "\tkey data\n"
- "}\n"
- "key2 \"data2 \" {\n"
- "\tkey data\n"
- "}\n"
- "key3 \"data\"\n"
- "\t \"3\" {\n"
- "\tkey data\n"
- "}\n"
- "\n"
- "\"key4\" data4\n"
- "{\n"
- "\tkey data\n"
- "}\n"
- "\"key.5\" \"data.5\" {\n"
- "\tkey data\n"
- "}\n"
- "\"key6\" \"data\"\n"
- "\t \"6\" {\n"
- "\tkey data\n"
- "}\n"
- "\\\\key\\t7 data7\\n\\\"data7\\\"\n"
- "{\n"
- "\tkey data\n"
- "}\n"
- "\"\\\\key\\t8\" \"data8\\n\\\"data8\\\"\"\n"
- "{\n"
- "\tkey data\n"
- "}\n"
- "\n";
- // Sample data 2
- const char *data2 =
- "key1\n"
- "key2\n"
- "key3\n"
- "key4\n";
- // Parse sample data
- info_parse(data1);
- info_parse(data2);
- }
|