• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
11 /* This is grammar of INFO file format written in form of boost::spirit rules.
12    For simplicity, it does not parse #include directive. Note that INFO parser
13    included in property_tree library does not use Spirit.
14 */
15 
16 //#define BOOST_SPIRIT_DEBUG        // uncomment to enable debug output
17 #include <boost/spirit.hpp>
18 
19 struct info_grammar: public boost::spirit::grammar<info_grammar>
20 {
21 
22     template<class Scanner>
23     struct definition
24     {
25 
26         boost::spirit::rule<typename boost::spirit::lexeme_scanner<Scanner>::type> chr, qchr, escape_seq;
27         boost::spirit::rule<Scanner> string, qstring, cstring, key, value, entry, info;
28 
definitioninfo_grammar::definition29         definition(const info_grammar &self)
30         {
31 
32             using namespace boost::spirit;
33 
34             escape_seq = chset_p("0abfnrtv\"\'\\");
35             chr = (anychar_p - space_p - '\\' - '{' - '}' - '#' - '"') | ('\\' >> escape_seq);
36             qchr = (anychar_p - '"' - '\n' - '\\') | ('\\' >> escape_seq);
37             string = lexeme_d[+chr];
38             qstring = lexeme_d['"' >> *qchr >> '"'];
39             cstring = lexeme_d['"' >> *qchr >> '"' >> '\\'];
40             key = string | qstring;
41             value = string | qstring | (+cstring >> qstring) | eps_p;
42             entry = key >> value >> !('{' >> *entry >> '}');
43             info = *entry >> end_p;
44 
45             // Debug nodes
46             BOOST_SPIRIT_DEBUG_NODE(escape_seq);
47             BOOST_SPIRIT_DEBUG_NODE(chr);
48             BOOST_SPIRIT_DEBUG_NODE(qchr);
49             BOOST_SPIRIT_DEBUG_NODE(string);
50             BOOST_SPIRIT_DEBUG_NODE(qstring);
51             BOOST_SPIRIT_DEBUG_NODE(key);
52             BOOST_SPIRIT_DEBUG_NODE(value);
53             BOOST_SPIRIT_DEBUG_NODE(entry);
54             BOOST_SPIRIT_DEBUG_NODE(info);
55 
56         }
57 
startinfo_grammar::definition58         const boost::spirit::rule<Scanner> &start() const
59         {
60             return info;
61         }
62 
63     };
64 };
65 
info_parse(const char * s)66 void info_parse(const char *s)
67 {
68 
69     using namespace boost::spirit;
70 
71     // Parse and display result
72     info_grammar g;
73     parse_info<const char *> pi = parse(s, g, space_p | comment_p(";"));
74     std::cout << "Parse result: " << (pi.hit ? "Success" : "Failure") << "\n";
75 
76 }
77 
main()78 int main()
79 {
80 
81     // Sample data 1
82     const char *data1 =
83         "\n"
84         "key1 data1\n"
85         "{\n"
86         "\tkey data\n"
87         "}\n"
88         "key2 \"data2  \" {\n"
89         "\tkey data\n"
90         "}\n"
91         "key3 \"data\"\n"
92         "\t \"3\" {\n"
93         "\tkey data\n"
94         "}\n"
95         "\n"
96         "\"key4\" data4\n"
97         "{\n"
98         "\tkey data\n"
99         "}\n"
100         "\"key.5\" \"data.5\" { \n"
101         "\tkey data \n"
102         "}\n"
103         "\"key6\" \"data\"\n"
104         "\t   \"6\" {\n"
105         "\tkey data\n"
106         "}\n"
107         "   \n"
108         "key1 data1\n"
109         "{\n"
110         "\tkey data\n"
111         "}\n"
112         "key2 \"data2  \" {\n"
113         "\tkey data\n"
114         "}\n"
115         "key3 \"data\"\n"
116         "\t \"3\" {\n"
117         "\tkey data\n"
118         "}\n"
119         "\n"
120         "\"key4\" data4\n"
121         "{\n"
122         "\tkey data\n"
123         "}\n"
124         "\"key.5\" \"data.5\" {\n"
125         "\tkey data\n"
126         "}\n"
127         "\"key6\" \"data\"\n"
128         "\t   \"6\" {\n"
129         "\tkey data\n"
130         "}\n"
131         "\\\\key\\t7 data7\\n\\\"data7\\\"\n"
132         "{\n"
133         "\tkey data\n"
134         "}\n"
135         "\"\\\\key\\t8\" \"data8\\n\\\"data8\\\"\"\n"
136         "{\n"
137         "\tkey data\n"
138         "}\n"
139         "\n";
140 
141     // Sample data 2
142     const char *data2 =
143         "key1\n"
144         "key2\n"
145         "key3\n"
146         "key4\n";
147 
148     // Parse sample data
149     info_parse(data1);
150     info_parse(data2);
151 
152 }
153