diff options
-rw-r--r-- | Parser.cpp | 101 | ||||
-rw-r--r-- | Parser.h | 24 | ||||
-rw-r--r-- | circuits/full-adder.txt | 12 | ||||
-rw-r--r-- | main.cpp | 4 |
4 files changed, 124 insertions, 17 deletions
@@ -1,20 +1,105 @@ +#include <cstring> +#include <sstream> +#include <cstdarg> + #include "Parser.h" -void Parser::parse(string input) const { - std::cout << input << std::endl; +using std::getline; + +ParserException::ParserException(const char * fmt, ...) { + va_list args; + va_start(args, fmt); + size_t sz = vsnprintf(NULL, 0, fmt, args) + 1; + if (error != NULL) free(error); + error = (char *) malloc(sz); + vsnprintf(error, sz, fmt, args); + va_end(args); } -istream & Parser::parse(const Parser & parser, istream & s) const { - string temp(std::istreambuf_iterator<char>(s), {}); - parse(temp); - return s; +ParserException::~ParserException() { + if (error != NULL) + free(error); +} + +const char * ParserException::what() { + return error; +} + +size_t Parser::filter(char * input) { + size_t + len = strlen(input), + offset = 0, + i = 0; + + while (i < len) { + if(input[i] == '#') { + offset += len - i; + break; + } + + size_t skip = strspn(input + i, " \t\n"); + if (skip > 0) { + offset += skip; + i += skip; + continue; + } + + input[i - offset] = input[i]; + i++; + } + + input[len - offset] = '\0'; + return len - offset; +} + +void Parser::parse(istream & input) const { + unsigned linenum = 0; + string line_str; + while (getline(input, line_str)) { + linenum++; + char* line = line_str.data(); + size_t len = Parser::filter(line); + + if (len == 0) continue; // ignore empty lines + + char* label = strtok(line, ":"); + if (label == NULL) throw ParserException("syntax error on line %u", linenum); + + char* content = strtok(NULL, ";"); + if (content == NULL) throw ParserException("syntax error on line %u", linenum); + + vector<string> nodes; + while ((content = strtok(content, ",")) != NULL) { + nodes.push_back(content); + content = NULL; + } + + handle_line(label, nodes); + } +} + +void Parser::handle_line(string label, vector<string> nodes) const { + if (nodes.size() == 1) { + printf("node or net "); + } else { + printf("net "); + } + + printf("[%s]\n", label.c_str()); } istream & operator >> (istream & s, const Parser & parser) { - return parser.parse(parser, s); + parser.parse(s); + return s; } istream & operator << (const Parser & parser, istream & s) { - return parser.parse(parser, s); + parser.parse(s); + return s; +} + +void Parser::parse(string input) const { + std::istringstream s(input); + parse(s); } @@ -2,16 +2,38 @@ #include <iostream> #include <istream> +#include <exception> +#include <vector> using std::istream; using std::string; +using std::vector; + +class ParserException : public std::exception { +public: + ParserException(const char * fmt, ...); + ~ParserException(); + const char * what(); + +private: + char * error = NULL; +}; class Parser { public: void parse(string input) const; + void parse(istream & input) const; + + /** + * \brief preprocess (filter) line of input + * + * normalize whitespace and remove comments + */ + static size_t filter(char * input); + + void handle_line(string label, vector<string> nodes) const; private: - istream & parse(const Parser & parser, istream & s) const; friend istream & operator << (const Parser & parser, istream & s); friend istream & operator >> (istream & s, const Parser & parser); }; diff --git a/circuits/full-adder.txt b/circuits/full-adder.txt index d0c3854..9b85bc7 100644 --- a/circuits/full-adder.txt +++ b/circuits/full-adder.txt @@ -17,14 +17,14 @@ NODE9: AND; NODE10: AND; NODE11: OR; -Cin: NODE3,NODE7,NODE10; -A: NODE1,NODE2; -B: NODE1,NODE2; -NODE1: NODE3,NODE5; -NODE2: NODE4,NODE6; +Cin: NODE3, NODE7, NODE10; +A: NODE1, NODE2; +B: NODE1, NODE2; +NODE1: NODE3, NODE5; +NODE2: NODE4, NODE6; NODE3: NODE6; NODE4: NODE5; -NODE5: NODE8,NODE9; +NODE5: NODE8, NODE9; NODE6: Cout; NODE7: NODE9; NODE8: NODE10; @@ -22,14 +22,14 @@ int main(int argc, char** argv) { try { file >> main_parser; - } catch (exception e) { + } catch (ParserException & e) { cout << "Parser error: " << e.what() << endl; return EXIT_FAILURE; } // try { // circuit.run(); - // } catch (exception e) { + // } catch (exception& e) { // cout << "Circuit error: " << e.what() << endl; // return EXIT_FAILURE; // } |