std::unique_ptr<table> parser::parse_table(const std::shared_ptr<const global_table_set>& gts, group_mem_protocol gmp, bool inside_rule_box) { HC_LOG_TRACE(""); std::string table_name; std::list<std::unique_ptr<rule_box>> rule_box_list; if (get_parser_type() == PT_TABLE) { get_next_token(); if ((!inside_rule_box && m_scanner.get_next_token(true, 0).get_type() == TT_NIL) || (inside_rule_box && m_scanner.get_next_token(true, 0).get_type() == TT_RIGHT_BRACKET )) { //table reference if (m_current_token.get_type() == TT_STRING) { table_name = m_current_token.get_string(); if (gts->get_table(table_name) != nullptr) { get_next_token(); auto rb = std::unique_ptr<rule_box>(new rule_table_ref(table_name, gts)); rule_box_list.push_back(std::move(rb)); return std::unique_ptr<table>(new table(std::string(), std::move(rule_box_list))); } else { HC_LOG_ERROR("failed to parse line " << m_current_line << " table " << table_name << " not found"); throw "failed to parse config file"; } } } else if (m_current_token.get_type() == TT_STRING || m_current_token.get_type() == TT_LEFT_BRACE) { if (m_current_token.get_type() == TT_STRING) { table_name = m_current_token.get_string(); get_next_token(); if (m_current_token.get_type() != TT_LEFT_BRACE) { HC_LOG_ERROR("failed to parse line " << m_current_line << " unknown token " << get_token_type_name(m_current_token.get_type()) << " with value " << m_current_token.get_string() << " in this context"); throw "failed to parse config file"; } } get_next_token(); auto tmp_rule = parse_rule(gts, gmp); while (tmp_rule != nullptr) { rule_box_list.push_back(std::move(tmp_rule)); get_next_token(); tmp_rule = parse_rule(gts, gmp); } if (m_current_token.get_type() == TT_RIGHT_BRACE) { get_next_token(); if ((!inside_rule_box && m_current_token.get_type() == TT_NIL) || (inside_rule_box && m_current_token.get_type() == TT_RIGHT_BRACKET)) { return std::unique_ptr<table>(new table(table_name, std::move(rule_box_list))); } } } } HC_LOG_ERROR("failed to parse line " << m_current_line << " unknown token " << get_token_type_name(m_current_token.get_type()) << " with value " << m_current_token.get_string() << " in this context"); throw "failed to parse config file"; }
// TODO support initialising with a file object or a string. static int Preprocessor_init(Preprocessor *self, PyObject *args, PyObject *kwds) { if (!PyArg_ParseTuple(args, "O", &self->parser)) return -1; if (!PyObject_TypeCheck(self->parser, get_parser_type())) { PyErr_SetString(PyExc_TypeError, "expected Parser as argument"); return -1; } Py_INCREF(self->parser); self->preprocessor = &get_parser(self->parser).getPreprocessor(); return 0; }
group_mem_protocol parser::parse_group_mem_proto() { HC_LOG_TRACE(""); //protocol = "protocol" potocol_type; //protocol_type = "MLDv1" | "MLDv2" | "IGMPv1" | "IGMPv2" | "IGMPv3"; group_mem_protocol result; if (get_parser_type() == PT_PROTOCOL) { get_next_token(); switch (m_current_token.get_type()) { case TT_MLDV1: result = MLDv1; break; case TT_MLDV2: result = MLDv2; break; case TT_IGMPV1: result = IGMPv1; break; case TT_IGMPV2: result = IGMPv2; break; case TT_IGMPV3: result = IGMPv3; break; default: HC_LOG_ERROR("failed to parse line " << m_current_line << " unknown token " << get_token_type_name(m_current_token.get_type()) << " with value " << m_current_token.get_string() << ", expected \"MLDV1\" or \"MLDv2\" or \"IGMPv1\" or \"IGMPv2\" or \"IGMPv3\""); throw "failed to parse config file"; break; } }else{ HC_LOG_ERROR("failed to parse line " << m_current_line << " unknown token " << get_token_type_name(m_current_token.get_type()) << " with value " << m_current_token.get_string() << ", expected \"protocol\""); throw "failed to parse config file"; } get_next_token(); if (m_current_token.get_type() == TT_NIL) { return result; } else { HC_LOG_ERROR("failed to parse line " << m_current_line << " unknown token " << get_token_type_name(m_current_token.get_type()) << " with value " << m_current_token.get_string()); throw "failed to parse config file"; } }
void parser::parse_interface_rule_binding(const std::shared_ptr<const global_table_set>& gts, group_mem_protocol gmp, const inst_def_set& ids) { HC_LOG_TRACE(""); //pinstance split downstream tunD1 out whitelist table {tunU1(* | *)}; std::string instance_name; rb_interface_type interface_type; std::string if_name; rb_interface_direction filter_direction; auto error_notification = [&]() { HC_LOG_ERROR("failed to parse line " << m_current_line << " unknown token " << get_token_type_name(m_current_token.get_type()) << " with value " << m_current_token.get_string() << " in this context"); throw "failed to parse config file"; }; if (get_parser_type() == PT_INTERFACE_RULE_BINDING) { get_next_token(); if (m_current_token.get_type() == TT_STRING) { instance_name = m_current_token.get_string(); auto it = ids.find(instance_name); if (it == ids.end()) { HC_LOG_ERROR("failed to parse line " << m_current_line << " proxy instance " << m_current_token.get_string() << " not defined"); throw "failed to parse config file"; } } else { error_notification(); } get_next_token(); if (m_current_token.get_type() == TT_UPSTREAM) { interface_type = IT_UPSTREAM; } else if (m_current_token.get_type() == TT_DOWNSTREAM) { interface_type = IT_DOWNSTREAM; } else { error_notification(); } get_next_token(); if (m_current_token.get_type() == TT_STRING) { if_name = m_current_token.get_string(); } else if (m_current_token.get_type() == TT_STAR) { if_name = "*"; } else { error_notification(); } get_next_token(); if (m_current_token.get_type() == TT_IN) { filter_direction = ID_IN; } else if (m_current_token.get_type() == TT_OUT) { filter_direction = ID_OUT; } else { error_notification(); } get_next_token(); if (m_current_token.get_type() == TT_WHITELIST || m_current_token.get_type() == TT_BLACKLIST) { return parse_interface_table_binding(std::move(instance_name), interface_type, std::move(if_name), filter_direction, gts, gmp, ids); } else if (m_current_token.get_type() == TT_RULE_MATCHING) { return parse_interface_rule_match_binding(std::move(instance_name), interface_type, std::move(if_name), filter_direction, ids); } else { error_notification(); } } else { error_notification(); } HC_LOG_ERROR("this code should never reached"); throw "this code should never reached"; }
void parser::parse_instance_definition(inst_def_set& ids) { HC_LOG_TRACE(""); //pinstance = "pinstance" @instance_name@ (instance_definition | interface_rule_binding); //instance_definition = ":" {@if_name@} "==>" @if_name@ {@if_name@}; std::list<std::shared_ptr<interface>> upstreams; std::list<std::shared_ptr<interface>> downstreams; std::string instance_name; int table_number = 0; bool user_selected_table_number = false; if (get_parser_type() == PT_INSTANCE_DEFINITION) { get_next_token(); if (m_current_token.get_type() == TT_STRING) { instance_name = m_current_token.get_string(); get_next_token(); if (m_current_token.get_type() == TT_LEFT_BRACKET) { get_next_token(); if (m_current_token.get_type() == TT_STRING) { try { table_number = std::stoi(m_current_token.get_string()); user_selected_table_number = true; } catch (std::logic_error e) { HC_LOG_ERROR("failed to parse line " << m_current_line << " table number: " << table_number << " is not a number"); throw "failed to parse config file"; } get_next_token(); if (m_current_token.get_type() == TT_RIGHT_BRACKET) { get_next_token(); } else { HC_LOG_ERROR("failed to parse line " << m_current_line << " instance " << instance_name << " with unknown table number"); throw "failed to parse config file"; } } else { HC_LOG_ERROR("failed to parse line " << m_current_line << " instance " << instance_name << " with unknown table number"); throw "failed to parse config file"; } } if (m_current_token.get_type() == TT_DOUBLE_DOT) { get_next_token(); while (m_current_token.get_type() == TT_STRING) { upstreams.push_back(std::make_shared<interface>(m_current_token.get_string())); get_next_token(); } if (m_current_token.get_type() == TT_ARROW) { get_next_token(); while (m_current_token.get_type() == TT_STRING) { downstreams.push_back(std::make_shared<interface>(m_current_token.get_string())); get_next_token(); } if (downstreams.size() > 0 && m_current_token.get_type() == TT_NIL) { if (!ids.insert(std::make_shared<instance_definition>(instance_name, std::move(upstreams), std::move(downstreams), table_number, user_selected_table_number))) { HC_LOG_ERROR("failed to parse line " << m_current_line << " instance " << instance_name << " already exists"); throw "failed to parse config file"; } else { return; } } } } } } HC_LOG_ERROR("failed to parse line " << m_current_line << " unknown token " << get_token_type_name(m_current_token.get_type()) << " with value " << m_current_token.get_string() << " in this context"); throw "failed to parse config file"; }