blob: 07025341b61a8e79b8153b615c99b9342fd78fc7 [file] [log] [blame]
// ----------------------------------------------------------------------------
// 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);
}