[Lemon-commits] [lemon_svn] deba: r1426 - hugo/trunk/src/work/deba
Lemon SVN
svn at lemon.cs.elte.hu
Mon Nov 6 20:45:21 CET 2006
Author: deba
Date: Tue Dec 14 20:26:50 2004
New Revision: 1426
Added:
hugo/trunk/src/work/deba/test.cpp
Modified:
hugo/trunk/src/work/deba/graph_io_test.cc
hugo/trunk/src/work/deba/graph_reader.h
hugo/trunk/src/work/deba/test.lgf
Log:
reader under construction
Modified: hugo/trunk/src/work/deba/graph_io_test.cc
==============================================================================
--- hugo/trunk/src/work/deba/graph_io_test.cc (original)
+++ hugo/trunk/src/work/deba/graph_io_test.cc Tue Dec 14 20:26:50 2004
@@ -1,5 +1,5 @@
#include <lemon/smart_graph.h>
-#include <lemon/graph_reader.h>
+#include "graph_reader.h"
#include <iostream>
#include <fstream>
@@ -11,13 +11,30 @@
ifstream input("test.lgf");
SmartGraph graph;
GraphReader<SmartGraph> reader(input, graph);
+ SmartGraph::NodeMap<int> id(graph);
+ reader.readNodeMap("id", id);
SmartGraph::NodeMap<int> cost(graph);
reader.readNodeMap("cost", cost);
SmartGraph::NodeMap<string> color(graph);
reader.readNodeMap("color", color);
- reader.read();
+ SmartGraph::NodeMap<string> description(graph);
+ reader.readNodeMap<QuotedStringReader>("description", description);
+ SmartGraph::EdgeMap<char> mmap(graph);
+ reader.readEdgeMap("mmap", mmap);
+ reader.skipEdgeMap<QuotedStringReader>("description");
+ try {
+ reader.read();
+ } catch (IOException& e) {
+ cerr << e.what() << endl;
+ } catch (Exception e) {
+ cerr << e.what() << endl;
+ }
for (SmartGraph::NodeIt it(graph); it != INVALID; ++it) {
- cout << cost[it] << color[it] << endl;
+ cout << cost[it] << ' ' << color[it] << ' ' << description[it] << endl;
+ }
+
+ for (SmartGraph::EdgeIt it(graph); it != INVALID; ++it) {
+ cout << mmap[it] << ' ' << id[graph.source(it)] << ' ' << id[graph.target(it)] << endl;
}
return 0;
}
Modified: hugo/trunk/src/work/deba/graph_reader.h
==============================================================================
--- hugo/trunk/src/work/deba/graph_reader.h (original)
+++ hugo/trunk/src/work/deba/graph_reader.h Tue Dec 14 20:26:50 2004
@@ -16,7 +16,7 @@
///\ingroup gio
///\file
-///\brief Map utilities.
+///\brief Graph reader.
#include <iostream>
#include <sstream>
@@ -30,6 +30,34 @@
namespace lemon {
+
+ // Exceptions
+
+ class IOException {
+ public:
+ virtual string what() const = 0;
+ };
+
+ class DataFormatException : public IOException {
+ std::string message;
+ public:
+ DataFormatException(const std::string& _message)
+ : message(_message) {}
+ std::string what() const {
+ return "DataFormatException: " + message;
+ }
+ };
+
+ class StreamException : public IOException {
+ public:
+ virtual int line() = 0;
+ private:
+ IOException* exception;
+ int line_num;
+ };
+
+
+ // Readers and ReaderTraits
struct DefaultReaderTraits {
@@ -37,36 +65,109 @@
struct Reader {
typedef _Value Value;
void read(std::istream& is, Value& value) {
- is >> value;
+ if (!(is >> value))
+ throw DataFormatException("Default Reader format exception");
}
};
- template <typename _Value>
- struct Skipper {
- typedef _Value Value;
- void read(std::istream& is) {
- Value tmp;
- is >> tmp;
- }
- };
+ typedef Reader<std::string> DefaultReader;
- struct DefaultSkipper {
- void read(std::istream& is) {
- std::string tmp;
- is >> tmp;
- }
- };
};
- class IOException {
- virtual string message() = 0;
- };
+ class QuotedStringReader {
+ public:
+ typedef std::string Value;
+
+ QuotedStringReader(bool _escaped = true) : escaped(_escaped) {}
+
+ void read(std::istream& is, std::string& value) {
+ char c;
+ value.clear();
+ is >> ws;
+ if (!is.get(c) || c != '\"') throw DataFormatException("Quoted string format exception");
+ while (is.get(c) && c != '\"') {
+ if (escaped && c == '\\') {
+ value += readEscape(is);
+ } else {
+ value += c;
+ }
+ }
+ if (!is) throw DataFormatException("Quoted string format exception");
+ }
+
+ private:
+
+ static char readEscape(std::istream& is) {
+ char c;
+ switch (is.get(c), c) {
+ case '\\':
+ return '\\';
+ case '\"':
+ return '\"';
+ case '\'':
+ return '\'';
+ case '\?':
+ return '\?';
+ case 'a':
+ return '\a';
+ case 'b':
+ return '\b';
+ case 'f':
+ return '\f';
+ case 'n':
+ return '\n';
+ case 'r':
+ return '\r';
+ case 't':
+ return '\t';
+ case 'v':
+ return '\v';
+ case 'x':
+ {
+ int code;
+ if (!is.get(c) || !isHex(c)) throw DataFormatException("Escape format exception");
+ else if (code = valueHex(c), !is.get(c) || !isHex(c)) is.putback(c);
+ else code = code * 16 + valueHex(c);
+ return code;
+ }
+ default:
+ {
+ int code;
+ if (!isOct(c)) throw DataFormatException("Escape format exception");
+ else if (code = valueOct(c), !is.get(c) || !isOct(c)) is.putback(c);
+ else if (code = code * 8 + valueOct(c), !is.get(c) || !isOct(c)) is.putback(c);
+ else code = code * 8 + valueOct(c);
+ return code;
+ }
+ }
+ }
+
+ static bool isOct(char c) {
+ return '0' <= c && c <='7';
+ }
+
+ static int valueOct(char c) {
+ return c - '0';
+ }
+
+ static bool isHex(char c) {
+ return ('0' <= c && c <= '9') || ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z');
+ }
+
+ static int valueHex(char c) {
+ if ('0' <= c && c <= '9') return c - '0';
+ if ('a' <= c && c <= 'z') return c - 'a' + 10;
+ return c - 'A' + 10;
+ }
- class FileReaderException {
- virtual int getLine() = 0;
+ bool escaped;
};
-
+
+
+
+
+ // Graph reader
template <typename _Graph, typename _ReaderTraits = DefaultReaderTraits>
class GraphReader {
@@ -78,83 +179,162 @@
typedef typename Graph::Edge Edge;
typedef _ReaderTraits ReaderTraits;
-
+ typedef typename ReaderTraits::DefaultReader DefaultReader;
+
+ GraphReader(istream& _is, Graph& _graph, const DefaultReader& _reader = DefaultReader())
+ : is(_is), graph(_graph), nodeSkipper(_reader), edgeSkipper(_reader) {}
+
- GraphReader(std::istream& _is, Graph& _graph) : is(_is), graph(_graph) {}
+ ~GraphReader() {
+
+ for (typename NodeReaders::iterator it = node_readers.begin(); it != node_readers.end(); ++it) {
+ delete it->second;
+ }
+
+ for (typename EdgeReaders::iterator it = edge_readers.begin(); it != edge_readers.end(); ++it) {
+ delete it->second;
+ }
+
+ }
template <typename Map>
- GraphReader& readNodeMap(std::string name, Map& map,
- const typename ReaderTraits::template Reader<typename Map::Value>& reader =
- typename ReaderTraits::template Reader<typename Map::Value>()) {
- return readNodeMap<Map, typename ReaderTraits::template Reader<typename Map::Value> >(name, map, reader);
+ GraphReader& readNodeMap(std::string name, Map& map) {
+ return readNodeMap<typename ReaderTraits::template Reader<typename Map::Value>, Map>(name, map);
}
- template <typename Map, typename Reader>
+ template <typename Reader, typename Map>
GraphReader& readNodeMap(std::string name, Map& map, const Reader& reader = Reader()) {
+ if (node_readers.find(name) != node_readers.end()) {
+ Exception e;
+ e << "Multiple read rule for node map: " << name;
+ throw e;
+ }
node_readers.insert(make_pair(name, new MapReader<Node, Map, Reader>(map, reader)));
return *this;
}
+ template <typename Reader>
+ GraphReader& skipNodeMap(std::string name, const Reader& reader = Reader()) {
+ if (node_readers.find(name) != node_readers.end()) {
+ Exception e;
+ e << "Multiple read rule for node map: " << name;
+ throw e;
+ }
+ node_readers.insert(make_pair(name, new SkipReader<Node, Reader>(reader)));
+ return *this;
+ }
+
template <typename Map>
- GraphReader& readEdgeMap(std::string name, Map& map,
- const typename ReaderTraits::template Reader<typename Map::Value>& reader =
- typename ReaderTraits::template Reader<typename Map::Value>()) {
- return readEdgeMap<Map, typename ReaderTraits::template Reader<typename Map::Value> >(name, map, reader);
+ GraphReader& readEdgeMap(std::string name, Map& map) {
+ return readEdgeMap<typename ReaderTraits::template Reader<typename Map::Value>, Map>(name, map);
}
- template <typename Map, typename Reader>
+
+ template <typename Reader, typename Map>
GraphReader& readEdgeMap(std::string name, Map& map, const Reader& reader = Reader()) {
+ if (edge_readers.find(name) != edge_readers.end()) {
+ Exception e;
+ e << "Multiple read rule for edge map: " << name;
+ throw e;
+ }
edge_readers.insert(make_pair(name, new MapReader<Edge, Map, Reader>(map, reader)));
return *this;
}
+ template <typename Reader>
+ GraphReader& skipEdgeMap(std::string name, const Reader& reader = Reader()) {
+ if (edge_readers.find(name) != edge_readers.end()) {
+ Exception e;
+ e << "Multiple read rule for edge map: " << name;
+ throw e;
+ }
+ edge_readers.insert(make_pair(name, new SkipReader<Edge, Reader>(reader)));
+ return *this;
+ }
+
void read() {
int line_num = 0;
- readNodeSet(line_num);
- readEdgeSet(line_num);
- {
- std::string line = readNotEmptyLine(is, line_num);
- }
+ InverterBase<Node>* nodeInverter = 0;
+ InverterBase<Edge>* edgeInverter = 0;
+ // \todo delete the inverters
+ // try {
+ {
+ std::string line = readNotEmptyLine(is, line_num);
+ }
+ readNodeSet(line_num, nodeInverter);
+ readEdgeSet(line_num, edgeInverter, nodeInverter);
+ // } catch (...){
+ if (nodeInverter != 0) delete nodeInverter;
+ if (edgeInverter != 0) delete edgeInverter;
+ // }
}
private:
- void readNodeSet(int& line_num) {
+ template <typename Item> class InverterBase;
+ // template <typename Item> class InverterBase;
+
+ void readNodeSet(int& line_num, InverterBase<Node>* & nodeInverter) {
int n = 0;
- {
- std::string line = readNotEmptyLine(is, line_num);
- }
- std::vector<MapReaderBase<Node>*> index;
+ std::vector<ReaderBase<Node>*> index;
{
std::string line = readNotEmptyLine(is, line_num);
std::string id;
std::istringstream ls(line);
while (ls >> id) {
- typename map<std::string, MapReaderBase<Node>* >::iterator it = node_readers.find(id);
+ if (id[0] == '#') break;
+ typename NodeReaders::iterator it = node_readers.find(id);
if (it != node_readers.end()) {
index.push_back(it->second);
} else {
- index.push_back(0);
+ index.push_back(&nodeSkipper);
}
++n;
}
}
+
+ nodeInverter = index[0]->getInverter();
std::string line;
while (line = readNotEmptyLine(is, line_num), line[0] != '@') {
Node node = graph.addNode();
std::istringstream ls(line);
- for (int i = 0; i < n; ++i) {
- if (index[i] != 0) {
- index[i]->read(ls, node);
- } else {
- default_skipper.read(ls);
- }
+ nodeInverter->read(ls, node);
+ for (int i = 1; i < n; ++i) {
+ index[i]->read(ls, node);
}
}
}
- void readEdgeSet(int& line_num) {
-
+ void readEdgeSet(int& line_num, InverterBase<Edge>* & edgeInverter, InverterBase<Node>* & nodeInverter) {
+ int n = 0;
+ std::vector<ReaderBase<Edge>*> index;
+ {
+ std::string line = readNotEmptyLine(is, line_num);
+ std::string id;
+ std::istringstream ls(line);
+ while (ls >> id) {
+ if (id[0] == '#') break;
+ typename EdgeReaders::iterator it = edge_readers.find(id);
+ if (it != edge_readers.end()) {
+ index.push_back(it->second);
+ } else {
+ index.push_back(&edgeSkipper);
+ }
+ ++n;
+ }
+ }
+ edgeInverter = index[0]->getInverter();
+ std::string line;
+ while (line = readNotEmptyLine(is, line_num), line[0] != '@') {
+ std::istringstream ls(line);
+ Node source = nodeInverter->read(ls);
+ Node target = nodeInverter->read(ls);
+ Edge edge = graph.addEdge(source, target);
+ edgeInverter->read(ls, edge);
+ for (int i = 1; i < n; ++i) {
+ index[i]->read(ls, edge);
+ }
+ }
}
std::string readNotEmptyLine(std::istream& is, int& line_num) {
@@ -168,23 +348,107 @@
throw Exception();
}
- istream& is;
- Graph& graph;
+ template <typename _Item>
+ class InverterBase {
+ public:
+ typedef _Item Item;
+ virtual void read(istream&, const Item&) = 0;
+ virtual Item read(istream&) = 0;
+ };
+
+ template <typename _Item, typename _Map, typename _Reader>
+ class MapReaderInverter : public InverterBase<_Item> {
+ public:
+ typedef _Item Item;
+ typedef _Reader Reader;
+ typedef typename Reader::Value Value;
+ typedef _Map Map;
+ typedef std::map<Value, Item> Inverse;
+
+ Map& map;
+ Reader reader;
+ Inverse inverse;
+
+ MapReaderInverter(Map& _map, const Reader& _reader)
+ : map(_map), reader(_reader) {}
+
+ virtual void read(istream& is, const Item& item) {
+ Value value;
+ reader.read(is, value);
+ map.set(item, value);
+ typename Inverse::iterator it = inverse.find(value);
+ if (it == inverse.end()) {
+ inverse.insert(make_pair(value, item));
+ } else {
+ throw DataFormatException("Multiple ID occurence");
+ }
+ }
+
+ virtual Item read(istream& is) {
+ Value value;
+ reader.read(is, value);
+ typename Inverse::const_iterator it = inverse.find(value);
+ if (it != inverse.end()) {
+ return it->second;
+ } else {
+ throw DataFormatException("Invalid ID");
+ }
+ }
+ };
+
+ template <typename _Item, typename _Reader>
+ class SkipReaderInverter : public InverterBase<_Item> {
+ public:
+ typedef _Item Item;
+ typedef _Reader Reader;
+ typedef typename Reader::Value Value;
+ typedef std::map<Value, Item> Inverse;
+
+ Reader reader;
+
+ SkipReaderInverter(const Reader& _reader)
+ : reader(_reader) {}
+
+ virtual void read(istream& is, const Item& item) {
+ Value value;
+ reader.read(is, value);
+ typename Inverse::iterator it = inverse.find(value);
+ if (it == inverse.end()) {
+ inverse.insert(make_pair(value, item));
+ } else {
+ throw DataFormatException("Multiple ID occurence");
+ }
+ }
+
+ virtual Item read(istream& is) {
+ Value value;
+ reader.read(is, value);
+ typename Inverse::const_iterator it = inverse.find(value);
+ if (it != inverse.end()) {
+ return it->second;
+ } else {
+ throw DataFormatException("Invalid ID");
+ }
+ }
+ private:
+ Inverse inverse;
+ };
- typename ReaderTraits::DefaultSkipper default_skipper;
template <typename _Item>
- class MapReaderBase {
+ class ReaderBase {
public:
typedef _Item Item;
virtual void read(istream& is, const Item& item) = 0;
+ virtual InverterBase<_Item>* getInverter() = 0;
};
-
+
template <typename _Item, typename _Map, typename _Reader>
- class MapReader : public MapReaderBase<_Item> {
+ class MapReader : public ReaderBase<_Item> {
public:
typedef _Map Map;
typedef _Reader Reader;
+ typedef typename Reader::Value Value;
typedef _Item Item;
Map& map;
@@ -195,18 +459,50 @@
virtual void read(istream& is, const Item& item) {
- typename Reader::Value value;
+ Value value;
reader.read(is, value);
map.set(item, value);
}
+
+ virtual InverterBase<_Item>* getInverter() {
+ return new MapReaderInverter<Item, Map, Reader>(map, reader);
+ }
};
- typedef std::map<std::string, MapReaderBase<Node>* > NodeReaders;
+
+ template <typename _Item, typename _Reader>
+ class SkipReader : public ReaderBase<_Item> {
+ public:
+ typedef _Reader Reader;
+ typedef typename Reader::Value Value;
+ typedef _Item Item;
+
+ Reader reader;
+ SkipReader(const Reader& _reader) : reader(_reader) {}
+
+ virtual void read(istream& is, const Item& item) {
+ Value value;
+ reader.read(is, value);
+ }
+
+ virtual InverterBase<Item>* getInverter() {
+ return new SkipReaderInverter<Item, Reader>(reader);
+ }
+ };
+
+
+ typedef std::map<std::string, ReaderBase<Node>* > NodeReaders;
NodeReaders node_readers;
- typedef std::map<std::string, MapReaderBase<Edge>* > EdgeReaders;
+ typedef std::map<std::string, ReaderBase<Edge>* > EdgeReaders;
EdgeReaders edge_readers;
+ std::istream& is;
+ Graph& graph;
+
+ SkipReader<Node, DefaultReader> nodeSkipper;
+ SkipReader<Edge, DefaultReader> edgeSkipper;
+
};
}
Added: hugo/trunk/src/work/deba/test.cpp
==============================================================================
--- (empty file)
+++ hugo/trunk/src/work/deba/test.cpp Tue Dec 14 20:26:50 2004
@@ -0,0 +1,51 @@
+#include <iostream>
+
+using namespace std;
+
+
+struct _EmptyList {
+ void write() const {}
+};
+
+template <typename _Item, typename _Next>
+struct _AddNode {
+ typedef _Next Next;
+ typedef _Item Item;
+
+ const Item item;
+ const Next& next;
+
+ _AddNode(const Item& _item, const Next& _next)
+ : item(_item), next(_next) {}
+
+ void write() const {
+ next.write();
+ cout << item << ' ';
+ }
+};
+
+template <typename _List = _EmptyList>
+struct _Writer {
+ typedef _List List;
+
+ const List list;
+
+ _Writer(const List& _list = List()) : list(_list) {}
+
+
+ template <typename Item> _Writer<_AddNode<Item, List> > add(Item item) const {
+ return _Writer<_AddNode<Item, List> >(_AddNode<Item, List>(item, list));
+ }
+
+ void write() const {
+ list.write();
+ cout << endl;
+ }
+};
+
+
+typedef _Writer<> Writer;
+
+int main() {
+ Writer().add(3).add("alpha").add(4.53).write();
+}
Modified: hugo/trunk/src/work/deba/test.lgf
==============================================================================
--- hugo/trunk/src/work/deba/test.lgf (original)
+++ hugo/trunk/src/work/deba/test.lgf Tue Dec 14 20:26:50 2004
@@ -1,30 +1,36 @@
+ at nodeset
+id cost color description mmap
+1 1 green "A -> B \t: 10" a
+2 2 blue "A -> B \t: 10" b
+# hatalom dicsoseg "A -> B \t: 10" c
+3 1 red "A -> B \t: 10" d #adjkhj
+4 2 red "A -> B \t: 10" e
+5 1 green "A -> B \t: 10" f
+10 1 green "A -> B \t: 10" g
+ # hello - bello csucsok "A -> B \t: 10"
+6 2 blue "A -> B \t: 10" h
+7 1 blue "A -> B \t: 10" i
+8 2 red "A -> B \t: 10" j
+9 1 green "A -> B \t: 10" k
- at nodes
+ at edgeset
+ id weight description mmap
+1 4 1 10 "A -> B \t: 101" a
+3 5 5 29 "A -> B \t: 10q" b
+3 4 2 92 "A -> B \t: 10a" c
+2 3 6 92 "A -> B \t: 10d" d
+9 5 9 49 "A -> B \t: 10c" e
+10 4 3 40 "A -> B \t: 10v" f
+1 3 8 84 "A -> B \t: 10g" g
+6 7 4 83 "A -> B \t: 10h" h
+8 9 7 37 "A -> B \t: 10j" i
+7 8 10 12 "A -> B \t: 10g" j
-id cost color
+ at nodes
+source 1
+target 7
-1 1 green
-2 2 blue
-# hatalom dicsoseg
-3 1 red
-4 2 red
-5 1 green
-10 1 green # ez nem egy igazan jo sor
- # hello - bello csucsok
-6 2 blue
-7 1 blue
-8 2 red
-9 1 green
@edges
-source target weight
-1 4 10
-3 5 29
-3 4 92
-2 3 92
-9 5 49
-10 4 40
-1 3 84
-6 7 83
-8 9 37
-7 8 89
+newedge 7
+
@end
More information about the Lemon-commits
mailing list