Browse Source

[5014_phase2] Added a JSON value subparser

Francis Dupont 8 years ago
parent
commit
a97417d5c5

+ 5 - 3
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_);
         }
     }
 %}

+ 10 - 1
src/bin/dhcp6/dhcp6_parser.yy

@@ -138,6 +138,7 @@ using namespace std;
   SUB_RESERVATION
   SUB_OPTION_DATA
   SUB_HOOKS_LIBRARY
+  SUB_JSON
 ;
 
 %token <std::string> 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)));

+ 6 - 4
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.

+ 8 - 8
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) {