• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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