• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //  Copyright (c) 2001-2011 Hartmut Kaiser
2 //  Copyright (c) 2009 Jean-Francois Ostiguy
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 #include <boost/detail/lightweight_test.hpp>
8 #include <boost/config/warning_disable.hpp>
9 
10 #include <boost/spirit/include/lex_lexertl.hpp>
11 #include <boost/spirit/include/qi_parse.hpp>
12 #include <boost/spirit/include/qi_operator.hpp>
13 #include <boost/spirit/include/qi_char.hpp>
14 #include <boost/spirit/include/qi_grammar.hpp>
15 #include <boost/spirit/include/qi_eoi.hpp>
16 
17 #include <boost/phoenix/operator/self.hpp>
18 #include <string>
19 #include <iostream>
20 #include <sstream>
21 
22 namespace lex = boost::spirit::lex;
23 namespace qi = boost::spirit::qi;
24 namespace mpl = boost::mpl;
25 
26 template <typename Lexer>
27 struct my_lexer : lex::lexer<Lexer>
28 {
my_lexermy_lexer29     my_lexer()
30     {
31         delimiter = "BEGIN|END";
32         identifier = "[a-zA-Z][_\\.a-zA-Z0-9]*";
33         ws = "[ \\t\\n]+";
34         real = "([0-9]*\\.?[0-9]+([eE][-+]?[0-9]+)?)|([-+]?[1-9]+\\.?([eE][-+]?[0-9]+))";
35         integer = "[0-9]+";
36 
37         this->self += ws[lex::_pass = lex::pass_flags::pass_ignore];
38         this->self += delimiter;
39         this->self += identifier;
40         this->self += real;
41         this->self += integer;
42         this->self += '=';
43         this->self += ';';
44     }
45 
46     lex::token_def<> ws;
47     lex::token_def<std::string> identifier;
48     lex::token_def<int> integer;
49     lex::token_def<double> real;
50     lex::token_def<> delimiter;
51 };
52 
53 template <typename Iterator>
54 struct my_grammar : qi::grammar<Iterator>
55 {
56     template <typename TokenDef>
my_grammarmy_grammar57     my_grammar( TokenDef const& tok )
58       :  my_grammar::base_type(statement)
59     {
60         statement
61             =   qi::eoi
62             |  *(delimiter | declaration)
63             ;
64 
65         delimiter = tok.delimiter >> tok.identifier;
66         declaration = tok.identifier >> option >> ';';
67         option = *(tok.identifier >> '=' >> (tok.real | tok.integer));
68     }
69 
70     qi::rule<Iterator> statement, delimiter, declaration, option;
71 };
72 
73 typedef lex::lexertl::token<char const*
74   , mpl::vector<std::string, double, int> > token_type;
75 typedef lex::lexertl::actor_lexer<token_type> lexer_type;
76 typedef my_lexer<lexer_type>::iterator_type iterator_type;
77 
main()78 int main()
79 {
80     std::string test_string ("BEGIN section\n");
81     // we introduce a syntax error: ";;" instead of ";" as a terminator.
82     test_string += "Identity;;\n";      // this will make the parser fail
83     test_string += "END section\n" ;
84 
85     char const* first = &test_string[0];
86     char const* last  = &first[test_string.size()];
87 
88     my_lexer<lexer_type> lexer;
89     my_grammar<iterator_type> grammar(lexer);
90 
91     BOOST_TEST(lex::tokenize_and_parse(first, last, lexer, grammar));
92     BOOST_TEST(first != last);
93 
94     return boost::report_errors();
95 }
96 
97 
98