f4105f823f
[SVN r37680]
153 lines
3.9 KiB
C++
153 lines
3.9 KiB
C++
// ----------------------------------------------------------------------------
|
|
// 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);
|
|
|
|
}
|