lexer.hpp 5.1 KB

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