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
}