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