master_lexer_state.h 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. // Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
  2. //
  3. // Permission to use, copy, modify, and/or distribute this software for any
  4. // purpose with or without fee is hereby granted, provided that the above
  5. // copyright notice and this permission notice appear in all copies.
  6. //
  7. // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
  8. // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  9. // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
  10. // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  11. // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  12. // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  13. // PERFORMANCE OF THIS SOFTWARE.
  14. #ifndef MASTER_LEXER_STATE_H
  15. #define MASTER_LEXER_STATE_H 1
  16. #include <dns/master_lexer.h>
  17. namespace isc {
  18. namespace dns {
  19. namespace master_lexer_internal {
  20. /// \brief Tokenization state for \c MasterLexer.
  21. ///
  22. /// This is a base class of classes that represent various states of a single
  23. /// tokenization session of \c MasterLexer, i.e., the states used for a
  24. /// single call to \c MasterLexer::getNextToken().
  25. ///
  26. /// It follows the convention of the state design pattern: each derived class
  27. /// corresponds to a specific state, and the state transition takes place
  28. /// through the virtual method named \c handle(). The \c handle() method
  29. /// takes the main \c MasterLexer object that holds all necessary internal
  30. /// context, and updates it as necessary; each \c State derived class is
  31. /// completely stateless.
  32. ///
  33. /// The initial transition takes place in a static method of the base class,
  34. /// \c start(). This is mainly for implementation convenience; we need to
  35. /// pass options given to \c MasterLexer::getNextToken() for the initial
  36. /// state, so it makes more sense to separate the interface for the transition
  37. /// from the initial state.
  38. ///
  39. /// When an object of a specific state class completes the session, it
  40. /// normally sets the identified token in the lexer, and returns NULL;
  41. /// if more transition is necessary, it returns a pointer to the next state
  42. /// object.
  43. ///
  44. /// As is usual in the state design pattern, the \c State class is made
  45. /// a friend class of \c MasterLexer and can refer to its internal details.
  46. /// This is intentional; essentially its a part of \c MasterLexer and
  47. /// is defined as a separate class only for implementation clarity and better
  48. /// testability. It's defined in a publicly visible header, but that's only
  49. /// for testing purposes. No normal application or even no other classes of
  50. /// this library are expected to use this class.
  51. class State {
  52. public:
  53. /// \brief Begin state transitions to get the next token.
  54. ///
  55. /// This is the first method that \c MasterLexer needs to call for a
  56. /// tokenization session. The lexer passes a reference to itself
  57. /// and options given in \c getNextToken().
  58. ///
  59. /// \throw InputSource::ReadError Unexpected I/O error
  60. /// \throw std::bad_alloc Internal resource allocation failure
  61. ///
  62. /// \param lexer The lexer object that holds the main context.
  63. /// \param options The options passed to getNextToken().
  64. /// \return A pointer to the next state object or NULL if the transition
  65. /// is completed.
  66. static const State* start(MasterLexer& lexer,
  67. MasterLexer::Options options);
  68. /// \brief Handle the process of one specific state.
  69. ///
  70. /// This method is expected to be called on the object returned by
  71. /// start(), and keep called on the returned object until NULL is
  72. /// returned. The call chain will form the complete state transition.
  73. ///
  74. /// \throw InputSource::ReadError Unexpected I/O error
  75. /// \throw std::bad_alloc Internal resource allocation failure
  76. ///
  77. /// \param lexer The lexer object that holds the main context.
  78. /// \return A pointer to the next state object or NULL if the transition
  79. /// is completed.
  80. virtual const State* handle(MasterLexer& lexer) const = 0;
  81. /// \brief Types of states.
  82. ///
  83. /// Specific states are basically hidden within the implementation,
  84. /// but we'd like to allow tests to examine them, so we provide
  85. /// a way to get an instance of a specific state.
  86. enum ID {
  87. CRLF, ///< Just seen a carriage-return character
  88. String ///< Handling a string token
  89. };
  90. /// \brief Returns a \c State instance of the given state.
  91. ///
  92. /// This is provided only for testing purposes so tests can check
  93. /// the behavior of each state separately. \c MasterLexer shouldn't
  94. /// need this method.
  95. static const State& getInstance(ID state_id);
  96. /// \name Read-only accessors for testing purposes.
  97. ///
  98. /// These allow tests to inspect some selected portion of the internal
  99. /// states of \c MasterLexer. These shouldn't be used except for testing
  100. /// purposes.
  101. ///@{
  102. bool wasLastEOL(const MasterLexer& lexer) const;
  103. const MasterLexer::Token& getToken(const MasterLexer& lexer) const;
  104. size_t getParenCount(const MasterLexer& lexer) const;
  105. ///@}
  106. protected:
  107. /// \brief An accessor to the internal implementation class of
  108. /// \c MasterLexer.
  109. ///
  110. /// This is provided for specific derived classes as they are not direct
  111. /// friends of \c MasterLexer.
  112. ///
  113. /// \param lexer The lexer object that holds the main context.
  114. /// \return A pointer to the implementation class object of the given
  115. /// lexer. This is never NULL.
  116. MasterLexer::MasterLexerImpl* getLexerImpl(MasterLexer& lexer) const {
  117. return (lexer.impl_);
  118. }
  119. };
  120. } // namespace master_lexer_internal
  121. } // namespace dns
  122. } // namespace isc
  123. #endif // MASTER_LEXER_STATE_H
  124. // Local Variables:
  125. // mode: c++
  126. // End: