Skip to content

Instantly share code, notes, and snippets.

@Romain-P
Created March 2, 2018 03:00
Show Gist options
  • Select an option

  • Save Romain-P/e5e43b6fdddb647e6a832d2adc02018e to your computer and use it in GitHub Desktop.

Select an option

Save Romain-P/e5e43b6fdddb647e6a832d2adc02018e to your computer and use it in GitHub Desktop.
//
// EPITECH PROJECT, 2018
//
// File description:
//
//
#include "Parser.hpp"
#include <string>
#include <iostream>
#include <fstream>
#include <algorithm>
#include <map>
#include <vector>
#include "Exceptions.hpp"
namespace nts {
//static const references
char constexpr Parser::CONFIG_KW_CHIPSETS[];
char constexpr Parser::CONFIG_KW_LINKS[];
//constants init
std::regex const Parser::REGEX_COMMENTS("^([^#]+)");
std::regex const Parser::REGEX_CHIPSETS("^(\\S+)\\s+([^\\s(]+)(?:\\(([^\\s]+)\\))?$");
std::regex const Parser::REGEX_LINKS("^(\\S+):(\\d+)[^\\S]*(\\S+):(\\d+)$");
void Parser::run() {
std::ifstream stream(_file);
if (!stream.is_open())
throw(ParsingError("Can't open the file " + _file));
std::smatch matcher;
std::string line;
while (std::getline(stream, line)) {
if (!parse_comments(matcher, line))
continue;
switch (_state) {
case COMMENTS:
if (line.find(CONFIG_KW_CHIPSETS))
throw(ParsingError("Section chipsets not found"));
_state = CHIPSETS;
break;
case CHIPSETS:
if (!line.find(CONFIG_KW_LINKS))
_state = LINKS;
else if (!parse_chipsets(matcher, line))
throw(ParsingError("Syntax error while parsing chipsets"));
break;
case LINKS:
if (!parse_links(matcher, line))
throw(ParsingError("Syntax error while parsing links"));
break;
}
}
if (_state != LINKS)
throw ParsingError(("Section links not found"));
}
bool Parser::parse_comments(std::smatch &matcher, std::string &line) const {
if (!std::regex_search(line, matcher, REGEX_COMMENTS))
return false; //empty line
line = matcher[1];
return !std::all_of(line.begin(), line.end(), isspace); //return true if only whitespaces
}
bool Parser::parse_chipsets(std::smatch &matcher, std::string &line) const {
if (!std::regex_search(line, matcher, REGEX_CHIPSETS))
return false;
std::string component = matcher[1];
std::string name = matcher[2];
std::string value = matcher[3]; //empty if not specified
std::cout << "[parser] " << component << " " << name << " " << value << std::endl;
return true;
}
bool Parser::parse_links(std::smatch &matcher, std::string &line) const {
if (!std::regex_search(line, matcher, REGEX_LINKS))
return false;
std::string component_a = matcher[1];
std::string pin_a = matcher[2];
std::string component_b = matcher[3];
std::string pin_b = matcher[4];
std::cout << "[parser] " << component_a << "<->" << pin_a << " | " << component_b << "<->" << pin_b << std::endl;
return true;
}
}
//
// Created by romain on 01/03/2018.
//
#ifndef CPP_NANOTEKSPICE_HEADER_H
#define CPP_NANOTEKSPICE_HEADER_H
#include "ComponentFactory.hpp"
#include <regex>
namespace nts
{
class Parser
{
public:
Parser(ComponentFactory &factory, std::string const &file)
: _factory(&factory), _file(file), _state(COMMENTS) {};
~Parser() = default;
Parser(Parser const &) = delete;
Parser(Parser &) = delete;
Parser &operator=(Parser const &) = delete;
Parser &operator=(Parser &) = delete;
/**
* Perform the parsing of the file field previously opened
*/
void run();
private:
static char constexpr CONFIG_KW_CHIPSETS[] = ".chipsets:";
static char constexpr CONFIG_KW_LINKS[] = ".links:";
static std::regex const REGEX_COMMENTS;
static std::regex const REGEX_CHIPSETS;
static std::regex const REGEX_LINKS;
bool parse_comments(std::smatch &matcher, std::string &line) const;
bool parse_chipsets(std::smatch &matcher, std::string &line) const;
bool parse_links(std::smatch &matcher, std::string &line) const;
enum ParserFunc {
COMMENTS,
CHIPSETS,
LINKS
};
ComponentFactory *_factory;
std::string const _file;
ParserFunc _state;
};
}
#endif //CPP_NANOTEKSPICE_HEADER_H
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment