From 952c31861914a60c6a0aa8378ca06dc844245b4f Mon Sep 17 00:00:00 2001 From: John Breaux Date: Fri, 22 Apr 2022 21:12:22 -0500 Subject: [PATCH] read_input: - Clarify what each regex does by assigning rule numbers - Properly handle commented-out lines in input files - Properly scope several vars which were in too broad a scope - Rewrite string-to-vector to use regex to parse malformed input - Remove dependency on sstream. --- src/read_input.cpp | 68 ++++++++++++++++++++++------------------------ 1 file changed, 32 insertions(+), 36 deletions(-) diff --git a/src/read_input.cpp b/src/read_input.cpp index 1c6744b..0fc4b58 100644 --- a/src/read_input.cpp +++ b/src/read_input.cpp @@ -1,54 +1,58 @@ //TODO: Include C file IO header (stdio.h? Whatever it is) #include -#include #include #include #include #include #include "graph.hpp" -#define MAX_LINE_LEN 1024 +#define MAX_INT_LEN 16 -// Vector of regices +// Vector of regices, in order of precedence. Earlier entries will be checked before later entries. std::vector patterns = { - //* A line starting with a % is a comment, and should be skipped - //* A blank line should be skipped - //* A line starting with `num_processes=` contains the number of processes - std::regex("^.*(num_processes)\\s*=\\s*(\\d+).*"), - //* A line starting with `num_resources=` contains the number of resources - std::regex("^.*(num_resources)\\s*=\\s*(\\d+)"), - //* A line containing comma-separated values should be returned as-is, for manual disassembly - std::regex("^([\\-0-9, ]+)")}; // matches comma-separated space-separated signed decimal integers + //* Rule 1: A line starting with a % is a comment, and should not be parsed + std::regex("^\\s*(%)"), + //* Rule 2: A line starting with `num_processes=` contains the number of processes + std::regex("^.*(num_processes)\\s*=\\s*(\\d+).*"), + //* Rule 3: A line starting with `num_resources=` contains the number of resources + std::regex("^.*(num_resources)\\s*=\\s*(\\d+)"), + //* Rule 4: A line containing only comma-separated values should be captured completely + std::regex("^([\\-0-9, ]+)") // matches comma-separated space-separated signed decimal integers +}; // convert comma-separated string s to vector std::vector stovi (const std::string &s); // TODO: Implement reading from a file void graph::read(std::string filename) { - printf("graph::read(%s)\n", filename.c_str()); // Open file with name filename as read-only std::fstream f; f.open(filename, f.in); - // TODO: Check for file IO errors (I might have a solution for that in another project) - std::string line; // Lines can be no more than 1KB in size, a sensible limitation + while (!f.eof()) { + // acquire a line + std::string line; std::getline (f, line); - std::smatch res; // Iterate over each pattern, and grab the associated data for (auto pattern: patterns) { + std::smatch res; if (std::regex_search (line, res, pattern)) { // get the pattern type, value std::string type = res.format("$1"), value = res.format("$2"); - // Handle the pattern - // If num_processes= matched, assign value to num_processes + // Rule 1: If line is a comment, ignore it and move on + if (type == "%"); else + + // Rule 2: If num_processes= matched, assign value to num_processes if (type == "num_processes") { num_processes = std::stoi(value); } else - // If num_resources= matched, assign value to num_resources + + // Rule 3: If num_resources= matched, assign value to num_resources if (type == "num_resources") { num_resources = std::stoi(value); } else - // If this line is a comma-separated list of numbers, + + // Rule 4: If this line is a comma-separated list of numbers, // and this is the first match, assign it to resource counts if (!resource_counts.size()) { resource_counts = stovi(type); } else // and this is a subsequent match, push it onto the matrix @@ -64,24 +68,16 @@ void graph::read(std::string filename) { f.close(); // TODO: Check for file IO errors (Shouldn't be any) - // print information about the graph - printf("np: %d\tnr: %d\n", num_processes, num_resources); - printf("resource_counts:\n"); for (auto e: resource_counts) printf("%d\t", e); printf("\n"); - printf("matrix:\n"); for (auto x: matrix.data) {for (auto y: x) printf("%d\t", y); printf("\n");} return; } std::vector stovi (const std::string &s) { - std::stringstream ss(s); - printf("%s\n", s.c_str()); - size_t idx = 0; - std::vector vi; - // reserve enough space for an entire string of one-character ints - vi.reserve((s.length()+1)/2); - while (!ss.eof()) { - char integer[16]; // " -WXXXYYYZZZ," - ss.getline(integer, 16, ','); - vi.push_back(atoi( (const char* ) &integer)); - } - return vi; -} + // Create the number classifier + std::regex breaker("[0-9]+"); + std::sregex_token_iterator first{s.begin(), s.end(), breaker, 0}, last; + // Match the numbers + std::vector res; + for (auto i = first; i != last; ++i) res.push_back(atoi(i->str().c_str())); + // give the numbers back + return res; +} \ No newline at end of file