From: Francis Dupont Date: Tue, 29 Nov 2016 01:23:15 +0000 (+0100) Subject: [5014_phase2] Added a JSON value subparser X-Git-Tag: trac5036_base2~2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=a97417d5c56536dd01094e2e9f08a31ce6b99dc8;p=thirdparty%2Fkea.git [5014_phase2] Added a JSON value subparser --- diff --git a/src/bin/dhcp6/dhcp6_lexer.ll b/src/bin/dhcp6/dhcp6_lexer.ll index c3aec9f5df..d54cc0c225 100644 --- a/src/bin/dhcp6/dhcp6_lexer.ll +++ b/src/bin/dhcp6/dhcp6_lexer.ll @@ -102,6 +102,9 @@ ControlCharacterFill [^"\\]|\\{JSONEscapeSequence} if (start_token_flag) { start_token_flag = false; switch (start_token_value) { + case Parser6Context::PARSER_GENERIC_JSON: + default: + return isc::dhcp::Dhcp6Parser::make_TOPLEVEL_GENERIC_JSON(driver.loc_); case Parser6Context::PARSER_DHCP6: return isc::dhcp::Dhcp6Parser::make_TOPLEVEL_DHCP6(driver.loc_); case Parser6Context::SUBPARSER_INTERFACES6: @@ -118,9 +121,8 @@ ControlCharacterFill [^"\\]|\\{JSONEscapeSequence} return isc::dhcp::Dhcp6Parser::make_SUB_OPTION_DATA(driver.loc_); case Parser6Context::SUBPARSER_HOOKS_LIBRARY: return isc::dhcp::Dhcp6Parser::make_SUB_HOOKS_LIBRARY(driver.loc_); - case Parser6Context::PARSER_GENERIC_JSON: - default: - return isc::dhcp::Dhcp6Parser::make_TOPLEVEL_GENERIC_JSON(driver.loc_); + case Parser6Context::SUBPARSER_JSON: + return isc::dhcp::Dhcp6Parser::make_SUB_JSON(driver.loc_); } } %} diff --git a/src/bin/dhcp6/dhcp6_parser.yy b/src/bin/dhcp6/dhcp6_parser.yy index 08a312a390..b6ac40fae3 100644 --- a/src/bin/dhcp6/dhcp6_parser.yy +++ b/src/bin/dhcp6/dhcp6_parser.yy @@ -138,6 +138,7 @@ using namespace std; SUB_RESERVATION SUB_OPTION_DATA SUB_HOOKS_LIBRARY + SUB_JSON ; %token STRING "constant string" @@ -153,7 +154,7 @@ using namespace std; // The whole grammar starts with a map, because the config file // constists of Dhcp, Logger and DhcpDdns entries in one big { }. -// We made the same for subparsers. +// We made the same for subparsers at the exception of the JSON value. %start start; start: TOPLEVEL_GENERIC_JSON { ctx.ctx_ = ctx.NO_KEYWORD; } map2 @@ -165,6 +166,7 @@ start: TOPLEVEL_GENERIC_JSON { ctx.ctx_ = ctx.NO_KEYWORD; } map2 | SUB_RESERVATION { ctx.ctx_ = ctx.RESERVATIONS; } sub_reservation | SUB_OPTION_DATA { ctx.ctx_ = ctx.OPTION_DATA; } sub_option_data | SUB_HOOKS_LIBRARY { ctx.ctx_ = ctx.HOOKS_LIBRARIES; } sub_hooks_library + | SUB_JSON { ctx.ctx_ = ctx.NO_KEYWORD; } sub_json ; // ---- generic JSON parser --------------------------------- @@ -181,6 +183,11 @@ value: INTEGER { $$ = ElementPtr(new IntElement($1, ctx.loc2pos(@1))); } | list_generic { $$ = ctx.stack_.back(); ctx.stack_.pop_back(); } ; +sub_json: value { + // Push back the JSON value on the stack + ctx.stack_.push_back($1); +}; + map2: LCURLY_BRACKET { // This code is executed when we're about to start parsing // the content of the map @@ -349,6 +356,8 @@ interfaces_config: INTERFACES_CONFIG { ctx.leave(); }; +// subparser: similar to the corresponding rule but without parent +// so the stack is empty at the rule entry. sub_interfaces6: LCURLY_BRACKET { // Parse the interfaces-config map ElementPtr m(new MapElement(ctx.loc2pos(@1))); diff --git a/src/bin/dhcp6/parser_context.h b/src/bin/dhcp6/parser_context.h index be813a1160..33b0798606 100644 --- a/src/bin/dhcp6/parser_context.h +++ b/src/bin/dhcp6/parser_context.h @@ -46,12 +46,14 @@ public: SUBPARSER_PD_POOL, SUBPARSER_HOST_RESERVATION6, // Common DHCP subparsers - // SUBPARSER_OPTION_DEF, + // SUBPARSER_OPTION_DEF, SUBPARSER_OPTION_DATA, SUBPARSER_HOOKS_LIBRARY, - // SUBPARSER_CONTROL_SOCKET, - // SUBPARSER_D2_CLIENT, - // SUBPARSER_LEASE_EXPIRATION + // SUBPARSER_CONTROL_SOCKET, + // SUBPARSER_D2_CLIENT, + // SUBPARSER_LEASE_EXPIRATION, + // JSON value subparser + SUBPARSER_JSON } ParserType; /// @brief Default constructor. diff --git a/src/bin/dhcp6/tests/parser_unittest.cc b/src/bin/dhcp6/tests/parser_unittest.cc index 7dff8a17d4..f24ea2745e 100644 --- a/src/bin/dhcp6/tests/parser_unittest.cc +++ b/src/bin/dhcp6/tests/parser_unittest.cc @@ -69,9 +69,9 @@ TEST(ParserTest, mapInMap) { } TEST(ParserTest, listInList) { - string txt = "{ \"countries\": [ [ \"Britain\", \"Wales\", \"Scotland\" ], " - "[ \"Pomorze\", \"Wielkopolska\", \"Tatry\"] ] }"; - testParser(txt, Parser6Context::PARSER_GENERIC_JSON); + string txt = "[ [ \"Britain\", \"Wales\", \"Scotland\" ], " + "[ \"Pomorze\", \"Wielkopolska\", \"Tatry\"] ]"; + testParser(txt, Parser6Context::SUBPARSER_JSON); } TEST(ParserTest, nestedMaps) { @@ -80,8 +80,8 @@ TEST(ParserTest, nestedMaps) { } TEST(ParserTest, nestedLists) { - string txt = "{ \"unity\": [ \"half\", [ \"quarter\", [ \"eighth\", [ \"sixteenth\" ]]]] }"; - testParser(txt, Parser6Context::PARSER_GENERIC_JSON); + string txt = "[ \"half\", [ \"quarter\", [ \"eighth\", [ \"sixteenth\" ]]]]"; + testParser(txt, Parser6Context::SUBPARSER_JSON); } TEST(ParserTest, listsInMaps) { @@ -91,9 +91,9 @@ TEST(ParserTest, listsInMaps) { } TEST(ParserTest, mapsInLists) { - string txt = "{ \"solar-system\": [ { \"body\": \"earth\", \"gravity\": 1.0 }," - " { \"body\": \"mars\", \"gravity\": 0.376 } ] }"; - testParser(txt, Parser6Context::PARSER_GENERIC_JSON); + string txt = "[ { \"body\": \"earth\", \"gravity\": 1.0 }," + " { \"body\": \"mars\", \"gravity\": 0.376 } ]"; + testParser(txt, Parser6Context::SUBPARSER_JSON); } TEST(ParserTest, types) {