diff --git a/crlcore/src/ccore/blif/BlifParser.cpp b/crlcore/src/ccore/blif/BlifParser.cpp index b2c3840f..96512d35 100644 --- a/crlcore/src/ccore/blif/BlifParser.cpp +++ b/crlcore/src/ccore/blif/BlifParser.cpp @@ -109,12 +109,34 @@ namespace { bool operator<(model const & o) const{ return name < o.name; } }; + std::vector tokenize(std::string const & s){ + std::vector ret; + auto b_it = s.begin(); + while(b_it != s.end()){ + // Remove whitespace + while(b_it != s.end() && (*b_it == ' ' or *b_it == '\t')) + ++b_it; + // Find the end of the token + auto e_it = b_it; + while(e_it != s.end() && *e_it != ' ' && *e_it != '\t' and *e_it != '#') + ++e_it; + // Create the token + if(e_it != b_it) + ret.push_back(std::string(b_it, e_it)); + // Handle comments + if(e_it != s.end() && *e_it == '#') + e_it = s.end(); + b_it = e_it; + } + std::reverse(ret.begin(), ret.end()); + return ret; + } + } // End of anonymous namespace. namespace CRL { - // // Can only parse simple, netlist BLIF files generated by Yosys // Ignores all ".names" and uses only the .subckt, .model, .input and .output @@ -140,11 +162,10 @@ Cell * Blif::load ( string cellPath ) //, Cell *cell ) vector current_names; while(getline(ccell, line)){ istringstream linestream(line); - string before_comment; - getline(linestream, before_comment, '#'); - istringstream tokens(before_comment); - string token; - if(tokens >> token){ + vector tokens = tokenize(line); + if(not tokens.empty()){ + string const token = tokens.back(); + tokens.pop_back(); assert(not token.empty()); if(token[0] == '.'){ // Process finished .names statement @@ -226,7 +247,9 @@ Cell * Blif::load ( string cellPath ) //, Cell *cell ) } } // Process all tokens after the control - while(tokens >> token){ + while(not tokens.empty()){ + string const token = tokens.back(); + tokens.pop_back(); assert(not token.empty()); // Either a pin or an input/output definition if(state == INPUTS or state == OUTPUTS){ @@ -242,14 +265,18 @@ Cell * Blif::load ( string cellPath ) //, Cell *cell ) else if(state == SUBCKT){ if(hasName){ // Encountered a pin: need to be processed - istringstream token_stream(token); - string before_space, after_space; - getline(token_stream, before_space, '='); - getline(token_stream, after_space, '='); - if(token_stream){ - Error("Encountered more than one '=' in token"); + auto equal_pos = token.find_first_of('='); + if(equal_pos+1 < token.size()){ + string before_space = token.substr(0, equal_pos); + string after_space = token.substr(equal_pos+1, string::npos); + models.back().subcircuits.back().pins.push_back(pair(before_space, after_space)); + } + else{ + ostringstream mess; + mess << "Unable to parse the subckt pin specification <" + << token << ">\n"; + Error(mess.str()); } - models.back().subcircuits.back().pins.push_back(pair(before_space, after_space)); } else{ models.back().subcircuits.back().cell = token;