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