\"dhcp4o6-port\" { return isc::dhcp::Dhcp6Parser::make_DHCP4O6_PORT(loc); }
+\"dhcp-ddns\" { return isc::dhcp::Dhcp6Parser::make_DHCP_DDNS(loc); }
+\"enable-updates\" { return isc::dhcp::Dhcp6Parser::make_ENABLE_UPDATES(loc); }
+\"qualifying-suffix\" { return isc::dhcp::Dhcp6Parser::make_QUALIFYING_SUFFIX(loc); }
+
+
{JSONString} {
// A string has been matched. It contains the actual string and single quotes.
// We need to get those quotes out of the way and just use its content, e.g.
using namespace isc::dhcp;
void
-Parser6Context::scanStringBegin(ParserType parser_type)
+Parser6Context::scanStringBegin(const std::string& str, ParserType parser_type)
{
start_token_flag = true;
start_token_value = parser_type;
loc.initialize(&file_);
yy_flex_debug = trace_scanning_;
YY_BUFFER_STATE buffer;
- buffer = yy_scan_bytes(string_.c_str(), string_.size());
+ buffer = yy_scan_bytes(str.c_str(), str.size());
if (!buffer) {
fatal("cannot scan string");
// fatal() throws an exception so this can't be reached
if (!buffer) {
fatal("cannot scan file " + file_);
}
+ parser6__switch_to_buffer(buffer);
}
void
yy_delete_buffer(YY_CURRENT_BUFFER);
}
+void
+Parser6Context::includeFile(const std::string& filename) {
+ fprintf(stderr, "includeFile(\"%s\")\n", filename.c_str());
+}
+
namespace {
/// To avoid unused function error
class Dummy {
DEBUGLEVEL "debuglevel"
SEVERITY "severity"
+ DHCP_DDNS "dhcp-ddns"
+ ENABLE_UPDATES "enable-updates"
+ QUALIFYING_SUFFIX "qualifying-suffix"
+
// Not real tokens, just a way to signal what the parser is expected to
// parse.
TOPLEVEL_DHCP6
| expired_leases_processing
| server_id
| dhcp4o6_port
+| dhcp_ddns
;
preferred_lifetime: PREFERRED_LIFETIME COLON INTEGER {
ElementPtr sev(new StringElement($3)); ctx.stack_.back()->set("output", sev);
};
+dhcp_ddns: DHCP_DDNS COLON LCURLY_BRACKET {
+ ElementPtr m(new MapElement());
+ ctx.stack_.back()->set("dhcp-ddns", m);
+ ctx.stack_.push_back(m);
+} dhcp_ddns_params RCURLY_BRACKET {
+ ctx.stack_.pop_back();
+};
+
+dhcp_ddns_params: dhcp_ddns_param
+| dhcp_ddns_params COMMA dhcp_ddns_param
+;
+
+dhcp_ddns_param: enable_updates
+| qualifying_suffix
+;
+enable_updates: ENABLE_UPDATES COLON BOOLEAN {
+ ElementPtr b(new BoolElement($3));
+ ctx.stack_.back()->set("enable-updates", b);
+};
+
+qualifying_suffix: QUALIFYING_SUFFIX COLON STRING {
+ ElementPtr qs(new StringElement($3));
+ ctx.stack_.back()->set("qualifying-suffix", qs);
+};
%%
Parser6Context::parseString(const std::string& str, ParserType parser_type)
{
file_ = "<string>";
- string_ = str;
- scanStringBegin(parser_type);
+ scanStringBegin(str, parser_type);
isc::dhcp::Dhcp6Parser parser(*this);
// Uncomment this to get detailed parser logs.
// trace_parsing_ = true;
isc::data::ConstElementPtr
Parser6Context::parseFile(const std::string& filename, ParserType parser_type) {
-
- ifstream f;
- f.open(filename.c_str());
- if (!f.is_open()) {
- isc_throw(BadValue, "Can't open file " << filename);
- }
-
- string_ = "";
- std::string line;
- while (!f.eof()) {
- std::getline(f, line);
- string_ = string_ + line + "\n";
- }
- f.close();
-
- file_ = filename;
-
- scanStringBegin(parser_type);
- isc::dhcp::Dhcp6Parser parser(*this);
- // Uncomment this to get detailed parser logs.
- // trace_parsing_ = true;
- parser.set_debug_level(trace_parsing_);
- int res = parser.parse();
- if (res != 0) {
- // @todo: handle exception here
- }
- scanStringEnd();
- if (stack_.size() == 1) {
- return (stack_[0]);
- } else {
- isc_throw(BadValue, "Expected exactly one terminal Element expected, found "
- << stack_.size());
- }
-
-#if 0
FILE* f = fopen(filename.c_str(), "r");
if (!f) {
isc_throw(BadValue, "Unable to open file " << filename);
}
file_ = filename;
- scanFileBegin(f);
+ scanFileBegin(f, parser_type);
isc::dhcp::Dhcp6Parser parser(*this);
// Uncomment this to get detailed parser logs.
isc_throw(BadValue, "Expected exactly one terminal Element expected, found "
<< stack_.size());
}
-#endif
}
std::vector<isc::data::ElementPtr> stack_;
/// @brief Method called before scanning starts on a string.
- void scanStringBegin(ParserType type);
+ void scanStringBegin(const std::string& str, ParserType type);
/// @brief Method called after the last tokens are scanned from a string.
void scanStringEnd();
+ /// @brief Method called before scanning starts on a file.
void scanFileBegin(FILE * f, ParserType type);
+
+ /// @brief Method called after the last tokens are scanned from a file.
void scanFileEnd(FILE * f);
/// @brief Run the parser on the string specified.
isc::data::ConstElementPtr parseString(const std::string& str,
ParserType parser_type);
+ /// @brief Run the parser on the file specified.
isc::data::ConstElementPtr parseFile(const std::string& filename,
ParserType parser_type);
/// Used later to pass the file name to the location tracker.
std::string file_;
- /// @brief The string being parsed.
- std::string string_;
-
/// @brief Error handler
///
/// @param loc location within the parsed file when experienced a problem.
static void fatal(const std::string& what);
private:
+ /// @brief Divert input to an include file.
+ void includeFile(const std::string& filename);
+
+ /// @brief File name stack.
+ std::vector<std::string> files_;
+
+ /// @brief Location stack.
+ std::vector<isc::dhcp::location> locs_;
+
+ /// @brief State stack.
+ std::vector<struct yy_buffer_state*> states_;
+
/// @brief Flag determining scanner debugging.
bool trace_scanning_;