Performance improvements for the BLIF parser

Got rid of streams
This commit is contained in:
Gabriel Gouvine 2015-04-13 17:38:51 +02:00
parent d7f9e5cb87
commit 575b6c923a
1 changed files with 41 additions and 14 deletions

View File

@ -109,12 +109,34 @@ namespace {
bool operator<(model const & o) const{ return name < o.name; } bool operator<(model const & o) const{ return name < o.name; }
}; };
std::vector<std::string> tokenize(std::string const & s){
std::vector<std::string> 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. } // End of anonymous namespace.
namespace CRL { namespace CRL {
// //
// Can only parse simple, netlist BLIF files generated by Yosys // Can only parse simple, netlist BLIF files generated by Yosys
// Ignores all ".names" and uses only the .subckt, .model, .input and .output // Ignores all ".names" and uses only the .subckt, .model, .input and .output
@ -140,11 +162,10 @@ Cell * Blif::load ( string cellPath ) //, Cell *cell )
vector<string> current_names; vector<string> current_names;
while(getline(ccell, line)){ while(getline(ccell, line)){
istringstream linestream(line); istringstream linestream(line);
string before_comment; vector<string> tokens = tokenize(line);
getline(linestream, before_comment, '#'); if(not tokens.empty()){
istringstream tokens(before_comment); string const token = tokens.back();
string token; tokens.pop_back();
if(tokens >> token){
assert(not token.empty()); assert(not token.empty());
if(token[0] == '.'){ if(token[0] == '.'){
// Process finished .names statement // Process finished .names statement
@ -226,7 +247,9 @@ Cell * Blif::load ( string cellPath ) //, Cell *cell )
} }
} }
// Process all tokens after the control // 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()); assert(not token.empty());
// Either a pin or an input/output definition // Either a pin or an input/output definition
if(state == INPUTS or state == OUTPUTS){ if(state == INPUTS or state == OUTPUTS){
@ -242,15 +265,19 @@ Cell * Blif::load ( string cellPath ) //, Cell *cell )
else if(state == SUBCKT){ else if(state == SUBCKT){
if(hasName){ if(hasName){
// Encountered a pin: need to be processed // Encountered a pin: need to be processed
istringstream token_stream(token); auto equal_pos = token.find_first_of('=');
string before_space, after_space; if(equal_pos+1 < token.size()){
getline(token_stream, before_space, '='); string before_space = token.substr(0, equal_pos);
getline(token_stream, after_space, '='); string after_space = token.substr(equal_pos+1, string::npos);
if(token_stream){
Error("Encountered more than one '=' in token");
}
models.back().subcircuits.back().pins.push_back(pair<string, string>(before_space, after_space)); models.back().subcircuits.back().pins.push_back(pair<string, string>(before_space, after_space));
} }
else{
ostringstream mess;
mess << "Unable to parse the subckt pin specification <"
<< token << ">\n";
Error(mess.str());
}
}
else{ else{
models.back().subcircuits.back().cell = token; models.back().subcircuits.back().cell = token;
hasName = true; hasName = true;