BIND 10 #2371: define dns::MasterLexer class

BIND 10 Development do-not-reply at isc.org
Fri Oct 19 06:25:31 UTC 2012


#2371: define dns::MasterLexer class
-------------------------------------+-------------------------------------
            Reporter:  jinmei        |                        Owner:
                Type:  task          |  UnAssigned
            Priority:  medium        |                       Status:  new
           Component:  libdns++      |                    Milestone:  New
           Sensitive:  0             |  Tasks
         Sub-Project:  DNS           |                     Keywords:
Estimated Difficulty:  0             |              Defect Severity:  N/A
         Total Hours:  0             |  Feature Depending on Ticket:
                                     |  loadzone-ng
                                     |          Add Hours to Ticket:  0
                                     |                    Internal?:  0
-------------------------------------+-------------------------------------
 subtask of #2368.  slightly depend on #2369 (but could be done
 in parallel).

 This is the main class for our lexer of master zone files.  It's a
 port of BIND 9's lib/isc/lex.c:isc_lex, but is much simplified so
 that it only handles DNS master files (isc_lex is more generic, and
 supports, e.g., C-style comments).

 The main method is getNextToken(), which is a port of
 isc_lex_gettoken().  But the BIND 9 version is a big, monolithic,
 complicated function containing a very long loop and switch-case with
 goto.  I'd like to make it more readable with some object-oriented
 flavor.  Specifically, I propose using the state design pattern to
 implement the internal state transition.  This part will go to
 separate sub tasks.

 At the moment, a rough sketch of the main class is as follows:
 {{{#!cpp
 class MasterLexer {
 private:
     friend class master_lexer_internal::State; // for the state DP
 public:
     enum Options {
         INITIAL_WS, //begin-of-line spaces are okay
         QSTRING, // quoted string okay (otherwise '"' would be part of
 string
         // may be some more
     };

     // This should go to a separate task
     const MasterToken& getNextToken(Options options);

     // Similar to getNextToken(), but only accept specified type of token
     // or EOL/EOF (if eol_ok is true).  no option.
     const MasterToken& getNextToken(TokenType expect_type, bool eol_ok);

     // source->ungetAll(), reset paren_count_
     void ungetToken();

     // These simple ones will be in a single task
     std::string getSourceName() const { return (sources_.top()->name_); }
     size_t getSourceLine() const { return
 (sources_.top()->getCurrentLine()); }
     open(const char* filename); // create new source and push it to
 sources_
     open(std::istream&);
     close();                    // close current "source"

 private:
     bool last_was_eol_;         // true if we just passed a new line
     bool no_comments_;          // true if we are now in a comment
     bool escaped_;              // true if we just ate '\'
     size_t paren_count_;        // nest level of unclosed '('
     size_t saved_paren_count_;  // used in ungetToken
     master_lexer_internal::State* saved_state_;
     stack<master_lexer_internal::InputSource> sources_;
     MasterToken token_; // used as a return value of getNextToken

     // helper method, used by states, detect if it's the beginning of
     // a comment.
     bool isCommentStart(int c, State* current_state);
 }
 }}}

 In this task, we just define the class and method excluding
 getNextToken() and ungetToken().  No need to have unnecessary member
 variables or private methods yet.

-- 
Ticket URL: <http://bind10.isc.org/ticket/2371>
BIND 10 Development <http://bind10.isc.org>
BIND 10 Development


More information about the bind10-tickets mailing list