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

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