]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#2084] allow trailing comma in JSON configuration
authorAndrei Pavel <andrei@isc.org>
Wed, 3 Nov 2021 11:55:35 +0000 (13:55 +0200)
committerAndrei Pavel <andrei@isc.org>
Fri, 17 Dec 2021 15:18:28 +0000 (17:18 +0200)
src/bin/agent/agent_parser.yy
src/bin/d2/d2_parser.yy
src/bin/dhcp4/dhcp4_parser.yy
src/bin/dhcp6/dhcp6_parser.yy
src/bin/netconf/netconf_parser.yy

index 063523457f9e6c6a8b692e37457b73b9f6db6f78..71e3ef5d316409f0af8df80e4e8d08502c7960fb 100644 (file)
@@ -194,6 +194,7 @@ not_empty_map: STRING COLON value {
                   ctx.unique($3, ctx.loc2pos(@3));
                   ctx.stack_.back()->set($3, $5);
                   }
+             | not_empty_map COMMA
              ;
 
 list_generic: LSQUARE_BRACKET {
@@ -214,6 +215,7 @@ not_empty_list: value {
                   // List ending with , and a value.
                   ctx.stack_.back()->add($3);
                   }
+              | not_empty_list COMMA
               ;
 
 // --- generic JSON parser ends here -------------------------------------------
@@ -244,7 +246,6 @@ agent_syntax_map: LCURLY_BRACKET {
 
 // This represents the single top level entry, e.g. Control-agent.
 global_object: CONTROL_AGENT {
-
     // Let's create a MapElement that will represent it, add it to the
     // top level map (that's already on the stack) and put the new map
     // on the stack as well, so child elements will be able to add
@@ -259,10 +260,13 @@ global_object: CONTROL_AGENT {
     // off the stack.
     ctx.stack_.pop_back();
     ctx.leave();
-};
+}
+             | global_object COMMA
+             ;
 
 global_params: global_param
              | global_params COMMA global_param
+             | global_params COMMA
              ;
 
 // These are the parameters that are allowed in the top-level for
@@ -400,6 +404,7 @@ hooks_libraries_list: %empty
 
 not_empty_hooks_libraries_list: hooks_library
     | not_empty_hooks_libraries_list COMMA hooks_library
+    | not_empty_hooks_libraries_list COMMA
     ;
 
 hooks_library: LCURLY_BRACKET {
@@ -412,6 +417,7 @@ hooks_library: LCURLY_BRACKET {
 
 hooks_params: hooks_param
             | hooks_params COMMA hooks_param
+            | hooks_params COMMA
             | unknown_map_entry
             ;
 
@@ -455,6 +461,7 @@ control_sockets: CONTROL_SOCKETS COLON LCURLY_BRACKET {
 // is required.
 control_sockets_params: control_socket
                       | control_sockets_params COMMA control_socket
+                      | control_sockets_params COMMA
                       ;
 
 // We currently support three types of sockets: DHCPv4, DHCPv6 and D2
@@ -504,6 +511,7 @@ d2_server_socket: D2_SERVER {
 // Socket parameters consist of one or more parameters.
 control_socket_params: control_socket_param
                      | control_socket_params COMMA control_socket_param
+                     | control_socket_params COMMA
                      ;
 
 // We currently support two socket parameters: type and name.
@@ -556,6 +564,7 @@ authentication: AUTHENTICATION {
 
 auth_params: auth_param
            | auth_params COMMA auth_param
+           | auth_params COMMA
            ;
 
 auth_param: auth_type
@@ -603,6 +612,7 @@ clients_list: %empty
 
 not_empty_clients_list: basic_auth
                       | not_empty_clients_list COMMA basic_auth
+                      | not_empty_clients_list COMMA
                       ;
 
 basic_auth: LCURLY_BRACKET {
@@ -615,6 +625,7 @@ basic_auth: LCURLY_BRACKET {
 
 clients_params: clients_param
               | clients_params COMMA clients_param
+              | clients_params COMMA
               ;
 
 clients_param: user
@@ -661,6 +672,7 @@ loggers: LOGGERS {
 // entry or multiple entries separate by commas.
 loggers_entries: logger_entry
                | loggers_entries COMMA logger_entry
+               | loggers_entries COMMA
                ;
 
 // This defines a single entry defined in loggers.
@@ -674,6 +686,7 @@ logger_entry: LCURLY_BRACKET {
 
 logger_params: logger_param
              | logger_params COMMA logger_param
+             | logger_params COMMA
              ;
 
 logger_param: name
@@ -722,6 +735,7 @@ output_options_list: OUTPUT_OPTIONS {
 
 output_options_list_content: output_entry
                            | output_options_list_content COMMA output_entry
+                           | output_options_list_content COMMA
                            ;
 
 output_entry: LCURLY_BRACKET {
@@ -734,6 +748,7 @@ output_entry: LCURLY_BRACKET {
 
 output_params_list: output_params
              | output_params_list COMMA output_params
+             | output_params_list COMMA
              ;
 
 output_params: output
index f6bc82cfaa1dd71d15ac30b303aadf72dbf541db..6d8a23fb56cb2683208b011b668ee7839b8e620e 100644 (file)
@@ -182,6 +182,7 @@ not_empty_map: STRING COLON value {
                   ctx.unique($3, ctx.loc2pos(@3));
                   ctx.stack_.back()->set($3, $5);
                   }
+             | not_empty_map COMMA
              ;
 
 list_generic: LSQUARE_BRACKET {
@@ -203,6 +204,7 @@ not_empty_list: value {
                   // List ending with , and a value.
                   ctx.stack_.back()->add($3);
                   }
+              | not_empty_list COMMA
               ;
 
 // ---- generic JSON parser ends here ----------------------------------
@@ -241,7 +243,9 @@ global_object: DHCPDDNS {
 } COLON LCURLY_BRACKET dhcpddns_params RCURLY_BRACKET {
     ctx.stack_.pop_back();
     ctx.leave();
-};
+}
+             | global_object COMMA
+             ;
 
 sub_dhcpddns: LCURLY_BRACKET {
     // Parse the dhcpddns map
@@ -253,6 +257,7 @@ sub_dhcpddns: LCURLY_BRACKET {
 
 dhcpddns_params: dhcpddns_param
                | dhcpddns_params COMMA dhcpddns_param
+               | dhcpddns_params COMMA
                ;
 
 // These are the top-level parameters allowed for DhcpDdns
@@ -402,6 +407,7 @@ ddns_mgr_params: %empty
 
 not_empty_ddns_mgr_params: ddns_mgr_param
                          | ddns_mgr_params COMMA ddns_mgr_param
+                         | ddns_mgr_params COMMA
                          ;
 
 ddns_mgr_param: ddns_domains
@@ -434,6 +440,7 @@ ddns_domain_list: %empty
 
 not_empty_ddns_domain_list: ddns_domain
                         | not_empty_ddns_domain_list COMMA ddns_domain
+                        | not_empty_ddns_domain_list COMMA
                         ;
 
 ddns_domain: LCURLY_BRACKET {
@@ -453,6 +460,7 @@ sub_ddns_domain: LCURLY_BRACKET {
 
 ddns_domain_params: ddns_domain_param
                   | ddns_domain_params COMMA ddns_domain_param
+                  | ddns_domain_params COMMA
                   ;
 
 ddns_domain_param: ddns_domain_name
@@ -510,6 +518,7 @@ sub_dns_servers: LSQUARE_BRACKET {
 
 dns_server_list: dns_server
                | dns_server_list COMMA dns_server
+               | dns_server_list COMMA
                ;
 
 dns_server: LCURLY_BRACKET {
@@ -529,6 +538,7 @@ sub_dns_server: LCURLY_BRACKET {
 
 dns_server_params: dns_server_param
                | dns_server_params COMMA dns_server_param
+               | dns_server_params COMMA
                ;
 
 dns_server_param: dns_server_hostname
@@ -601,6 +611,7 @@ tsig_keys_list: %empty
 
 not_empty_tsig_keys_list: tsig_key
                         | not_empty_tsig_keys_list COMMA tsig_key
+                        | not_empty_tsig_keys_list COMMA
                         ;
 
 tsig_key: LCURLY_BRACKET {
@@ -622,6 +633,7 @@ sub_tsig_key: LCURLY_BRACKET {
 
 tsig_key_params: tsig_key_param
                | tsig_key_params COMMA tsig_key_param
+               | tsig_key_params COMMA
                ;
 
 tsig_key_param: tsig_key_name
@@ -697,6 +709,7 @@ control_socket: CONTROL_SOCKET {
 
 control_socket_params: control_socket_param
                      | control_socket_params COMMA control_socket_param
+                     | control_socket_params COMMA
                      ;
 
 control_socket_param: control_socket_type
@@ -743,6 +756,7 @@ hooks_libraries_list: %empty
 
 not_empty_hooks_libraries_list: hooks_library
     | not_empty_hooks_libraries_list COMMA hooks_library
+    | not_empty_hooks_libraries_list COMMA
     ;
 
 hooks_library: LCURLY_BRACKET {
@@ -767,6 +781,7 @@ sub_hooks_library: LCURLY_BRACKET {
 
 hooks_params: hooks_param
             | hooks_params COMMA hooks_param
+            | hooks_params COMMA
             | unknown_map_entry
             ;
 
@@ -808,6 +823,7 @@ loggers: LOGGERS {
 // entry or multiple entries separate by commas.
 loggers_entries: logger_entry
                | loggers_entries COMMA logger_entry
+               | loggers_entries COMMA
                ;
 
 // This defines a single entry defined in loggers.
@@ -821,6 +837,7 @@ logger_entry: LCURLY_BRACKET {
 
 logger_params: logger_param
              | logger_params COMMA logger_param
+             | logger_params COMMA
              ;
 
 logger_param: name
@@ -869,6 +886,7 @@ output_options_list: OUTPUT_OPTIONS {
 
 output_options_list_content: output_entry
                            | output_options_list_content COMMA output_entry
+                           | output_options_list_content COMMA
                            ;
 
 output_entry: LCURLY_BRACKET {
@@ -881,6 +899,7 @@ output_entry: LCURLY_BRACKET {
 
 output_params_list: output_params
              | output_params_list COMMA output_params
+             | output_params_list COMMA
              ;
 
 output_params: output
index a9961c67ffb1bb26fd16e65148e0c6f073a0f708..674de16106e783d44e63cb9fd5dc210552b6b833 100644 (file)
@@ -354,6 +354,7 @@ not_empty_map: STRING COLON value {
                   ctx.unique($3, ctx.loc2pos(@3));
                   ctx.stack_.back()->set($3, $5);
                   }
+             | not_empty_map COMMA
              ;
 
 list_generic: LSQUARE_BRACKET {
@@ -375,6 +376,7 @@ not_empty_list: value {
                   // List ending with , and a value.
                   ctx.stack_.back()->add($3);
                   }
+              | not_empty_list COMMA
               ;
 
 // This one is used in syntax parser and is restricted to strings.
@@ -397,6 +399,7 @@ not_empty_list_strings: STRING {
                           ElementPtr s(new StringElement($3, ctx.loc2pos(@3)));
                           ctx.stack_.back()->add(s);
                           }
+                      | not_empty_list_strings COMMA
                       ;
 
 // ---- generic JSON parser ends here ----------------------------------
@@ -441,7 +444,9 @@ global_object: DHCP4 {
     // No global parameter is required
     ctx.stack_.pop_back();
     ctx.leave();
-};
+}
+             | global_object COMMA
+             ;
 
 // subparser: similar to the corresponding rule but without parent
 // so the stack is empty at the rule entry.
@@ -456,6 +461,7 @@ sub_dhcp4: LCURLY_BRACKET {
 
 global_params: global_param
              | global_params COMMA global_param
+             | global_params COMMA
              ;
 
 // These are the parameters that are allowed in the top-level for
@@ -754,6 +760,7 @@ interfaces_config: INTERFACES_CONFIG {
 
 interfaces_config_params: interfaces_config_param
                         | interfaces_config_params COMMA interfaces_config_param
+                        | interfaces_config_params COMMA
                         ;
 
 interfaces_config_param: interfaces_list
@@ -843,7 +850,9 @@ sanity_checks: SANITY_CHECKS {
 };
 
 sanity_checks_params: sanity_checks_param
-                    | sanity_checks_params COMMA sanity_checks_param;
+                    | sanity_checks_params COMMA sanity_checks_param
+                    | sanity_checks_params COMMA
+                    ;
 
 sanity_checks_param: lease_checks;
 
@@ -896,6 +905,7 @@ database_list: %empty
 
 not_empty_database_list: database
                        | not_empty_database_list COMMA database
+                       | not_empty_database_list COMMA
                        ;
 
 database: LCURLY_BRACKET {
@@ -910,6 +920,7 @@ database: LCURLY_BRACKET {
 
 database_map_params: database_map_param
                    | database_map_params COMMA database_map_param
+                   | database_map_params COMMA
                    ;
 
 database_map_param: database_type
@@ -1115,6 +1126,7 @@ host_reservation_identifiers: HOST_RESERVATION_IDENTIFIERS {
 
 host_reservation_identifiers_list: host_reservation_identifier
     | host_reservation_identifiers_list COMMA host_reservation_identifier
+    | host_reservation_identifiers_list COMMA
     ;
 
 host_reservation_identifier: duid_id
@@ -1166,6 +1178,7 @@ dhcp_multi_threading: DHCP_MULTI_THREADING {
 
 multi_threading_params: multi_threading_param
                       | multi_threading_params COMMA multi_threading_param
+                      | multi_threading_params COMMA
                       ;
 
 multi_threading_param: enable_multi_threading
@@ -1211,6 +1224,7 @@ hooks_libraries_list: %empty
 
 not_empty_hooks_libraries_list: hooks_library
     | not_empty_hooks_libraries_list COMMA hooks_library
+    | not_empty_hooks_libraries_list COMMA
     ;
 
 hooks_library: LCURLY_BRACKET {
@@ -1235,6 +1249,7 @@ sub_hooks_library: LCURLY_BRACKET {
 
 hooks_params: hooks_param
             | hooks_params COMMA hooks_param
+            | hooks_params COMMA
             | unknown_map_entry
             ;
 
@@ -1274,6 +1289,7 @@ expired_leases_processing: EXPIRED_LEASES_PROCESSING {
 
 expired_leases_params: expired_leases_param
                      | expired_leases_params COMMA expired_leases_param
+                     | expired_leases_params COMMA
                      ;
 
 expired_leases_param: reclaim_timer_wait_time
@@ -1343,6 +1359,7 @@ subnet4_list_content: %empty
 
 not_empty_subnet4_list: subnet4
                       | not_empty_subnet4_list COMMA subnet4
+                      | not_empty_subnet4_list COMMA
                       ;
 
 // --- Subnet definitions -------------------------------
@@ -1388,6 +1405,7 @@ sub_subnet4: LCURLY_BRACKET {
 // This defines that subnet can have one or more parameters.
 subnet4_params: subnet4_param
               | subnet4_params COMMA subnet4_param
+              | subnet4_params COMMA
               ;
 
 // This defines a list of allowed parameters for each subnet.
@@ -1562,6 +1580,7 @@ shared_networks_content: %empty
 // This allows 1 or more shared network definitions.
 shared_networks_list: shared_network
                     | shared_networks_list COMMA shared_network
+                    | shared_networks_list COMMA
                     ;
 
 shared_network: LCURLY_BRACKET {
@@ -1574,6 +1593,7 @@ shared_network: LCURLY_BRACKET {
 
 shared_network_params: shared_network_param
                      | shared_network_params COMMA shared_network_param
+                     | shared_network_params COMMA
                      ;
 
 shared_network_param: name
@@ -1651,7 +1671,8 @@ option_def_list_content: %empty
 
 not_empty_option_def_list: option_def_entry
                          | not_empty_option_def_list COMMA option_def_entry
-                          ;
+                         | not_empty_option_def_list COMMA
+                         ;
 
 // This defines the content of a single entry { ... } within
 // option-def list.
@@ -1690,6 +1711,7 @@ option_def_params: %empty
 
 not_empty_option_def_params: option_def_param
                            | not_empty_option_def_params COMMA option_def_param
+                           | not_empty_option_def_params COMMA
                            ;
 
 option_def_param: option_def_name
@@ -1783,6 +1805,7 @@ option_data_list_content: %empty
 // be a single value or multiple entries separated by comma.
 not_empty_option_data_list: option_data_entry
                           | not_empty_option_data_list COMMA option_data_entry
+                          | not_empty_option_data_list COMMA
                           ;
 
 // This defines th content of a single entry { ... } within
@@ -1819,6 +1842,7 @@ option_data_params: %empty
 // a list of parameters separated by comma.
 not_empty_option_data_params: option_data_param
     | not_empty_option_data_params COMMA option_data_param
+    | not_empty_option_data_params COMMA
     ;
 
 // Each single option-data parameter can be one of the following
@@ -1883,6 +1907,7 @@ pools_list_content: %empty
 
 not_empty_pools_list: pool_list_entry
                     | not_empty_pools_list COMMA pool_list_entry
+                    | not_empty_pools_list COMMA
                     ;
 
 pool_list_entry: LCURLY_BRACKET {
@@ -1907,6 +1932,7 @@ sub_pool4: LCURLY_BRACKET {
 
 pool_params: pool_param
            | pool_params COMMA pool_param
+           | pool_params COMMA
            ;
 
 pool_param: pool_entry
@@ -1999,6 +2025,7 @@ reservations_list: %empty
 
 not_empty_reservations_list: reservation
                            | not_empty_reservations_list COMMA reservation
+                           | not_empty_reservations_list COMMA
                            ;
 
 reservation: LCURLY_BRACKET {
@@ -2025,6 +2052,7 @@ reservation_params: %empty
 
 not_empty_reservation_params: reservation_param
     | not_empty_reservation_params COMMA reservation_param
+    | not_empty_reservation_params COMMA
     ;
 
 /// @todo probably need to add mac-address as well here
@@ -2191,6 +2219,7 @@ client_classes: CLIENT_CLASSES {
 
 client_classes_list: client_class_entry
                    | client_classes_list COMMA client_class_entry
+                   | client_classes_list COMMA
                    ;
 
 client_class_entry: LCURLY_BRACKET {
@@ -2209,6 +2238,7 @@ client_class_params: %empty
 
 not_empty_client_class_params: client_class_param
     | not_empty_client_class_params COMMA client_class_param
+    | not_empty_client_class_params COMMA
     ;
 
 client_class_param: client_class_name
@@ -2267,6 +2297,7 @@ control_socket: CONTROL_SOCKET {
 
 control_socket_params: control_socket_param
                      | control_socket_params COMMA control_socket_param
+                     | control_socket_params COMMA
                      ;
 
 control_socket_param: control_socket_type
@@ -2312,6 +2343,7 @@ dhcp_queue_control: DHCP_QUEUE_CONTROL {
 
 queue_control_params: queue_control_param
                     | queue_control_params COMMA queue_control_param
+                    | queue_control_params COMMA
                     ;
 
 queue_control_param: enable_queue
@@ -2378,6 +2410,7 @@ sub_dhcp_ddns: LCURLY_BRACKET {
 
 dhcp_ddns_params: dhcp_ddns_param
                 | dhcp_ddns_params COMMA dhcp_ddns_param
+                | dhcp_ddns_params COMMA
                 ;
 
 dhcp_ddns_param: enable_updates
@@ -2554,6 +2587,7 @@ sub_config_control: LCURLY_BRACKET {
 // This defines that subnet can have one or more parameters.
 config_control_params: config_control_param
                      | config_control_params COMMA config_control_param
+                     | config_control_params COMMA
                      ;
 
 // This defines a list of allowed parameters for each subnet.
@@ -2595,6 +2629,7 @@ loggers: LOGGERS {
 // entry or multiple entries separate by commas.
 loggers_entries: logger_entry
                | loggers_entries COMMA logger_entry
+               | loggers_entries COMMA
                ;
 
 // This defines a single entry defined in loggers.
@@ -2608,6 +2643,7 @@ logger_entry: LCURLY_BRACKET {
 
 logger_params: logger_param
              | logger_params COMMA logger_param
+             | logger_params COMMA
              ;
 
 logger_param: name
@@ -2647,6 +2683,7 @@ output_options_list: OUTPUT_OPTIONS {
 
 output_options_list_content: output_entry
                            | output_options_list_content COMMA output_entry
+                           | output_options_list_content COMMA
                            ;
 
 output_entry: LCURLY_BRACKET {
@@ -2659,6 +2696,7 @@ output_entry: LCURLY_BRACKET {
 
 output_params_list: output_params
                   | output_params_list COMMA output_params
+                  | output_params_list COMMA
                   ;
 
 output_params: output
@@ -2717,6 +2755,7 @@ compatibility: COMPATIBILITY {
 
 compatibility_params: compatibility_param
                     | compatibility_params COMMA compatibility_param
+                    | compatibility_params COMMA
                     ;
 
 compatibility_param: lenient_option_parsing
index 3871ded5ad5c3b637385471a60ae3be696265e19..86e3780b83f03de2c29b4ca9f0d5021949d2cda7 100644 (file)
@@ -362,6 +362,7 @@ not_empty_map: STRING COLON value {
                   ctx.unique($3, ctx.loc2pos(@3));
                   ctx.stack_.back()->set($3, $5);
                   }
+             | not_empty_map COMMA
              ;
 
 list_generic: LSQUARE_BRACKET {
@@ -383,6 +384,7 @@ not_empty_list: value {
                   // List ending with , and a value.
                   ctx.stack_.back()->add($3);
                   }
+              | not_empty_list COMMA
               ;
 
 // This one is used in syntax parser and is restricted to strings.
@@ -405,6 +407,7 @@ not_empty_list_strings: STRING {
                           ElementPtr s(new StringElement($3, ctx.loc2pos(@3)));
                           ctx.stack_.back()->add(s);
                           }
+                      | not_empty_list_strings COMMA
                       ;
 
 // ---- generic JSON parser ends here ----------------------------------
@@ -449,7 +452,9 @@ global_object: DHCP6 {
     // No global parameter is required
     ctx.stack_.pop_back();
     ctx.leave();
-};
+}
+             | global_object COMMA
+             ;
 
 // subparser: similar to the corresponding rule but without parent
 // so the stack is empty at the rule entry.
@@ -464,6 +469,7 @@ sub_dhcp6: LCURLY_BRACKET {
 
 global_params: global_param
              | global_params COMMA global_param
+             | global_params COMMA
              ;
 
 // These are the parameters that are allowed in the top-level for
@@ -781,6 +787,7 @@ sub_interfaces6: LCURLY_BRACKET {
 
 interfaces_config_params: interfaces_config_param
                         | interfaces_config_params COMMA interfaces_config_param
+                        | interfaces_config_params COMMA
                         ;
 
 interfaces_config_param: interfaces_list
@@ -850,6 +857,7 @@ database_list: %empty
 
 not_empty_database_list: database
                        | not_empty_database_list COMMA database
+                       | not_empty_database_list COMMA
                        ;
 
 database: LCURLY_BRACKET {
@@ -864,6 +872,7 @@ database: LCURLY_BRACKET {
 
 database_map_params: database_map_param
                    | database_map_params COMMA database_map_param
+                   | database_map_params COMMA
                    ;
 
 database_map_param: database_type
@@ -1067,7 +1076,9 @@ sanity_checks: SANITY_CHECKS {
 };
 
 sanity_checks_params: sanity_checks_param
-                    | sanity_checks_params COMMA sanity_checks_param;
+                    | sanity_checks_params COMMA sanity_checks_param
+                    | sanity_checks_params COMMA
+                    ;
 
 sanity_checks_param: lease_checks;
 
@@ -1103,7 +1114,8 @@ mac_sources: MAC_SOURCES {
 
 mac_sources_list: mac_sources_value
                 | mac_sources_list COMMA mac_sources_value
-;
+                | mac_sources_list COMMA
+                ;
 
 mac_sources_value: duid_id
                  | string_id
@@ -1132,6 +1144,7 @@ host_reservation_identifiers: HOST_RESERVATION_IDENTIFIERS {
 
 host_reservation_identifiers_list: host_reservation_identifier
     | host_reservation_identifiers_list COMMA host_reservation_identifier
+    | host_reservation_identifiers_list COMMA
     ;
 
 host_reservation_identifier: duid_id
@@ -1179,6 +1192,7 @@ dhcp_multi_threading: DHCP_MULTI_THREADING {
 
 multi_threading_params: multi_threading_param
                       | multi_threading_params COMMA multi_threading_param
+                      | multi_threading_params COMMA
                       ;
 
 multi_threading_param: enable_multi_threading
@@ -1224,6 +1238,7 @@ hooks_libraries_list: %empty
 
 not_empty_hooks_libraries_list: hooks_library
     | not_empty_hooks_libraries_list COMMA hooks_library
+    | not_empty_hooks_libraries_list COMMA
     ;
 
 hooks_library: LCURLY_BRACKET {
@@ -1248,6 +1263,7 @@ sub_hooks_library: LCURLY_BRACKET {
 
 hooks_params: hooks_param
             | hooks_params COMMA hooks_param
+            | hooks_params COMMA
             | unknown_map_entry
             ;
 
@@ -1287,6 +1303,7 @@ expired_leases_processing: EXPIRED_LEASES_PROCESSING {
 
 expired_leases_params: expired_leases_param
                      | expired_leases_params COMMA expired_leases_param
+                     | expired_leases_params COMMA
                      ;
 
 expired_leases_param: reclaim_timer_wait_time
@@ -1356,6 +1373,7 @@ subnet6_list_content: %empty
 
 not_empty_subnet6_list: subnet6
                       | not_empty_subnet6_list COMMA subnet6
+                      | not_empty_subnet6_list COMMA
                       ;
 
 // --- Subnet definitions -------------------------------
@@ -1401,6 +1419,7 @@ sub_subnet6: LCURLY_BRACKET {
 // This defines that subnet can have one or more parameters.
 subnet6_params: subnet6_param
               | subnet6_params COMMA subnet6_param
+              | subnet6_params COMMA
               ;
 
 // This defines a list of allowed parameters for each subnet.
@@ -1561,6 +1580,7 @@ shared_networks_content: %empty
 // This allows 1 or more shared network definitions.
 shared_networks_list: shared_network
                     | shared_networks_list COMMA shared_network
+                    | shared_networks_list COMMA
                     ;
 
 shared_network: LCURLY_BRACKET {
@@ -1573,6 +1593,7 @@ shared_network: LCURLY_BRACKET {
 
 shared_network_params: shared_network_param
                      | shared_network_params COMMA shared_network_param
+                     | shared_network_params COMMA
                      ;
 
 shared_network_param: name
@@ -1650,7 +1671,8 @@ option_def_list_content: %empty
 
 not_empty_option_def_list: option_def_entry
                          | not_empty_option_def_list COMMA option_def_entry
-                          ;
+                         | not_empty_option_def_list COMMA
+                         ;
 
 // This defines the content of a single entry { ... } within
 // option-def list.
@@ -1689,6 +1711,7 @@ option_def_params: %empty
 
 not_empty_option_def_params: option_def_param
                            | not_empty_option_def_params COMMA option_def_param
+                           | not_empty_option_def_params COMMA
                            ;
 
 option_def_param: option_def_name
@@ -1782,6 +1805,7 @@ option_data_list_content: %empty
 // be a single value or multiple entries separated by comma.
 not_empty_option_data_list: option_data_entry
                           | not_empty_option_data_list COMMA option_data_entry
+                          | not_empty_option_data_list COMMA
                           ;
 
 // This defines th content of a single entry { ... } within
@@ -1818,6 +1842,7 @@ option_data_params: %empty
 // a list of parameters separated by comma.
 not_empty_option_data_params: option_data_param
     | not_empty_option_data_params COMMA option_data_param
+    | not_empty_option_data_params COMMA
     ;
 
 // Each single option-data parameter can be one of the following
@@ -1882,6 +1907,7 @@ pools_list_content: %empty
 
 not_empty_pools_list: pool_list_entry
                     | not_empty_pools_list COMMA pool_list_entry
+                    | not_empty_pools_list COMMA
                     ;
 
 pool_list_entry: LCURLY_BRACKET {
@@ -1906,6 +1932,7 @@ sub_pool6: LCURLY_BRACKET {
 
 pool_params: pool_param
            | pool_params COMMA pool_param
+           | pool_params COMMA
            ;
 
 pool_param: pool_entry
@@ -2000,6 +2027,7 @@ pd_pools_list_content: %empty
 
 not_empty_pd_pools_list: pd_pool_entry
                        | not_empty_pd_pools_list COMMA pd_pool_entry
+                       | not_empty_pd_pools_list COMMA
                        ;
 
 pd_pool_entry: LCURLY_BRACKET {
@@ -2028,6 +2056,7 @@ sub_pd_pool: LCURLY_BRACKET {
 
 pd_pool_params: pd_pool_param
               | pd_pool_params COMMA pd_pool_param
+              | pd_pool_params COMMA
               ;
 
 pd_pool_param: pd_prefix
@@ -2099,6 +2128,7 @@ reservations_list: %empty
 
 not_empty_reservations_list: reservation
                            | not_empty_reservations_list COMMA reservation
+                           | not_empty_reservations_list COMMA
                            ;
 
 reservation: LCURLY_BRACKET {
@@ -2125,6 +2155,7 @@ reservation_params: %empty
 
 not_empty_reservation_params: reservation_param
     | not_empty_reservation_params COMMA reservation_param
+    | not_empty_reservation_params COMMA
     ;
 
 /// @todo probably need to add mac-address as well here
@@ -2253,6 +2284,7 @@ client_classes: CLIENT_CLASSES {
 
 client_classes_list: client_class_entry
                    | client_classes_list COMMA client_class_entry
+                   | client_classes_list COMMA
                    ;
 
 client_class_entry: LCURLY_BRACKET {
@@ -2271,6 +2303,7 @@ client_class_params: %empty
 
 not_empty_client_class_params: client_class_param
     | not_empty_client_class_params COMMA client_class_param
+    | not_empty_client_class_params COMMA
     ;
 
 client_class_param: client_class_name
@@ -2323,6 +2356,7 @@ server_id: SERVER_ID {
 
 server_id_params: server_id_param
                 | server_id_params COMMA server_id_param
+                | server_id_params COMMA
                 ;
 
 server_id_param: server_id_type
@@ -2399,6 +2433,7 @@ control_socket: CONTROL_SOCKET {
 
 control_socket_params: control_socket_param
                      | control_socket_params COMMA control_socket_param
+                     | control_socket_params COMMA
                      ;
 
 control_socket_param: socket_type
@@ -2444,6 +2479,7 @@ dhcp_queue_control: DHCP_QUEUE_CONTROL {
 
 queue_control_params: queue_control_param
                     | queue_control_params COMMA queue_control_param
+                    | queue_control_params COMMA
                     ;
 
 queue_control_param: enable_queue
@@ -2510,6 +2546,7 @@ sub_dhcp_ddns: LCURLY_BRACKET {
 
 dhcp_ddns_params: dhcp_ddns_param
                 | dhcp_ddns_params COMMA dhcp_ddns_param
+                | dhcp_ddns_params COMMA
                 ;
 
 dhcp_ddns_param: enable_updates
@@ -2686,6 +2723,7 @@ sub_config_control: LCURLY_BRACKET {
 // This defines that subnet can have one or more parameters.
 config_control_params: config_control_param
                      | config_control_params COMMA config_control_param
+                     | config_control_params COMMA
                      ;
 
 // This defines a list of allowed parameters for each subnet.
@@ -2727,6 +2765,7 @@ loggers: LOGGERS {
 // entry or multiple entries separate by commas.
 loggers_entries: logger_entry
                | loggers_entries COMMA logger_entry
+               | loggers_entries COMMA
                ;
 
 // This defines a single entry defined in loggers.
@@ -2740,6 +2779,7 @@ logger_entry: LCURLY_BRACKET {
 
 logger_params: logger_param
              | logger_params COMMA logger_param
+             | logger_params COMMA
              ;
 
 logger_param: name
@@ -2779,6 +2819,7 @@ output_options_list: OUTPUT_OPTIONS {
 
 output_options_list_content: output_entry
                            | output_options_list_content COMMA output_entry
+                           | output_options_list_content COMMA
                            ;
 
 output_entry: LCURLY_BRACKET {
@@ -2791,6 +2832,7 @@ output_entry: LCURLY_BRACKET {
 
 output_params_list: output_params
                   | output_params_list COMMA output_params
+                  | output_params_list COMMA
                   ;
 
 output_params: output
@@ -2849,6 +2891,7 @@ compatibility: COMPATIBILITY {
 
 compatibility_params: compatibility_param
                     | compatibility_params COMMA compatibility_param
+                    | compatibility_params COMMA
                     ;
 
 compatibility_param: lenient_option_parsing
index 53a2bbdbe16dad178907661ef1b6f2b6760c4024..be7b72deed686193c39a4ce36c0ef233d64f9710 100644 (file)
@@ -188,6 +188,7 @@ not_empty_map: STRING COLON value {
                   ctx.unique($3, ctx.loc2pos(@3));
                   ctx.stack_.back()->set($3, $5);
                   }
+             | not_empty_map COMMA
              ;
 
 list_generic: LSQUARE_BRACKET {
@@ -208,6 +209,7 @@ not_empty_list: value {
                   // List ending with , and a value.
                   ctx.stack_.back()->add($3);
                   }
+              | not_empty_list COMMA
               ;
 
 // --- generic JSON parser ends here -------------------------------------------
@@ -238,7 +240,6 @@ netconf_syntax_map: LCURLY_BRACKET {
 
 // This represents the single top level entry, e.g. Netconf.
 global_object: NETCONF {
-
     // Let's create a MapElement that will represent it, add it to the
     // top level map (that's already on the stack) and put the new map
     // on the stack as well, so child elements will be able to add
@@ -255,7 +256,9 @@ global_object: NETCONF {
     // off the stack.
     ctx.stack_.pop_back();
     ctx.leave();
-};
+}
+             | global_object COMMA
+             ;
 
 global_params: %empty
              | not_empty_global_params
@@ -263,6 +266,7 @@ global_params: %empty
 
 not_empty_global_params: global_param
                        | not_empty_global_params COMMA global_param
+                       | not_empty_global_params COMMA
                        ;
 
 // These are the parameters that are allowed in the top-level for
@@ -366,6 +370,7 @@ hooks_libraries_list: %empty
 
 not_empty_hooks_libraries_list: hooks_library
     | not_empty_hooks_libraries_list COMMA hooks_library
+    | not_empty_hooks_libraries_list COMMA
     ;
 
 hooks_library: LCURLY_BRACKET {
@@ -378,6 +383,7 @@ hooks_library: LCURLY_BRACKET {
 
 hooks_params: hooks_param
             | hooks_params COMMA hooks_param
+            | hooks_params COMMA
             | unknown_map_entry
             ;
 
@@ -422,6 +428,7 @@ servers_entries: %empty
 
 not_empty_servers_entries: server_entry
                          | not_empty_servers_entries COMMA server_entry
+                         | not_empty_servers_entries COMMA
                          ;
 
 
@@ -485,6 +492,7 @@ ca_server: CA_SERVER {
 // Server parameters consist of one or more parameters.
 managed_server_params: managed_server_param
                      | managed_server_params COMMA managed_server_param
+                     | managed_server_params COMMA
                      ;
 
 // We currently support two server parameters: model and control-socket.
@@ -523,6 +531,7 @@ control_socket: CONTROL_SOCKET {
 // control-socket parameters
 control_socket_params: control_socket_param
                      | control_socket_params COMMA control_socket_param
+                     | control_socket_params COMMA
                      ;
 
 control_socket_param: socket_type
@@ -585,6 +594,7 @@ loggers: LOGGERS {
 // entry or multiple entries separate by commas.
 loggers_entries: logger_entry
                | loggers_entries COMMA logger_entry
+               | loggers_entries COMMA
                ;
 
 // This defines a single entry defined in loggers.
@@ -598,6 +608,7 @@ logger_entry: LCURLY_BRACKET {
 
 logger_params: logger_param
              | logger_params COMMA logger_param
+             | logger_params COMMA
              ;
 
 logger_param: name
@@ -646,6 +657,7 @@ output_options_list: OUTPUT_OPTIONS {
 
 output_options_list_content: output_entry
                            | output_options_list_content COMMA output_entry
+                           | output_options_list_content COMMA
                            ;
 
 output_entry: LCURLY_BRACKET {
@@ -658,6 +670,7 @@ output_entry: LCURLY_BRACKET {
 
 output_params_list: output_params
              | output_params_list COMMA output_params
+             | output_params_list COMMA
              ;
 
 output_params: output