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>
13 #include <boost/spirit/include/phoenix.hpp>
14 #include <boost/foreach.hpp>
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>
parse(const std::string message,const std::string & input,const std::string & rule,const Parser & 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:";
37 BOOST_FOREACH(result_type const& str, parsed_result)
38 {
39 std::cout << "[" << str << "]";
40 }
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>
ident()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
main()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 }
113