blob: 07025341b61a8e79b8153b615c99b9342fd78fc7 [file] [log] [blame]
Brian Silverman836e90c2018-08-04 16:19:46 -07001// ----------------------------------------------------------------------------
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
19struct 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
29 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
58 const boost::spirit::rule<Scanner> &start() const
59 {
60 return info;
61 }
62
63 };
64};
65
66void 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
78int 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}