lexer.hpp 4.6 KB

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