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