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<int> to use regex to parse malformed input - Remove dependency on sstream.
This commit is contained in:
		@@ -1,54 +1,58 @@
 | 
			
		||||
//TODO: Include C file IO header (stdio.h? Whatever it is)
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include <sstream>
 | 
			
		||||
#include <fstream>
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <vector>
 | 
			
		||||
#include <regex>
 | 
			
		||||
#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<std::regex> 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<int>
 | 
			
		||||
std::vector<int> 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<int> stovi (const std::string &s) {
 | 
			
		||||
   std::stringstream ss(s);
 | 
			
		||||
   printf("%s\n", s.c_str());
 | 
			
		||||
   size_t idx = 0;
 | 
			
		||||
   std::vector<int> 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<int> res;
 | 
			
		||||
   for (auto i = first; i != last; ++i) res.push_back(atoi(i->str().c_str()));
 | 
			
		||||
   // give the numbers back
 | 
			
		||||
   return res;
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user