lexer.h #ifndef LEXER_H #define LEXER_H #include #include using namespace std; enum TokenKind { ident, number, text, separator, eos }; class Lexer { private: ifstream f; char ch; void nextChar (); public: TokenKind kind; string token; void nextToken (); void error (string msg); bool isSeparator (char c); void checkSeparator (char c); string readIdent (); public: Lexer (string fileName); }; #endif // LEXER_H lexer.cpp #include "lexer.h" #include // cout const char zero = 0; Lexer::Lexer (string fileName) { f.open (fileName); if (! f.good ()) error ("Cannot open file: " + fileName); ch = zero; nextChar (); nextToken (); } void Lexer::error (string msg) { cout << "Error: " << msg << endl; exit (1); } void Lexer::nextChar() { f >> ch; if (! f.good ()) ch = zero; } void Lexer::nextToken() { token = ""; while (ch != zero && ch <= ' ') nextChar (); if (ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z') { kind = ident; while (ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z') { token = token + ch; nextChar (); } } else if (ch >= '0' && ch <= '9') { kind = number; while (ch >= '0' && ch <= '9') { token = token + ch; nextChar (); } } else if (ch != zero) { kind = separator; token = string (1, ch); nextChar (); } else { kind = eos; } } bool Lexer::isSeparator (char c) { return kind==separator && token==string(1, c); } void Lexer::checkSeparator(char c) { if (!isSeparator(c)) error(string (1,c)+" expected"); nextToken(); } string Lexer:: readIdent () { if (kind!=ident) error("Identifire expected."); string result = token; nextToken(); return result; } list.h #ifndef LIST_H #define LIST_H #include using namespace std; class Item; // double sqr (double x) { return x*x; } class List { private: Item * first; Item * last; public: Item * getFirst () { return first; } Item * getLast () { return last; } public: List (); // konstruktor ~ List (); // destruktor void insertFirst (string name0); void insertLast (string name0); void linkFirst (Item * p); void linkLast (Item * p); void linkBefore (Item * old, Item * p); // vloz p pred old void linkAfter (Item * old, Item * p); // vloz p za old void unlink (Item * p); // odpoj p ze seznamu void print (); void insert (string name0); void move (List & target); // presunout vsechny prvky z this do target void transfer (List & source); // presunout vsechny prvky ze source do this void reverse (); private: void link (Item * a, Item * b, Item * c); // pripoj b v poradi a, b, c // b novy, zatim neni v senamu // a predchudce, muze byt nulovy // c naslednik, muze byt nulovy }; class Item { private: string name; List * owner; Item * prev; Item * next; public: string getName () { return name; } Item * getPrev () { return prev; } Item * getNext () { return next; } public: Item (string name0 = ""); friend class List; }; #endif // LIST_H list.cpp #include "list.h" // #include #include #include using namespace std; List::List() : first (nullptr), last (nullptr) { } Item::Item (string name0) : name (name0), owner (nullptr), prev (nullptr), next (nullptr) { } void List::insertFirst (string name0) { linkFirst ( new Item (name0) ); } void List::insertLast (string name0) { // Item * p = new Item; // p->name = name0; Item * p = new Item (name0); linkLast (p); } void List::linkFirst(Item *p) { link (nullptr, p, first); } void List::linkLast(Item *p) { link (last, p, nullptr); } void List::linkBefore (Item *old, Item *p) // vloz p pred old { assert (old != nullptr); link (old->prev, p, old); } void List::linkAfter(Item *old, Item *p) // vloz p za old { assert (old != nullptr); link (old, p, old->next); } void List::link(Item *a, Item *b, Item *c) { // #include assert (b != nullptr); assert (b->owner == nullptr); b->owner = this; assert (a == nullptr || a->owner == this); assert (c == nullptr || c->owner == this); b->prev = a; b->next = c; if (a != nullptr) a->next = b; else first = b; if (c != nullptr) c->prev = b; else last = b; } void List::unlink (Item *p) { assert (p != nullptr); assert (p->owner == this); Item * a = p->prev; Item * c = p->next; if (a != nullptr) a->next = c; // mame predchudce, muzeme propojit else first = c; // nemame predchudce, naslednik se stava prvnim if (c != nullptr) c->prev = a; else last = a; p->owner = nullptr; p->prev = nullptr; p->next = nullptr; } List::~List() { Item * p = first; while (p != nullptr) { Item * t = p->next; unlink (p); // cout << "Mazeme " << p->name << endl; delete p; p = t; } } void List::move (List & target) { Item * p = first; while (p != nullptr) { Item * t = p->next; unlink (p); target.linkLast (p); p = t; } } void List::transfer (List & source) { Item * p = source.first; while (p != nullptr) { Item * t = p->next; source.unlink (p); linkLast (p); p = t; } } void List::reverse () { List target; Item * p = first; while (p != nullptr) { Item * t = p->next; unlink (p); target.linkFirst (p); p = t; } target.move (*this); } void List::print () { // #include cout << "[" << endl; Item * p = first; while (p != nullptr) { cout << p->name << endl; p = p->next; } cout << "]" << endl << endl; } void List::insert (string name0) { Item * t = first; while (t != nullptr && t->name <= name0) t = t->next; Item * p = new Item (name0); if (t != nullptr) linkBefore (t, p); else linkLast (p); } main.cpp #include #include "lexer.h" #include "list.h" using namespace std; int main() { List a; Lexer f ("../lexer/abc.txt"); f.checkSeparator('{'); if (! f.isSeparator('}')) { a.insertLast (f.readIdent ()); while (f.isSeparator (',')) { f.nextToken (); a.insertLast (f.readIdent ()); } } f.checkSeparator('}'); a.print(); return 0; } { selmy , lichopytnici, sudokopytnici }