// %start dhcp6_map - this will parse everything with Dhcp6 syntax checking
%start syntax_map;
+// ---- generic JSON parser ---------------------------------
+
// Values rule
value : INTEGER { $$ = ElementPtr(new IntElement($1)); }
| FLOAT { $$ = ElementPtr(new DoubleElement($1)); }
// Assignments rule
map_content: { /* do nothing, it's an empty map */ }
| STRING COLON value {
- // map containing a single entry
- ctx.stack_.back()->set($1, $3);
+ // map containing a single entry
+ ctx.stack_.back()->set($1, $3);
}
| map_content COMMA STRING COLON value {
- // map consisting of a shorter map followed by comma and string:value
- ctx.stack_.back()->set($3, $5);
+ // map consisting of a shorter map followed by comma and string:value
+ ctx.stack_.back()->set($3, $5);
}
;
list: LSQUARE_BRACKET {
// List parsing about to start
- ElementPtr l(new ListElement());
- ctx.stack_.push_back(l);
} list_content RSQUARE_BRACKET {
// list parsing complete. Put any sanity checking here
};
list_content: { /* do nothing, it's an empty list */ }
| value {
- // List consisting of a single element.
- ctx.stack_.back()->add($1);
+ // List consisting of a single element.
+ ctx.stack_.back()->add($1);
}
| list_content COMMA value {
- // List ending with , and a value.
- ctx.stack_.back()->add($3);
+ // List ending with , and a value.
+ ctx.stack_.back()->add($3);
}
;
+// ---- generic JSON parser ends here ----------------------------------
+
+// ---- syntax checking parser starts here -----------------------------
+
+// This defines the top-level { } that holds Dhcp6, Dhcp4, DhcpDdns or Logging
+// objects.
+syntax_map: LCURLY_BRACKET {
+ // This code is executed when we're about to start parsing
+ // the content of the map
+ ElementPtr m(new MapElement());
+ ctx.stack_.push_back(m);
+} global_objects RCURLY_BRACKET {
+ // map parsing completed. If we ever want to do any wrap up
+ // (maybe some sanity checking), this would be the best place
+ // for it.
+};
+
+// This represents a single top level entry, e.g. Dhcp6 or DhcpDdns.
+global_object: dhcp6_object
+| logging_object;
+
+// This represents top-level entries: Dhcp6, Dhcp4, DhcpDdns, Logging
+global_objects
+: global_object
+| global_objects COMMA global_object
+;
+
+dhcp6_object: DHCP6 COLON LCURLY_BRACKET {
+ // This code is executed when we're about to start parsing
+ // the content of the map
+ ElementPtr m(new MapElement());
+ ctx.stack_.back()->set("Dhcp6", m);
+ ctx.stack_.push_back(m);
+} global_params RCURLY_BRACKET {
+ // map parsing completed. If we ever want to do any wrap up
+ // (maybe some sanity checking), this would be the best place
+ // for it.
+ ctx.stack_.pop_back();
+};
+
global_params: global_param
| global_params COMMA global_param;
// These are the parameters that are allowed in the top-level for
-// Dhcp6.
+// Dhcp6.
global_param
: preferred_lifetime
| valid_lifetime
;
preferred_lifetime: PREFERRED_LIFETIME COLON INTEGER {
-
+ ElementPtr prf(new IntElement($3));
+ ctx.stack_.back()->set("preferred-lifetime", prf);
};
valid_lifetime: VALID_LIFETIME COLON INTEGER {
-
+ ElementPtr prf(new IntElement($3));
+ ctx.stack_.back()->set("valid-lifetime", prf);
};
renew_timer: RENEW_TIMER COLON INTEGER {
-
+ ElementPtr prf(new IntElement($3));
+ ctx.stack_.back()->set("renew-timer", prf);
};
-interfaces_config: INTERFACES_CONFIG COLON LCURLY_BRACKET interface_config_map RCURLY_BRACKET;
+rebind_timer: REBIND_TIMER COLON INTEGER {
+ ElementPtr prf(new IntElement($3));
+ ctx.stack_.back()->set("rebind-timer", prf);
+};
-interface_config_map: INTERFACES COLON list;
+interfaces_config: INTERFACES_CONFIG COLON {
+ ElementPtr i(new MapElement());
+ ctx.stack_.back()->set("interfaces-config", i);
+ ctx.stack_.push_back(i);
+ } LCURLY_BRACKET interface_config_map RCURLY_BRACKET {
+ ctx.stack_.pop_back();
+};
-lease_database: LEASE_DATABASE COLON LCURLY_BRACKET lease_database_map RCURLY_BRACKET;
+interface_config_map: INTERFACES {
+ ElementPtr l(new ListElement());
+ ctx.stack_.back()->set("interfaces", l);
+ ctx.stack_.push_back(l);
+ } COLON list {
+ ctx.stack_.pop_back();
+ }
+
+lease_database: LEASE_DATABASE {
+ ElementPtr i(new MapElement());
+ ctx.stack_.back()->set("lease-database", i);
+ ctx.stack_.push_back(i);
+}
+COLON LCURLY_BRACKET lease_database_map_params {
+ ctx.stack_.pop_back();
+} RCURLY_BRACKET;
-lease_database_map: TYPE COLON STRING;
+lease_database_map_params: lease_database_map_param
+| lease_database_map_params COMMA lease_database_map_param;
-rebind_timer: REBIND_TIMER COLON INTEGER {
+lease_database_map_param: lease_database_type;
+lease_database_type: TYPE COLON STRING {
+ ElementPtr prf(new StringElement($3));
+ ctx.stack_.back()->set("type", prf);
};
// This defines subnet6 as a list of maps.
// "subnet6": [ ... ]
subnet6_list: SUBNET6 COLON LSQUARE_BRACKET {
ElementPtr l(new ListElement());
+ ctx.stack_.back()->set("subnet6", l);
ctx.stack_.push_back(l);
} subnet6_list_content RSQUARE_BRACKET {
-
+ ctx.stack_.pop_back();
};
// This defines the ... in "subnet6": [ ... ]
// This defines a single subnet, i.e. a single map with
// subnet6 array.
-subnet6: LCURLY_BRACKET subnet6_params RCURLY_BRACKET;
+subnet6: LCURLY_BRACKET {
+ ElementPtr m(new MapElement());
+ ctx.stack_.back()->add(m);
+ ctx.stack_.push_back(m);
+} subnet6_params {
+ ctx.stack_.pop_back();
+} RCURLY_BRACKET;
-subnet6_params: subnet6_param
+subnet6_params: subnet6_param
| subnet6_params COMMA subnet6_param;
subnet6_param: { /* empty list */ }
| option_data_list
| pools_list
-| SUBNET COLON STRING { }
-| INTERFACE COLON STRING { }
+| SUBNET COLON STRING {
+ ElementPtr name(new StringElement($3)); ctx.stack_.back()->set("subnet", name);
+
+ }
+| INTERFACE COLON STRING {
+ ElementPtr name(new StringElement($3)); ctx.stack_.back()->set("interface", name);
+ }
;
// ---- option-data --------------------------
// This defines the "option-data": [ ... ] entry that may appear
// in several places, but most notably in subnet6 entries.
-option_data_list: OPTION_DATA COLON LSQUARE_BRACKET option_data_list_content RSQUARE_BRACKET;
+option_data_list: OPTION_DATA {
+ ElementPtr l(new ListElement());
+ ctx.stack_.back()->set("option-data", l);
+ ctx.stack_.push_back(l);
+} COLON LSQUARE_BRACKET option_data_list_content RSQUARE_BRACKET {
+ ctx.stack_.pop_back();
+};
// This defines the content of option-data. It may be empty,
// have one entry or multiple entries separated by comma.
// This defines th content of a single entry { ... } within
// option-data list.
-option_data_entry: LCURLY_BRACKET option_data_params RCURLY_BRACKET;
+option_data_entry: LCURLY_BRACKET {
+ ElementPtr m(new MapElement());
+ ctx.stack_.back()->add(m);
+ ctx.stack_.push_back(m);
+} option_data_params RCURLY_BRACKET {
+ ctx.stack_.pop_back();
+};
// This defines parameters specified inside the map that itself
// is an entry in option-data list.
| option_data_param
| option_data_params COMMA option_data_param;
-option_data_param: NAME COLON STRING {}
-| DATA COLON STRING
-| CODE COLON INTEGER;
+option_data_param:
+NAME COLON STRING {
+ ElementPtr name(new StringElement($3)); ctx.stack_.back()->set("name", name);
+}
+| DATA COLON STRING {
+ ElementPtr data(new StringElement($3)); ctx.stack_.back()->set("data", data);
+}
+| CODE COLON INTEGER {
+ ElementPtr code(new IntElement($3)); ctx.stack_.back()->set("code", code);
+};
// ---- pools ------------------------------------
// This defines the "pools": [ ... ] entry that may appear in subnet6.
-pools_list: POOLS COLON LSQUARE_BRACKET pools_list_content RSQUARE_BRACKET;
+pools_list: POOLS COLON {
+ ElementPtr l(new ListElement());
+ ctx.stack_.back()->set("pools", l);
+ ctx.stack_.push_back(l);
+} LSQUARE_BRACKET pools_list_content RSQUARE_BRACKET {
+ ctx.stack_.pop_back();
+};
// Pools may be empty, contain a single pool entry or multiple entries
// separate by commas.
| pool_entry
| pools_list_content COMMA pool_entry;
-pool_entry: LCURLY_BRACKET pool_params RCURLY_BRACKET;
+pool_entry: LCURLY_BRACKET {
+ ElementPtr m(new MapElement());
+ ctx.stack_.back()->add(m);
+ ctx.stack_.push_back(m);
+} pool_params RCURLY_BRACKET {
+ ctx.stack_.pop_back();
+};
pool_params: pool_param
| pool_params COMMA pool_param;
-pool_param: POOL COLON STRING
+pool_param: POOL COLON STRING {
+ ElementPtr name(new StringElement($3)); ctx.stack_.back()->set("pool", name);
+}
| option_data_list;
// --- end of pools definition -------------------------------
-dhcp6_object: DHCP6 COLON LCURLY_BRACKET {
- // This code is executed when we're about to start parsing
- // the content of the map
- ElementPtr m(new MapElement());
- ctx.stack_.push_back(m);
-} global_params RCURLY_BRACKET {
- // map parsing completed. If we ever want to do any wrap up
- // (maybe some sanity checking), this would be the best place
- // for it.
-};
-
// --- logging entry -----------------------------------------
// This defines the top level "Logging" object. It parses
output_param: OUTPUT COLON STRING;
-// This represents a single top level entry, e.g. Dhcp6 or DhcpDdns.
-global_object: dhcp6_object
-| logging_object;
-
-// This represents top-level entries: Dhcp6, Dhcp4, DhcpDdns, Logging
-global_objects
-: global_object
-| global_objects COMMA global_object
-;
-
-// This defines the top-level { } that holds Dhcp6, Dhcp4, DhcpDdns or Logging
-// objects.
-syntax_map: LCURLY_BRACKET {
- // This code is executed when we're about to start parsing
- // the content of the map
- ElementPtr m(new MapElement());
- ctx.stack_.push_back(m);
-} global_objects RCURLY_BRACKET {
- // map parsing completed. If we ever want to do any wrap up
- // (maybe some sanity checking), this would be the best place
- // for it.
-};
void
isc::dhcp::Dhcp6Parser::error(const location_type& loc,
- const std::string& what)
+ const std::string& what)
{
ctx.error(loc, what);
}