atpg-ls/parser.cpp

148 lines
4.6 KiB
C++
Raw Permalink Normal View History

#include "circuit.h"
#include <iostream>
#include <fstream>
#include <string>
#include <regex>
#include <set>
2023-02-12 16:22:32 +08:00
void line2tokens(const std::string &line, std::vector<std::string> &tokens) {
std::string token;
for(char c : line) {
if(c == ' ' || c == '\t' || c == '\r' || c == '\n') continue;
if(c == '=' || c == ',' || c == '(' || c == ')') {
if(!token.size()) continue;
tokens.push_back(token);
token.clear(); token += c;
tokens.push_back(token);
token.clear();
} else {
token += c;
}
}
if(token.size()) {
tokens.push_back(token);
}
}
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
2023-02-23 11:00:24 +08:00
file.rdbuf()->pubsetbuf(0, 10 * 1024 * 1024);
2023-02-12 16:22:32 +08:00
std::vector<std::string> bufPO;
std::string line;
while(std::getline(file, line)) {
if(line[0] == '#') continue;
if(line == "\r" || line == "") continue;
2023-02-12 16:22:32 +08:00
std::vector<std::string> tokens;
2023-02-12 16:22:32 +08:00
line2tokens(line, tokens);
// std::cout << line << std::endl;
// std::cout << "tokens: ";
// for(auto &token : tokens) {
// std::cout << "$" << token << "$ ";
// }
// std::cout << std::endl;
2023-02-12 16:22:32 +08:00
// gate
if(tokens.size() >= 6 && tokens[1] == "=" && tokens[3] == "(" && tokens.back() == ")") {
std::vector<std::string> ins;
2023-02-12 16:22:32 +08:00
for(int i=4; i<tokens.size()-1; i+=2) {
if(tokens[i] == ",") {
printf("Error while reading line: %s\n", line.c_str());
exit(1);
}
ins.push_back(tokens[i]);
}
for(int i=5; i<tokens.size()-1; i+=2) {
if(tokens[i] != ",") {
printf("Error while reading line: %s\n", line.c_str());
exit(1);
}
}
2023-02-12 16:22:32 +08:00
Gate* gate = new Gate();
gate->name = tokens[0];
2023-02-28 08:45:13 +00:00
gate->propagate = false;
2023-02-19 19:42:50 +08:00
gate->stem = false;
2023-02-27 02:49:59 +00:00
gate->pi = false;
gate->po = false;
2023-02-19 19:42:50 +08:00
2023-02-12 16:22:32 +08:00
for(auto &in : ins) {
if(!name2gate.count(in)) {
2023-02-12 16:22:32 +08:00
printf("Error while reading file: gate %s used before defination.\n", in.c_str());
exit(1);
}
2023-02-12 16:22:32 +08:00
auto in_gate = name2gate[in];
gate->inputs.push_back(in_gate);
in_gate->outputs.push_back(gate);
}
2023-02-12 16:22:32 +08:00
if(tokens[2] == "AND") { gate->type = Gate::AND; }
else if(tokens[2] == "NAND") { gate->type = Gate::NAND; }
else if(tokens[2] == "OR") { gate->type = Gate::OR; }
else if(tokens[2] == "NOR") { gate->type = Gate::NOR; }
else if(tokens[2] == "XOR") { gate->type = Gate::XOR; }
else if(tokens[2] == "XNOR") { gate->type = Gate::XNOR; }
else if(tokens[2] == "NOT") { gate->type = Gate::NOT; }
else if(tokens[2] == "BUFF") { gate->type = Gate::BUF; }
else if(tokens[2] == "BUF") { gate->type = Gate::BUF; }
else {
2023-02-12 16:22:32 +08:00
printf("Error while reading file: %s is not a valid gate.\n", tokens[2].c_str());
exit(1);
}
2023-02-12 16:22:32 +08:00
name2gate.insert(std::make_pair(gate->name, gate));
gates.push_back(gate);
}
// input
else if(tokens.size() == 4 && tokens[0] == "INPUT" && tokens[1] == "(" && tokens[3] == ")") {
Gate* gate = new Gate();
gate->name = tokens[2];
gate->type = Gate::INPUT;
2023-02-28 08:45:13 +00:00
gate->propagate = false;
2023-02-19 19:42:50 +08:00
gate->stem = true;
2023-02-27 02:49:59 +00:00
gate->pi = true;
gate->po = false;
2023-02-12 16:22:32 +08:00
name2gate.insert(std::make_pair(gate->name, gate));
2023-02-19 19:42:50 +08:00
gates.push_back(gate);
2023-02-12 16:22:32 +08:00
PIs.push_back(gate);
}
// gate
else if(tokens.size() == 4 && tokens[0] == "OUTPUT" && tokens[1] == "(" && tokens[3] == ")") {
bufPO.push_back(tokens[2]);
}
// invalid line
else {
printf("Error while reading line: %s\n", line.c_str());
exit(1);
}
}
// handle PO
for(auto& po_name : bufPO) {
if(!name2gate.count(po_name)) {
printf("Error while reading file: po %s is not a exist gate.\n", po_name.c_str());
exit(1);
2023-02-12 16:22:32 +08:00
}
2023-02-19 19:42:50 +08:00
Gate* po = name2gate[po_name];
2023-02-27 02:49:59 +00:00
po->po = true;
2023-02-19 19:42:50 +08:00
po->stem = true;
POs.push_back(po);
}
}