1// Copyright (c) 2001-2011 Hartmut Kaiser
2//
3// Distributed under the Boost Software License, Version 1.0. (See accompanying
4// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5
6#include <boost/spirit/include/lex_lexertl.hpp>
7#include <boost/spirit/include/qi_parse.hpp>
8#include <boost/spirit/include/qi_operator.hpp>
9#include "test_parser.hpp"
10
11#include <boost/core/lightweight_test.hpp>
12
13///////////////////////////////////////////////////////////////////////////////
14// Token definition
15///////////////////////////////////////////////////////////////////////////////
16template <typename Lexer>
17struct switch_state_tokens : boost::spirit::lex::lexer<Lexer>
18{
19 switch_state_tokens()
20 {
21 // define tokens and associate them with the lexer
22 identifier = "[a-zA-Z_][a-zA-Z0-9_]*";
23 this->self = identifier;
24
25 // any token definition to be used as the skip parser during parsing
26 // has to be associated with a separate lexer state (here 'WS')
27 white_space = "[ \\t\\n]+";
28 this->self("WS") = white_space;
29
30 separators = "[,;]";
31 this->self("SEP") = separators;
32 }
33
34 boost::spirit::lex::token_def<> identifier, white_space, separators;
35};
36
37///////////////////////////////////////////////////////////////////////////////
38int main()
39{
40 using namespace boost::spirit;
41 using namespace boost::spirit::qi;
42 using namespace spirit_test;
43
44 typedef std::string::iterator base_iterator_type;
45 typedef boost::spirit::lex::lexertl::token<base_iterator_type> token_type;
46 typedef boost::spirit::lex::lexertl::lexer<token_type> lexer_type;
47
48 {
49 // the tokens class will be initialized inside the test_parser function
50 switch_state_tokens<lexer_type> lex;
51
52 BOOST_TEST(test_parser("ident", lex.identifier, lex));
53 BOOST_TEST(!test_parser("ident", set_state("WS") >> lex.identifier, lex));
54 BOOST_TEST(!test_parser("ident", in_state("WS")[lex.identifier], lex));
55
56 BOOST_TEST(test_parser("\t \n", set_state("WS") >> lex.white_space, lex));
57 BOOST_TEST(test_parser("\t \n", in_state("WS")[lex.white_space], lex));
58 BOOST_TEST(!test_parser("\t \n", lex.white_space, lex));
59 }
60
61 {
62 // the tokens class will be initialized inside the test_parser function
63 switch_state_tokens<lexer_type> lex;
64
65 BOOST_TEST(test_parser(",ident", lex.identifier, lex,
66 in_state("SEP")[lex.separators]));
67 BOOST_TEST(!test_parser(";ident", set_state("WS") >> lex.identifier,
68 lex, in_state("SEP")[lex.separators]));
69 BOOST_TEST(!test_parser(",ident", in_state("WS")[lex.identifier],
70 lex, in_state("SEP")[lex.separators]));
71
72 BOOST_TEST(test_parser(",\t \n", set_state("WS") >> lex.white_space,
73 lex, in_state("SEP")[lex.separators]));
74 BOOST_TEST(test_parser(";\t \n", in_state("WS")[lex.white_space],
75 lex, in_state("SEP")[lex.separators]));
76 BOOST_TEST(!test_parser(",\t \n", lex.white_space, lex,
77 in_state("SEP")[lex.separators]));
78 }
79
80 {
81 // the tokens class will be initialized inside the test_parser function
82 switch_state_tokens<lexer_type> lex;
83
84 BOOST_TEST(test_parser("ident\t \n",
85 lex.identifier >> set_state("WS") >> lex.white_space, lex));
86 BOOST_TEST(test_parser("\t \nident",
87 in_state("WS")[lex.white_space] >> lex.identifier, lex));
88 }
89
90 return boost::report_errors();
91}
92
93

source code of boost/libs/spirit/test/lex/state_switcher.cpp