//pstring get_string(); protected string get_identifier() { ptokenizer_token_t tok = get_token(); if (!tok.is_type(ptokenizer_token_type.IDENTIFIER)) { error(MF_EXPECTED_IDENTIFIER_GOT_1(tok.str())); } return(tok.str()); }
protected string get_identifier_or_number() { ptokenizer_token_t tok = get_token(); if (!(tok.is_type(ptokenizer_token_type.IDENTIFIER) || tok.is_type(ptokenizer_token_type.NUMBER))) { error(MF_EXPECTED_ID_OR_NUM_GOT_1(tok.str())); } return(tok.str()); }
protected void require_token(ptokenizer_token_t tok, ptokenizer_token_id_t token_num) { if (!tok.is_(token_num)) { error(MF_EXPECTED_TOKEN_1_GOT_2(token_num.name(), tok.str())); } }
string stringify_expression(ref parser_t_token_t tok) { int pc = 0; string ret = ""; while (!tok.is_(m_tok_comma)) { if (tok.is_(m_tok_paren_left)) { pc++; } else if (tok.is_(m_tok_paren_right)) { if (pc <= 0) { break; } pc--; } ret += tok.str(); tok = get_token(); } return(ret); }
void netdev_param() { require_token(m_tok_paren_left); string param = get_identifier(); require_token(m_tok_comma); parser_t_token_t tok = get_token(); if (tok.is_type(parser_t_token_type.STRING)) { m_setup.log().debug.op("Parser: Param: {0} {1}\n", param, tok.str()); m_setup.register_param(param, tok.str()); require_token(m_tok_paren_right); } else { var val = stringify_expression(ref tok); m_setup.log().debug.op("Parser: Param: {0} {1}\n", param, val); m_setup.register_param(param, val); require_token(tok, m_tok_paren_right); } }
void net_c() { require_token(m_tok_paren_left); string first = get_identifier(); require_token(m_tok_comma); while (true) { string t1 = get_identifier(); m_setup.register_link(first, t1); m_setup.log().debug.op("Parser: Connect: {0} {1}\n", first, t1); parser_t_token_t n = get_token(); if (n.is_(m_tok_paren_right)) { break; } if (!n.is_(m_tok_comma)) { error(MF_EXPECTED_COMMA_OR_RP_1(n.str())); } } }
bool process_line_token(ptokenizer_token_t tok) { if (tok.is_type(ptokenizer_token_type.LINEMARKER)) { bool benter = false; bool bexit = false; string file; unsigned lineno = 0; var sp = plib.pg.psplit(tok.str(), ' '); //printf("%d %s\n", (int) sp.size(), ret.str().c_str()); bool err = false; lineno = plib.pg.pstonum_ne_unsigned(false, sp[1], out err); if (err) { error(MF_EXPECTED_LINENUM_GOT_1(tok.str())); } if (sp[2].substr(0, 1) != "\"") { error(MF_EXPECTED_FILENAME_GOT_1(tok.str())); } file = sp[2].substr(1, sp[2].length() - 2); for (size_t i = 3; i < sp.size(); i++) { if (sp[i] == "1") { benter = true; } if (sp[i] == "2") { bexit = true; } // FIXME: process flags; actually only 1 (file enter) and 2 (after file exit) } if (bexit) // pop the last location { m_source_location.pop_back(); } if (!benter) // new location! { m_source_location.pop_back(); } m_source_location.emplace_back(new plib.source_location(file, lineno)); return(true); } if (tok.is_type(ptokenizer_token_type.SOURCELINE)) { m_line = tok.str(); m_source_location.back().inc(); //++m_source_location.back(); return(true); } return(false); }
void parse_netlist() { while (true) { parser_t_token_t token = get_token(); if (token.is_type(parser_t_token_type.ENDOFFILE)) { error(MF_UNEXPECTED_END_OF_FILE()); } m_setup.log().debug.op("Parser: Device: {0}\n", token.str()); if (token.is_(m_tok_ALIAS)) { net_alias(); } else if (token.is_(m_tok_DIPPINS)) { dippins(); } else if (token.is_(m_tok_NET_C)) { net_c(); } else if (token.is_(m_tok_FRONTIER)) { frontier(); } else if (token.is_(m_tok_PARAM)) { netdev_param(); } else if (token.is_(m_tok_DEFPARAM)) { netdev_defparam(); } else if (token.is_(m_tok_HINT)) { netdev_hint(); } else if (token.is_(m_tok_NET_MODEL)) { net_model(); } else if (token.is_(m_tok_SUBMODEL)) { net_submodel(); } else if (token.is_(m_tok_INCLUDE)) { net_include(); } else if (token.is_(m_tok_LOCAL_SOURCE)) { net_local_source(); } else if (token.is_(m_tok_EXTERNAL_SOURCE)) { net_external_source(); } else if (token.is_(m_tok_LOCAL_LIB_ENTRY)) { net_lib_entry(true); } else if (token.is_(m_tok_EXTERNAL_LIB_ENTRY)) { net_lib_entry(false); } else if (token.is_(m_tok_TRUTHTABLE_ENTRY)) { require_token(m_tok_paren_left); string name = get_identifier(); register_local_as_source(name); m_setup.include(name); require_token(m_tok_paren_right); } else if (token.is_(m_tok_NET_REGISTER_DEV)) { net_register_dev(); } else if (token.is_(m_tok_NETLIST_END)) { netdev_netlist_end(); return; } else if (!token.is_type(parser_t_token_type.IDENTIFIER)) { error(MF_EXPECTED_IDENTIFIER_GOT_1(token.str())); } else { device(token.str()); } } }
//bool parse(plib::istream_uptr &&strm, const pstring &nlname); public bool parse(parser_t_token_store tokstor, string nlname) { set_token_source(tokstor); bool in_nl = false; while (true) { // FIXME: line numbers in cached local netlists are wrong // need to process raw tokens here. parser_t_token_t token = get_token_raw(); if (token.is_type(parser_t_token_type.ENDOFFILE)) { return(false); } if (token.is_(m_tok_NETLIST_END) || token.is_(m_tok_TRUTHTABLE_END)) { if (!in_nl) { error(MF_PARSER_UNEXPECTED_1(token.str())); } else { in_nl = false; } require_token(m_tok_paren_left); require_token(m_tok_paren_right); m_cur_local.push_back(token); m_cur_local.push_back(new parser_t_token_t(m_tok_paren_left)); m_cur_local.push_back(new parser_t_token_t(m_tok_paren_right)); } else if (token.is_(m_tok_NETLIST_START) || token.is_(m_tok_TRUTHTABLE_START)) { if (in_nl) { error(MF_PARSER_UNEXPECTED_1(token.str())); } require_token(m_tok_paren_left); parser_t_token_t name = get_token(); if (token.is_(m_tok_NETLIST_START) && (name.str() == nlname || nlname.empty())) { require_token(m_tok_paren_right); parse_netlist(); return(true); } if (token.is_(m_tok_TRUTHTABLE_START) && name.str() == nlname) { net_truthtable_start(nlname); return(true); } // create a new cached local store m_local.emplace(name.str(), new parser_t_token_store()); m_cur_local = m_local[name.str()]; var sl = sourceloc(); var li = new plib.pfmt("# {0} \"{1}\"").op(sl.line(), sl.file_name()); m_cur_local.push_back(new parser_t_token_t(parser_t_token_type.LINEMARKER, li)); m_cur_local.push_back(token); m_cur_local.push_back(new parser_t_token_t(m_tok_paren_left)); m_cur_local.push_back(name); //m_cur_local->push_back(token_t(m_tok_paren_right)); in_nl = true; } // FIXME: do we really need this going forward ? there should be no need // for NETLIST_EXTERNAL in netlist files else if (token.is_(m_tok_NETLIST_EXTERNAL)) { if (in_nl) { error(MF_UNEXPECTED_NETLIST_EXTERNAL()); } require_token(m_tok_paren_left); parser_t_token_t name = get_token(); require_token(m_tok_paren_right); } else if (!in_nl) { if (!token.is_(m_tok_static) && !token.is_type(parser_t_token_type.SOURCELINE) && !token.is_type(parser_t_token_type.LINEMARKER)) { error(MF_EXPECTED_NETLIST_START_1(token.str())); } } else { m_cur_local.push_back(token); } } }