#include "circuit.h" #include #include #include #include #include std::string trim(const std::string& s) { auto wsfront = std::find_if_not(s.begin(), s.end(), [](int c){ return std::isspace(c); }); auto wsback = std::find_if_not(s.rbegin(), s.rend(), [](int c){ return std::isspace(c); }).base(); return (wsback <= wsfront ? std::string() : std::string(wsfront, wsback)); } void Circuit::parse_from_file(const char *filename) { std::ifstream file(filename); if(!file.is_open()) { printf("Error while reading %s\n", filename); exit(1); } // buf 10MB file.rdbuf()->pubsetbuf(0, 10 *1024 * 1024); std::string line; while(std::getline(file, line)) { if(line[0] == '#') continue; if(line == "\r" || line == "") continue; std::cmatch m; if(std::regex_match(line.c_str(), m, std::regex("INPUT\\s*\\(\\s*(.*)\\s*\\)\\s*"))) { Gate *input = new Gate(); input->name = m.str(1); input->type = Gate::INPUT; input->value = Gate::VAL_X; name2gate.insert(std::make_pair(input->name, input)); std::cout << "input -> $" << input->name << "$" << std::endl; PIs.push_back(input); } else if(std::regex_match(line.c_str(), m, std::regex("OUTPUT\\s*\\(\\s*(.*)\\s*\\)\\s*"))) { Gate *output = new Gate(); output->name = m.str(1); output->type = Gate::OUTPUT; output->value = Gate::VAL_X; name2gate.insert(std::make_pair(output->name, output)); POs.push_back(output); } else if(std::regex_match(line.c_str(), m, std::regex("\\s*(\\S+)\\s*=\\s*(\\w+)\\s*\\(\\s*(.*)\\s*\\)\\s*"))) { std::string output_name = m.str(1); std::string gate_name = m.str(2); std::string list = m.str(3); Gate *gate = new Gate(); gate->name = output_name; gate->value = Gate::VAL_X; name2gate.insert(std::make_pair(gate->name, gate)); // split by "," std::regex pattern(R"(\s*,\s*)"); std::sregex_token_iterator it(list.begin(), list.end(), pattern, -1); std::sregex_token_iterator end; while (it != end) { std::string in = trim(*it++); if(!name2gate.count(in)) { printf("Error while reading file: $%s$ is not defined before used.\n", in.c_str()); exit(1); } Gate* in_gate = name2gate[in]; gate->inputs.push_back(in_gate); in_gate->outputs.push_back(gate); } if(gate_name == "AND") { gate->type = Gate::AND; } else if(gate_name == "NAND") { gate->type = Gate::NAND; } else if(gate_name == "OR") { gate->type = Gate::OR; } else if(gate_name == "NOR") { gate->type = Gate::NOR; } else if(gate_name == "XOR") { gate->type = Gate::XOR; } else if(gate_name == "XNOR") { gate->type = Gate::XNOR; } else if(gate_name == "NOT") { gate->type = Gate::NOT; } else if(gate_name == "BUF") { gate->type = Gate::BUF; } else { printf("Error while reading file: %s is not a valid gate.\n", gate_name.c_str()); exit(1); } } else { printf("Error while reading file: \"%s\" is a wrong line.\n", line.c_str()); exit(1); } } }