• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*=============================================================================
2     Copyright (c) 2003 Sam Nabialek
3     Copyright (c) 2001-2010 Joel de Guzman
4 
5     Distributed under the Boost Software License, Version 1.0. (See accompanying
6     file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 =============================================================================*/
8 ///////////////////////////////////////////////////////////////////////////////
9 //
10 //  The Nabialek trick.
11 //
12 //  [ Sam Nabialek; Somewhere, sometime in 2003... ]    spirit1
13 //  [ JDG November 17, 2009 ]                           spirit2
14 //  [ JDG January 10, 2010 ]                            Updated to use rule pointers
15 //                                                      for efficiency.
16 //
17 ///////////////////////////////////////////////////////////////////////////////
18 
19 #include <boost/config/warning_disable.hpp>
20 #include <boost/spirit/include/qi.hpp>
21 #include <boost/spirit/include/phoenix_operator.hpp>
22 #include <iostream>
23 #include <string>
24 
25 namespace client
26 {
27     namespace qi = boost::spirit::qi;
28     namespace ascii = boost::spirit::ascii;
29 
30     ///////////////////////////////////////////////////////////////////////////////
31     //  Our nabialek_trick grammar
32     ///////////////////////////////////////////////////////////////////////////////
33     template <typename Iterator>
34     struct nabialek_trick : qi::grammar<
35         Iterator, ascii::space_type, qi::locals<qi::rule<Iterator, ascii::space_type>*> >
36     {
nabialek_trickclient::nabialek_trick37         nabialek_trick() : nabialek_trick::base_type(start)
38         {
39             using ascii::alnum;
40             using qi::lexeme;
41             using qi::lazy;
42             using qi::_a;
43             using qi::_1;
44 
45             id = lexeme[*(ascii::alnum | '_')];
46             one = id;
47             two = id >> ',' >> id;
48 
49             keyword.add
50                 ("one", &one)
51                 ("two", &two)
52                 ;
53 
54             start = *(keyword[_a = _1] >> lazy(*_a));
55         }
56 
57         qi::rule<Iterator, ascii::space_type> id, one, two;
58         qi::rule<Iterator, ascii::space_type, qi::locals<qi::rule<Iterator, ascii::space_type>*> > start;
59         qi::symbols<char, qi::rule<Iterator, ascii::space_type>*> keyword;
60     };
61 }
62 
63 ///////////////////////////////////////////////////////////////////////////////
64 //  Main program
65 ///////////////////////////////////////////////////////////////////////////////
66 int
main()67 main()
68 {
69     using boost::spirit::ascii::space;
70     typedef std::string::const_iterator iterator_type;
71     typedef client::nabialek_trick<iterator_type> nabialek_trick;
72 
73     nabialek_trick g; // Our grammar
74 
75     std::string str = "one only\none again\ntwo first,second";
76     std::string::const_iterator iter = str.begin();
77     std::string::const_iterator end = str.end();
78     bool r = phrase_parse(iter, end, g, space);
79 
80     if (r && iter == end)
81     {
82         std::cout << "-------------------------\n";
83         std::cout << "Parsing succeeded\n";
84         std::cout << "-------------------------\n";
85     }
86     else
87     {
88         std::string rest(iter, end);
89         std::cout << "-------------------------\n";
90         std::cout << "Parsing failed\n";
91         std::cout << "stopped at: \": " << rest << "\"\n";
92         std::cout << "-------------------------\n";
93     }
94 
95     return 0;
96 }
97 
98 
99