• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
25 namespace 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
operator ()client::lexer::conjure_tokens98         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(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
tokenclient::lexer::conjure_tokens109         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(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