]>
Commit | Line | Data |
---|---|---|
b32b8144 FG |
1 | /*============================================================================= |
2 | Copyright (c) 2016 Frank Hein, maxence business consulting gmbh | |
3 | ||
4 | Distributed under the Boost Software License, Version 1.0. (See accompanying | |
5 | file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
6 | ==============================================================================*/ | |
7 | ||
8 | #include <iostream> | |
9 | #include <map> | |
10 | ||
11 | #include <boost/spirit/home/qi.hpp> | |
12 | #include <boost/spirit/home/qi/nonterminal/grammar.hpp> | |
1e59de90 | 13 | #include <boost/phoenix.hpp> |
11fdf7f2 | 14 | #include <boost/foreach.hpp> |
b32b8144 FG |
15 | |
16 | namespace qi = boost::spirit::qi; | |
17 | ||
18 | typedef std::string::const_iterator iterator_type; | |
19 | typedef std::string result_type; | |
20 | ||
21 | template<typename Parser> | |
22 | void parse(const std::string message, const std::string& input, const std::string& rule, const Parser& parser) { | |
23 | iterator_type iter = input.begin(), end = input.end(); | |
24 | ||
25 | std::vector<result_type> parsed_result; | |
26 | ||
27 | std::cout << "-------------------------\n"; | |
28 | std::cout << message << "\n"; | |
29 | std::cout << "Rule: " << rule << std::endl; | |
30 | std::cout << "Parsing: \"" << input << "\"\n"; | |
31 | ||
32 | bool result = qi::phrase_parse(iter, end, parser, qi::space, parsed_result); | |
33 | if (result) | |
34 | { | |
35 | std::cout << "Parser succeeded.\n"; | |
36 | std::cout << "Parsed " << parsed_result.size() << " elements:"; | |
11fdf7f2 TL |
37 | BOOST_FOREACH(result_type const& str, parsed_result) |
38 | { | |
b32b8144 | 39 | std::cout << "[" << str << "]"; |
11fdf7f2 | 40 | } |
b32b8144 FG |
41 | std::cout << std::endl; |
42 | } | |
43 | else | |
44 | { | |
45 | std::cout << "Parser failed" << std::endl; | |
46 | } | |
47 | if (iter == end) { | |
48 | std::cout << "EOI reached." << std::endl; | |
49 | } | |
50 | else { | |
51 | std::cout << "EOI not reached. Unparsed: \"" << std::string(iter, end) << "\"" << std::endl; | |
52 | } | |
53 | std::cout << "-------------------------\n"; | |
54 | ||
55 | } | |
56 | ||
57 | namespace grammars { | |
58 | namespace phx = boost::phoenix; | |
59 | ||
60 | template <typename Iterator> | |
61 | struct ident : qi::grammar < Iterator, std::string(), qi::space_type> | |
62 | { | |
63 | ident(); | |
64 | ||
65 | qi::rule <iterator_type, std::string(), qi::space_type> | |
66 | id, id_list, qualified_id; | |
67 | }; | |
68 | ||
69 | template <typename Iterator> | |
70 | ident<Iterator>::ident() : ident::base_type(id_list) { | |
71 | ||
72 | using qi::on_error; | |
73 | using qi::fail; | |
74 | using qi::expect; | |
75 | ||
76 | id = (qi::alpha | qi::char_('_')) >> *(qi::alnum | qi::char_('_')); | |
77 | ||
78 | id_list = expect[id >> qi::lit(';')]; | |
79 | ||
80 | on_error<fail>(id_list, | |
81 | phx::ref(std::cout) | |
82 | << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl | |
83 | << "Error! Expecting " | |
84 | << qi::_4 | |
85 | << " here: " | |
86 | << phx::construct<std::string>(qi::_3, qi::_2) << std::endl | |
87 | << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl | |
88 | ); | |
89 | } | |
90 | } | |
91 | ||
92 | int main() { | |
93 | ||
94 | grammars::ident<iterator_type> id; | |
95 | ||
96 | parse("expect directive, fail on first" | |
97 | , "1234; id2;" | |
98 | , "qi::expect[ id >> qi::lit(';') ]" | |
99 | , id); | |
100 | ||
101 | parse("expect directive, fail on second" | |
102 | , "id1, id2" | |
103 | , "qi::expect[ id >> qi::lit(';') ]" | |
104 | , id); | |
105 | ||
106 | parse("expect directive, success" | |
107 | , "id1;" | |
108 | , "qi::expect[ id >> qi::lit(';') ]" | |
109 | , id); | |
110 | ||
111 | return 0; | |
112 | } |