From 6cda16c11b85198871918ada89352e5401381a6b Mon Sep 17 00:00:00 2001 From: Francis Dupont Date: Fri, 18 Nov 2016 07:15:15 +0100 Subject: [PATCH] [5014] Fixed syntax for tests, ready to add includes --- src/bin/dhcp6/dhcp6_lexer.ll | 15 ++++++++++-- src/bin/dhcp6/dhcp6_parser.yy | 29 +++++++++++++++++++++++ src/bin/dhcp6/parser_context.cc | 41 ++------------------------------- src/bin/dhcp6/parser_context.h | 21 +++++++++++++---- 4 files changed, 61 insertions(+), 45 deletions(-) diff --git a/src/bin/dhcp6/dhcp6_lexer.ll b/src/bin/dhcp6/dhcp6_lexer.ll index a029257e2f..2490b949d1 100644 --- a/src/bin/dhcp6/dhcp6_lexer.ll +++ b/src/bin/dhcp6/dhcp6_lexer.ll @@ -203,6 +203,11 @@ JSONString \"{JSONStringCharacter}*\" \"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. @@ -270,7 +275,7 @@ null { 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; @@ -278,7 +283,7 @@ Parser6Context::scanStringBegin(ParserType 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 @@ -306,6 +311,7 @@ Parser6Context::scanFileBegin(FILE * f, ParserType parser_type) { if (!buffer) { fatal("cannot scan file " + file_); } + parser6__switch_to_buffer(buffer); } void @@ -314,6 +320,11 @@ Parser6Context::scanFileEnd(FILE * f) { 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 { diff --git a/src/bin/dhcp6/dhcp6_parser.yy b/src/bin/dhcp6/dhcp6_parser.yy index 4e3d2e2057..8677c51b9c 100644 --- a/src/bin/dhcp6/dhcp6_parser.yy +++ b/src/bin/dhcp6/dhcp6_parser.yy @@ -119,6 +119,10 @@ using namespace std; 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 @@ -269,6 +273,7 @@ global_param | expired_leases_processing | server_id | dhcp4o6_port +| dhcp_ddns ; preferred_lifetime: PREFERRED_LIFETIME COLON INTEGER { @@ -936,7 +941,31 @@ output_param: OUTPUT COLON STRING { 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); +}; %% diff --git a/src/bin/dhcp6/parser_context.cc b/src/bin/dhcp6/parser_context.cc index 3f89839ff1..1c2993c99b 100644 --- a/src/bin/dhcp6/parser_context.cc +++ b/src/bin/dhcp6/parser_context.cc @@ -28,8 +28,7 @@ isc::data::ConstElementPtr Parser6Context::parseString(const std::string& str, ParserType parser_type) { file_ = ""; - string_ = str; - scanStringBegin(parser_type); + scanStringBegin(str, parser_type); isc::dhcp::Dhcp6Parser parser(*this); // Uncomment this to get detailed parser logs. // trace_parsing_ = true; @@ -49,47 +48,12 @@ Parser6Context::parseString(const std::string& str, ParserType parser_type) 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. @@ -106,7 +70,6 @@ Parser6Context::parseFile(const std::string& filename, ParserType parser_type) { isc_throw(BadValue, "Expected exactly one terminal Element expected, found " << stack_.size()); } -#endif } diff --git a/src/bin/dhcp6/parser_context.h b/src/bin/dhcp6/parser_context.h index 5a3027e6a4..6a7337e6b6 100644 --- a/src/bin/dhcp6/parser_context.h +++ b/src/bin/dhcp6/parser_context.h @@ -51,12 +51,15 @@ public: std::vector 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. @@ -67,6 +70,7 @@ public: 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); @@ -74,9 +78,6 @@ public: /// 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. @@ -95,6 +96,18 @@ public: 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 files_; + + /// @brief Location stack. + std::vector locs_; + + /// @brief State stack. + std::vector states_; + /// @brief Flag determining scanner debugging. bool trace_scanning_; -- 2.47.2