1/*=============================================================================
2 Copyright (c) 2001-2011 Hartmut Kaiser
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#if !defined(BOOST_SPIRIT_CONJURE_LEXER_HPP)
8#define BOOST_SPIRIT_CONJURE_LEXER_HPP
9
10#include <boost/spirit/include/lex_lexertl.hpp>
11#include <boost/spirit/include/lex_lexertl_position_token.hpp>
12
13#include "config.hpp"
14#include "ids.hpp"
15
16#if CONJURE_LEXER_STATIC_TABLES != 0
17#include <boost/spirit/include/lex_static_lexertl.hpp>
18#include "conjure_static_lexer.hpp"
19#elif CONJURE_LEXER_STATIC_SWITCH != 0
20#include <boost/spirit/include/lex_static_lexertl.hpp>
21#include "conjure_static_switch_lexer.hpp"
22#endif
23#include <boost/assert.hpp>
24
25namespace client { namespace lexer
26{
27 namespace lex = boost::spirit::lex;
28
29 ///////////////////////////////////////////////////////////////////////////
30 namespace detail
31 {
32 namespace lex = boost::spirit::lex;
33
34 template <typename BaseIterator>
35 struct get_lexer_type
36 {
37 // Our token needs to be able to carry several token values:
38 // std::string, unsigned int, and bool
39 typedef boost::mpl::vector<std::string, unsigned int, bool>
40 token_value_types;
41
42 // Using the position_token class as the token type to be returned
43 // from the lexer iterators allows to retain positional information
44 // as every token instance stores an iterator pair pointing to the
45 // matched input sequence.
46 typedef lex::lexertl::position_token<
47 BaseIterator, token_value_types, boost::mpl::false_
48 > token_type;
49
50#if CONJURE_LEXER_DYNAMIC_TABLES != 0
51 // use the lexer based on runtime generated DFA tables
52 typedef lex::lexertl::actor_lexer<token_type> type;
53#elif CONJURE_LEXER_STATIC_TABLES != 0
54 // use the lexer based on pre-generated static DFA tables
55 typedef lex::lexertl::static_actor_lexer<
56 token_type
57 , boost::spirit::lex::lexertl::static_::lexer_conjure_static
58 > type;
59#elif CONJURE_LEXER_STATIC_SWITCH != 0
60 // use the lexer based on pre-generated static code
61 typedef lex::lexertl::static_actor_lexer<
62 token_type
63 , boost::spirit::lex::lexertl::static_::lexer_conjure_static_switch
64 > type;
65#else
66#error "Configuration problem: please select exactly one type of lexer to build"
67#endif
68 };
69 }
70
71 ///////////////////////////////////////////////////////////////////////////
72 template <typename BaseIterator>
73 struct conjure_tokens
74 : lex::lexer<typename detail::get_lexer_type<BaseIterator>::type>
75 {
76 private:
77 // get the type of any qi::raw_token(...) and qi::token(...) constructs
78 typedef typename boost::spirit::result_of::terminal<
79 boost::spirit::tag::raw_token(token_ids::type)
80 >::type raw_token_spec;
81
82 typedef typename boost::spirit::result_of::terminal<
83 boost::spirit::tag::token(token_ids::type)
84 >::type token_spec;
85
86 typedef std::map<std::string, token_ids::type> keyword_map_type;
87
88 protected:
89 // add a keyword to the mapping table
90 bool add_keyword(std::string const& keyword);
91
92 public:
93 typedef BaseIterator base_iterator_type;
94
95 conjure_tokens();
96
97 // extract a raw_token(id) for the given registered keyword
98 raw_token_spec operator()(std::string const& kwd) const
99 {
100 namespace qi = boost::spirit::qi;
101 qi::raw_token_type raw_token;
102
103 typename keyword_map_type::const_iterator it = keywords_.find(x: kwd);
104 BOOST_ASSERT(it != keywords_.end());
105 return raw_token((it != keywords_.end()) ? (*it).second : token_ids::invalid);
106 }
107
108 // extract a token(id) for the given registered keyword
109 token_spec token(std::string const& kwd) const
110 {
111 namespace qi = boost::spirit::qi;
112 qi::token_type token;
113
114 typename keyword_map_type::const_iterator it = keywords_.find(x: kwd);
115 BOOST_ASSERT(it != keywords_.end());
116 return token((it != keywords_.end()) ? (*it).second : token_ids::invalid);
117 }
118
119 lex::token_def<std::string> identifier;
120 lex::token_def<unsigned int> lit_uint;
121 lex::token_def<bool> true_or_false;
122 keyword_map_type keywords_;
123 };
124}}
125
126#endif
127
128
129

source code of boost/libs/spirit/example/qi/compiler_tutorial/conjure2/lexer.hpp