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