Created
March 3, 2018 02:33
-
-
Save Romain-P/a798ec42b6733ed04fbf775175b54663 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // | |
| // EPITECH PROJECT, 2018 | |
| // | |
| // File description: | |
| // | |
| // | |
| #include <Exceptions.hpp> | |
| #include <iostream> | |
| #include "ConsoleAnalyser.hpp" | |
| #include <signal.h> | |
| #include <stdlib.h> | |
| #include <stdio.h> | |
| #include <unistd.h> | |
| namespace nts { | |
| //reference | |
| char constexpr ConsoleAnalyser::STATEMENT_DELIMITER; | |
| char constexpr ConsoleAnalyser::COMMAND_EXIT[]; | |
| char constexpr ConsoleAnalyser::COMMAND_DISPLAY[]; | |
| char constexpr ConsoleAnalyser::COMMAND_SIMULATE[]; | |
| char constexpr ConsoleAnalyser::COMMAND_LOOP[]; | |
| char constexpr ConsoleAnalyser::COMMAND_DUMP[]; | |
| bool ConsoleAnalyser::loop_mode = false; | |
| bool ConsoleAnalyser::parse_options() { | |
| if (_parsed) | |
| return false; | |
| for (size_t i=2; i < _argc; ++i) { | |
| std::string opt(_args[i]); | |
| if (!parse_statement(opt)) | |
| throw ParsingError("Invalid option"); | |
| } | |
| return (_parsed = true); | |
| } | |
| bool ConsoleAnalyser::init_analyser() { | |
| if (_init) | |
| return false; | |
| _init = true; | |
| handle_sigint(); | |
| std::cout << "> "; | |
| for(std::string line; std::getline(std::cin, line);) { | |
| if (line == COMMAND_EXIT) | |
| break; | |
| else if (line == COMMAND_DISPLAY) | |
| _manager->Display(); | |
| else if (line == COMMAND_SIMULATE) | |
| _manager->Simulate(); | |
| else if (line == COMMAND_LOOP) | |
| start_loop(); | |
| else if (line == COMMAND_DUMP) | |
| _manager->Dump(); | |
| else if (!parse_statement(line)) | |
| throw ParsingError("Unknown command"); | |
| std::cout << "> "; | |
| } | |
| return true; | |
| } | |
| bool ConsoleAnalyser::parse_statement(std::string &line) const { | |
| size_t delimiter_pos = line.find(STATEMENT_DELIMITER); | |
| if (delimiter_pos == std::string::npos) | |
| return false; | |
| std::string component = line.substr(0, delimiter_pos); | |
| line.erase(0, delimiter_pos + 1); | |
| char state = (char) std::stoi(line); | |
| Tristate parsed; | |
| switch(state) { | |
| case true: | |
| parsed = TRUE; | |
| break; | |
| case false: | |
| parsed = FALSE; | |
| break; | |
| case -true: | |
| parsed = UNDEFINED; | |
| break; | |
| default: | |
| throw ParsingError("Invalid command statement found"); | |
| } | |
| _manager->ChangePinValue(component, parsed); | |
| return true; | |
| } | |
| void ConsoleAnalyser::handle_sigint() { | |
| struct sigaction sigIntHandler; | |
| sigIntHandler.sa_handler = [](int) -> void { | |
| std::cout<<std::endl; | |
| loop_mode = false; | |
| }; | |
| sigemptyset(&sigIntHandler.sa_mask); | |
| sigIntHandler.sa_flags = 0; | |
| sigaction(SIGINT, &sigIntHandler, nullptr); | |
| } | |
| void ConsoleAnalyser::start_loop() { | |
| loop_mode = true; | |
| while (loop_mode) | |
| _manager->Simulate(); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // | |
| // EPITECH PROJECT, 2018 | |
| // | |
| // File description: | |
| // | |
| // | |
| #ifndef UNTITLED3_CONSOLEANALYSER_H | |
| #define UNTITLED3_CONSOLEANALYSER_H | |
| #include <cstddef> | |
| #include "Parser.hpp" | |
| #include "NtsManager.hpp" | |
| namespace nts { | |
| class ConsoleAnalyser { | |
| public: | |
| ConsoleAnalyser(NtsManager &manager, std::size_t argc, char *args[]) | |
| : _init(false), _parsed(false), _manager(&manager), _argc(argc), _args(args) {}; | |
| ~ConsoleAnalyser() = default; | |
| ConsoleAnalyser(ConsoleAnalyser const &) = delete; | |
| ConsoleAnalyser(ConsoleAnalyser &) = delete; | |
| ConsoleAnalyser &operator=(ConsoleAnalyser const &) = delete; | |
| ConsoleAnalyser &operator=(ConsoleAnalyser &) = delete; | |
| bool parse_options(); | |
| bool init_analyser(); | |
| private: | |
| static char constexpr STATEMENT_DELIMITER = '='; | |
| static char constexpr COMMAND_EXIT[] = "exit"; | |
| static char constexpr COMMAND_DISPLAY[] = "display"; | |
| static char constexpr COMMAND_SIMULATE[] = "simulate"; | |
| static char constexpr COMMAND_LOOP[] = "loop"; | |
| static char constexpr COMMAND_DUMP[] = "dump"; | |
| static bool loop_mode; | |
| bool parse_statement(std::string &line) const; | |
| void start_loop(); | |
| void handle_sigint(); | |
| bool _init; | |
| bool _parsed; | |
| NtsManager * const _manager; | |
| size_t const _argc; | |
| char ** _args; | |
| }; | |
| } | |
| #endif //UNTITLED3_CONSOLEANALYSER_H |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // | |
| // EPITECH PROJECT, 2018 | |
| // | |
| // File description: | |
| // | |
| // | |
| #include "Parser.hpp" | |
| #include "Exceptions.hpp" | |
| #include <iostream> | |
| #include <fstream> | |
| 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; | |
| default: | |
| break; | |
| } | |
| } | |
| if (_state != LINKS) | |
| throw ParsingError(("Section links not found")); | |
| _state = SUCCESS; | |
| } | |
| 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 false if only whitespaces | |
| } | |
| bool Parser::parse_chipsets(std::smatch &matcher, std::string &line) { | |
| 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 | |
| if (_chipsets.find(name) != _chipsets.end()) | |
| throw ParsingError("Found several chipsets with the same name"); | |
| auto chipset = _factory->createComponent(component, name); | |
| _chipsets[name] = std::move(chipset); | |
| 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 linked_name = matcher[1]; | |
| std::size_t linked_pin = parse_uint(matcher[2]); | |
| std::string linker_name = matcher[3]; | |
| std::size_t linker_pin = parse_uint(matcher[4]); | |
| auto linked = _chipsets.find(linked_name); | |
| auto linker = _chipsets.find(linker_name); | |
| if (linked == _chipsets.end() || linker == _chipsets.end()) | |
| throw ParsingError("Undefined reference name to a chipset"); | |
| linker->second->setLink(linker_pin, *(linked->second.get()), linked_pin); | |
| return true; | |
| } | |
| size_t Parser::parse_uint(std::string string) const { | |
| size_t uint; | |
| std::istringstream(string) >> uint; | |
| return uint; | |
| } | |
| bool Parser::successed() const { | |
| return _state == SUCCESS; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // | |
| // Created by romain on 01/03/2018. | |
| // | |
| #ifndef CPP_NANOTEKSPICE_HEADER_H | |
| #define CPP_NANOTEKSPICE_HEADER_H | |
| #include "ComponentFactory.hpp" | |
| #include "NtsManager.hpp" | |
| #include <regex> | |
| namespace nts | |
| { | |
| class Parser | |
| { | |
| public: | |
| Parser(ComponentFactory &factory, NtsManager &manager, std::string const &file) | |
| : _factory(&factory), _chipsets(manager.getComponents()), _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 | |
| * | |
| * @throws ParsingError if the file cant be parsed | |
| */ | |
| void run(); | |
| bool successed() const; | |
| 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); | |
| bool parse_links(std::smatch &matcher, std::string &line) const; | |
| size_t parse_uint(std::string string) const; | |
| enum ParserFunc { | |
| COMMENTS, | |
| CHIPSETS, | |
| LINKS, | |
| SUCCESS | |
| }; | |
| ComponentFactory *_factory; | |
| std::map<std::string, std::unique_ptr<IComponent>> &_chipsets; | |
| 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