reader under construction
authordeba
Tue, 14 Dec 2004 19:26:50 +0000
changeset 10362f514b5c7122
parent 1035 f2a3426e64e6
child 1037 3eaff8d04171
reader under construction
src/work/deba/graph_io_test.cc
src/work/deba/graph_reader.h
src/work/deba/test.cpp
src/work/deba/test.lgf
     1.1 --- a/src/work/deba/graph_io_test.cc	Thu Dec 09 17:02:53 2004 +0000
     1.2 +++ b/src/work/deba/graph_io_test.cc	Tue Dec 14 19:26:50 2004 +0000
     1.3 @@ -1,5 +1,5 @@
     1.4  #include <lemon/smart_graph.h>
     1.5 -#include <lemon/graph_reader.h>
     1.6 +#include "graph_reader.h"
     1.7  
     1.8  #include <iostream>
     1.9  #include <fstream>
    1.10 @@ -11,13 +11,30 @@
    1.11    ifstream input("test.lgf");
    1.12    SmartGraph graph;
    1.13    GraphReader<SmartGraph> reader(input, graph);
    1.14 +  SmartGraph::NodeMap<int> id(graph);
    1.15 +  reader.readNodeMap("id", id);
    1.16    SmartGraph::NodeMap<int> cost(graph);
    1.17    reader.readNodeMap("cost", cost);
    1.18    SmartGraph::NodeMap<string> color(graph);
    1.19    reader.readNodeMap("color", color);
    1.20 -  reader.read();
    1.21 +  SmartGraph::NodeMap<string> description(graph);
    1.22 +  reader.readNodeMap<QuotedStringReader>("description", description);
    1.23 +  SmartGraph::EdgeMap<char> mmap(graph);
    1.24 +  reader.readEdgeMap("mmap", mmap);
    1.25 +  reader.skipEdgeMap<QuotedStringReader>("description");
    1.26 +  try {
    1.27 +    reader.read();
    1.28 +  } catch (IOException& e) {
    1.29 +    cerr << e.what() << endl;
    1.30 +  } catch (Exception e) {
    1.31 +    cerr << e.what() << endl;
    1.32 +  }
    1.33    for (SmartGraph::NodeIt it(graph); it != INVALID; ++it) {
    1.34 -    cout << cost[it] << color[it] << endl;
    1.35 +    cout << cost[it] << ' ' << color[it] << ' ' << description[it] << endl;
    1.36 +  }
    1.37 +
    1.38 +  for (SmartGraph::EdgeIt it(graph); it != INVALID; ++it) {
    1.39 +    cout << mmap[it] << ' ' << id[graph.source(it)] << ' ' << id[graph.target(it)]  << endl;
    1.40    }
    1.41    return 0;
    1.42  }
     2.1 --- a/src/work/deba/graph_reader.h	Thu Dec 09 17:02:53 2004 +0000
     2.2 +++ b/src/work/deba/graph_reader.h	Tue Dec 14 19:26:50 2004 +0000
     2.3 @@ -16,7 +16,7 @@
     2.4  
     2.5  ///\ingroup gio
     2.6  ///\file
     2.7 -///\brief Map utilities.
     2.8 +///\brief Graph reader.
     2.9  
    2.10  #include <iostream>
    2.11  #include <sstream>
    2.12 @@ -30,6 +30,34 @@
    2.13  
    2.14  
    2.15  namespace lemon {
    2.16 +
    2.17 +  // Exceptions
    2.18 +
    2.19 +  class IOException {
    2.20 +  public:
    2.21 +    virtual string what() const = 0;
    2.22 +  };
    2.23 +
    2.24 +  class DataFormatException : public IOException {
    2.25 +    std::string message;
    2.26 +  public:
    2.27 +    DataFormatException(const std::string& _message) 
    2.28 +      : message(_message) {}
    2.29 +    std::string what() const {
    2.30 +      return "DataFormatException: " + message; 
    2.31 +    }
    2.32 +  };
    2.33 +
    2.34 +  class StreamException : public IOException {
    2.35 +  public:
    2.36 +    virtual int line() = 0;
    2.37 +  private:
    2.38 +    IOException* exception;
    2.39 +    int line_num;
    2.40 +  };  
    2.41 +
    2.42 +
    2.43 +  // Readers and ReaderTraits
    2.44    
    2.45    struct DefaultReaderTraits {
    2.46  
    2.47 @@ -37,36 +65,109 @@
    2.48      struct Reader {
    2.49        typedef _Value Value;
    2.50        void read(std::istream& is, Value& value) {
    2.51 -	is >> value;
    2.52 +	if (!(is >> value)) 
    2.53 +	  throw DataFormatException("Default Reader format exception");
    2.54        }
    2.55      };
    2.56  
    2.57 -    template <typename _Value>
    2.58 -    struct Skipper {
    2.59 -      typedef _Value Value;
    2.60 -      void read(std::istream& is) {
    2.61 -	Value tmp;
    2.62 -	is >> tmp;
    2.63 -      }      
    2.64 -    };
    2.65 +    typedef Reader<std::string> DefaultReader;
    2.66  
    2.67 -    struct DefaultSkipper {
    2.68 -      void read(std::istream& is) {
    2.69 -	std::string tmp;
    2.70 -	is >> tmp;
    2.71 -      }
    2.72 -    };
    2.73    };
    2.74  
    2.75 -  class IOException {
    2.76 -    virtual string message() = 0;
    2.77 +  class QuotedStringReader {
    2.78 +  public:
    2.79 +    typedef std::string Value;
    2.80 +
    2.81 +    QuotedStringReader(bool _escaped = true) : escaped(_escaped) {}
    2.82 +
    2.83 +    void read(std::istream& is, std::string& value) {
    2.84 +      char c;
    2.85 +      value.clear();
    2.86 +      is >> ws;
    2.87 +      if (!is.get(c) || c != '\"') throw DataFormatException("Quoted string format exception");
    2.88 +      while (is.get(c) && c != '\"') {
    2.89 +	if (escaped && c == '\\') {
    2.90 +	  value += readEscape(is);
    2.91 +	} else {
    2.92 +	  value += c;
    2.93 +	}
    2.94 +      }
    2.95 +      if (!is) throw DataFormatException("Quoted string format exception");
    2.96 +    }
    2.97 +
    2.98 +  private:
    2.99 +    
   2.100 +    static char readEscape(std::istream& is) {
   2.101 +      char c;
   2.102 +      switch (is.get(c), c) {
   2.103 +      case '\\':
   2.104 +	return '\\';
   2.105 +      case '\"':
   2.106 +	return '\"';
   2.107 +      case '\'':
   2.108 +	return '\'';
   2.109 +      case '\?':
   2.110 +	return '\?';
   2.111 +      case 'a':
   2.112 +	return '\a';
   2.113 +      case 'b':
   2.114 +	return '\b';
   2.115 +      case 'f':
   2.116 +	return '\f';
   2.117 +      case 'n':
   2.118 +	return '\n';
   2.119 +      case 'r':
   2.120 +	return '\r';
   2.121 +      case 't':
   2.122 +	return '\t';
   2.123 +      case 'v':
   2.124 +	return '\v';
   2.125 +      case 'x':
   2.126 +	{
   2.127 +	  int code;
   2.128 +	  if (!is.get(c) || !isHex(c)) throw DataFormatException("Escape format exception");
   2.129 +	  else if (code = valueHex(c), !is.get(c) || !isHex(c)) is.putback(c);
   2.130 +	  else code = code * 16 + valueHex(c);
   2.131 +	  return code;
   2.132 +	}
   2.133 +      default:
   2.134 +	{
   2.135 +	  int code;
   2.136 +	  if (!isOct(c)) throw DataFormatException("Escape format exception");
   2.137 +	  else if (code = valueOct(c), !is.get(c) || !isOct(c)) is.putback(c);
   2.138 +	  else if (code = code * 8 + valueOct(c), !is.get(c) || !isOct(c)) is.putback(c);
   2.139 +	  else code = code * 8 + valueOct(c);
   2.140 +	  return code;
   2.141 +	}	      
   2.142 +      } 
   2.143 +    }
   2.144 +
   2.145 +    static bool isOct(char c) {
   2.146 +      return '0' <= c && c <='7'; 
   2.147 +    }
   2.148 +    
   2.149 +    static int valueOct(char c) {
   2.150 +      return c - '0';
   2.151 +    }
   2.152 +
   2.153 +   static bool isHex(char c) {
   2.154 +      return ('0' <= c && c <= '9') || ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z'); 
   2.155 +    }
   2.156 +    
   2.157 +    static int valueHex(char c) {
   2.158 +      if ('0' <= c && c <= '9') return c - '0';
   2.159 +      if ('a' <= c && c <= 'z') return c - 'a' + 10;
   2.160 +      return c - 'A' + 10;
   2.161 +    }
   2.162 +
   2.163 +    bool escaped;
   2.164    };
   2.165  
   2.166 -  class FileReaderException {
   2.167 -    virtual int getLine() = 0;    
   2.168 -  };
   2.169  
   2.170 -  
   2.171 +
   2.172 +
   2.173 +
   2.174 +  // Graph reader
   2.175    
   2.176    template <typename _Graph, typename _ReaderTraits = DefaultReaderTraits> 
   2.177    class GraphReader {
   2.178 @@ -78,83 +179,162 @@
   2.179      typedef typename Graph::Edge Edge;
   2.180  
   2.181      typedef _ReaderTraits ReaderTraits;
   2.182 -    
   2.183 +    typedef typename ReaderTraits::DefaultReader DefaultReader;
   2.184  
   2.185 -    GraphReader(std::istream& _is, Graph& _graph) : is(_is), graph(_graph) {}
   2.186 +    GraphReader(istream& _is, Graph& _graph, const DefaultReader& _reader = DefaultReader()) 
   2.187 +      : is(_is), graph(_graph), nodeSkipper(_reader), edgeSkipper(_reader) {}
   2.188 +
   2.189 +
   2.190 +    ~GraphReader() {
   2.191 +
   2.192 +      for (typename NodeReaders::iterator it = node_readers.begin(); it != node_readers.end(); ++it) {
   2.193 +	delete it->second;
   2.194 +      }
   2.195 +
   2.196 +      for (typename EdgeReaders::iterator it = edge_readers.begin(); it != edge_readers.end(); ++it) {
   2.197 +	delete it->second;
   2.198 +      }
   2.199 +
   2.200 +    }
   2.201  
   2.202      template <typename Map>
   2.203 -    GraphReader& readNodeMap(std::string name, Map& map, 
   2.204 -			     const typename ReaderTraits::template Reader<typename Map::Value>& reader =
   2.205 -			     typename ReaderTraits::template Reader<typename Map::Value>()) {
   2.206 -      return readNodeMap<Map, typename ReaderTraits::template Reader<typename Map::Value> >(name, map, reader);
   2.207 +    GraphReader& readNodeMap(std::string name, Map& map) {
   2.208 +      return readNodeMap<typename ReaderTraits::template Reader<typename Map::Value>, Map>(name, map);
   2.209      }
   2.210  
   2.211 -    template <typename Map, typename Reader>
   2.212 +    template <typename Reader, typename Map>
   2.213      GraphReader& readNodeMap(std::string name, Map& map, const Reader& reader = Reader()) {
   2.214 +      if (node_readers.find(name) != node_readers.end()) {
   2.215 +	Exception e;
   2.216 +	e << "Multiple read rule for node map: " << name;
   2.217 +	throw e;
   2.218 +      }
   2.219        node_readers.insert(make_pair(name, new MapReader<Node, Map, Reader>(map, reader)));
   2.220        return *this;
   2.221      }
   2.222  
   2.223 -    template <typename Map>
   2.224 -    GraphReader& readEdgeMap(std::string name, Map& map, 
   2.225 -			     const typename ReaderTraits::template Reader<typename Map::Value>& reader =
   2.226 -			     typename ReaderTraits::template Reader<typename Map::Value>()) {
   2.227 -      return readEdgeMap<Map, typename ReaderTraits::template Reader<typename Map::Value> >(name, map, reader);
   2.228 +    template <typename Reader>
   2.229 +    GraphReader& skipNodeMap(std::string name, const Reader& reader = Reader()) {
   2.230 +      if (node_readers.find(name) != node_readers.end()) {
   2.231 +	Exception e;
   2.232 +	e << "Multiple read rule for node map: " << name;
   2.233 +	throw e;
   2.234 +      }
   2.235 +      node_readers.insert(make_pair(name, new SkipReader<Node, Reader>(reader)));
   2.236 +      return *this;
   2.237      }
   2.238  
   2.239 -    template <typename Map, typename Reader>
   2.240 +    template <typename Map>
   2.241 +    GraphReader& readEdgeMap(std::string name, Map& map) { 
   2.242 +      return readEdgeMap<typename ReaderTraits::template Reader<typename Map::Value>, Map>(name, map);
   2.243 +    }
   2.244 +
   2.245 +
   2.246 +    template <typename Reader, typename Map>
   2.247      GraphReader& readEdgeMap(std::string name, Map& map, const Reader& reader = Reader()) {
   2.248 +      if (edge_readers.find(name) != edge_readers.end()) {
   2.249 +	Exception e;
   2.250 +	e << "Multiple read rule for edge map: " << name;
   2.251 +	throw e;
   2.252 +      }
   2.253        edge_readers.insert(make_pair(name, new MapReader<Edge, Map, Reader>(map, reader)));
   2.254        return *this;
   2.255      }
   2.256  
   2.257 +    template <typename Reader>
   2.258 +    GraphReader& skipEdgeMap(std::string name, const Reader& reader = Reader()) {
   2.259 +      if (edge_readers.find(name) != edge_readers.end()) {
   2.260 +	Exception e;
   2.261 +	e << "Multiple read rule for edge map: " << name;
   2.262 +	throw e;
   2.263 +      }
   2.264 +      edge_readers.insert(make_pair(name, new SkipReader<Edge, Reader>(reader)));
   2.265 +      return *this;
   2.266 +    }
   2.267 +
   2.268      void read() {
   2.269        int line_num = 0;
   2.270 -      readNodeSet(line_num);
   2.271 -      readEdgeSet(line_num);
   2.272 -      {
   2.273 -	std::string line = readNotEmptyLine(is, line_num);
   2.274 -      }
   2.275 +      InverterBase<Node>* nodeInverter = 0;
   2.276 +      InverterBase<Edge>* edgeInverter = 0;
   2.277 +      // \todo delete the inverters
   2.278 +      //      try {
   2.279 +	{
   2.280 +	  std::string line = readNotEmptyLine(is, line_num);
   2.281 +	}
   2.282 +	readNodeSet(line_num, nodeInverter);
   2.283 +	readEdgeSet(line_num, edgeInverter, nodeInverter);
   2.284 +	//      } catch (...){
   2.285 +	if (nodeInverter != 0) delete nodeInverter;
   2.286 +	if (edgeInverter != 0) delete edgeInverter;
   2.287 +	//      }
   2.288      }
   2.289  
   2.290    private:
   2.291  
   2.292 -    void readNodeSet(int& line_num) {
   2.293 +    template <typename Item> class InverterBase;
   2.294 +    //    template <typename Item> class InverterBase;
   2.295 +
   2.296 +    void readNodeSet(int& line_num, InverterBase<Node>* & nodeInverter) {
   2.297        int n = 0;
   2.298 -      {
   2.299 -	std::string line = readNotEmptyLine(is, line_num);	
   2.300 -      }
   2.301 -      std::vector<MapReaderBase<Node>*> index;
   2.302 +      std::vector<ReaderBase<Node>*> index;
   2.303        {
   2.304  	std::string line = readNotEmptyLine(is, line_num);    
   2.305  	std::string id;
   2.306  	std::istringstream ls(line);	
   2.307  	while (ls >> id) {
   2.308 -	  typename map<std::string, MapReaderBase<Node>* >::iterator it = node_readers.find(id);
   2.309 +	  if (id[0] == '#') break;
   2.310 +	  typename NodeReaders::iterator it = node_readers.find(id);
   2.311  	  if (it != node_readers.end()) {
   2.312  	    index.push_back(it->second);
   2.313  	  } else {
   2.314 -	    index.push_back(0);
   2.315 +	    index.push_back(&nodeSkipper);
   2.316  	  }
   2.317  	  ++n;
   2.318  	}
   2.319        }
   2.320 +
   2.321 +      nodeInverter = index[0]->getInverter();
   2.322        std::string line;
   2.323        while (line = readNotEmptyLine(is, line_num), line[0] != '@') {
   2.324  	Node node = graph.addNode();
   2.325  	std::istringstream ls(line);
   2.326 -	for (int i = 0; i < n; ++i) {
   2.327 -	  if (index[i] != 0) {	    
   2.328 -	    index[i]->read(ls, node);
   2.329 -	  } else {
   2.330 -	    default_skipper.read(ls);
   2.331 -	  }
   2.332 +	nodeInverter->read(ls, node);
   2.333 +	for (int i = 1; i < n; ++i) {
   2.334 +	  index[i]->read(ls, node);
   2.335  	}
   2.336        }
   2.337      }
   2.338  
   2.339 -    void readEdgeSet(int& line_num) {
   2.340 -      
   2.341 +    void readEdgeSet(int& line_num, InverterBase<Edge>* & edgeInverter, InverterBase<Node>* & nodeInverter) {
   2.342 +      int n = 0;
   2.343 +      std::vector<ReaderBase<Edge>*> index;
   2.344 +      {
   2.345 +	std::string line = readNotEmptyLine(is, line_num);    
   2.346 +	std::string id;
   2.347 +	std::istringstream ls(line);	
   2.348 +	while (ls >> id) {
   2.349 +	  if (id[0] == '#') break;
   2.350 +	  typename EdgeReaders::iterator it = edge_readers.find(id);
   2.351 +	  if (it != edge_readers.end()) {
   2.352 +	    index.push_back(it->second);
   2.353 +	  } else {
   2.354 +	    index.push_back(&edgeSkipper);
   2.355 +	  }
   2.356 +	  ++n;
   2.357 +	}
   2.358 +      }
   2.359 +      edgeInverter = index[0]->getInverter();
   2.360 +      std::string line;
   2.361 +      while (line = readNotEmptyLine(is, line_num), line[0] != '@') {	
   2.362 +	std::istringstream ls(line);
   2.363 +	Node source = nodeInverter->read(ls);
   2.364 +	Node target = nodeInverter->read(ls);
   2.365 +	Edge edge = graph.addEdge(source, target);
   2.366 +	edgeInverter->read(ls, edge);
   2.367 +	for (int i = 1; i < n; ++i) {
   2.368 +	  index[i]->read(ls, edge);
   2.369 +	}
   2.370 +      }      
   2.371      }
   2.372  
   2.373      std::string readNotEmptyLine(std::istream& is, int& line_num) {
   2.374 @@ -168,23 +348,107 @@
   2.375        throw Exception();
   2.376      }
   2.377      
   2.378 -    istream& is;
   2.379 -    Graph& graph;
   2.380 +    template <typename _Item>
   2.381 +    class InverterBase {
   2.382 +    public:
   2.383 +      typedef _Item Item;
   2.384 +      virtual void read(istream&, const Item&) = 0;
   2.385 +      virtual Item read(istream&) = 0;
   2.386 +    };
   2.387  
   2.388 -    typename ReaderTraits::DefaultSkipper default_skipper;
   2.389 +    template <typename _Item, typename _Map, typename _Reader>
   2.390 +    class MapReaderInverter : public InverterBase<_Item> {
   2.391 +    public:
   2.392 +      typedef _Item Item;
   2.393 +      typedef _Reader Reader;
   2.394 +      typedef typename Reader::Value Value;
   2.395 +      typedef _Map Map;
   2.396 +      typedef std::map<Value, Item> Inverse;
   2.397 +
   2.398 +      Map& map;
   2.399 +      Reader reader;
   2.400 +      Inverse inverse;
   2.401 +
   2.402 +      MapReaderInverter(Map& _map, const Reader& _reader) 
   2.403 +	: map(_map), reader(_reader) {}
   2.404 +
   2.405 +      virtual void read(istream& is, const Item& item) {
   2.406 +	Value value;
   2.407 +	reader.read(is, value);
   2.408 +	map.set(item, value);
   2.409 +	typename Inverse::iterator it = inverse.find(value);
   2.410 +	if (it == inverse.end()) {
   2.411 +	  inverse.insert(make_pair(value, item));
   2.412 +	} else {
   2.413 +	  throw DataFormatException("Multiple ID occurence");
   2.414 +	}
   2.415 +      }
   2.416 +
   2.417 +      virtual Item read(istream& is) {
   2.418 +	Value value;
   2.419 +	reader.read(is, value);	
   2.420 +	typename Inverse::const_iterator it = inverse.find(value);
   2.421 +	if (it != inverse.end()) {
   2.422 +	  return it->second;
   2.423 +	} else {
   2.424 +	  throw DataFormatException("Invalid ID");
   2.425 +	}
   2.426 +      }      
   2.427 +    };
   2.428 +
   2.429 +    template <typename _Item, typename _Reader>
   2.430 +    class SkipReaderInverter : public InverterBase<_Item> {
   2.431 +    public:
   2.432 +      typedef _Item Item;
   2.433 +      typedef _Reader Reader;
   2.434 +      typedef typename Reader::Value Value;
   2.435 +      typedef std::map<Value, Item> Inverse;
   2.436 +
   2.437 +      Reader reader;
   2.438 +
   2.439 +      SkipReaderInverter(const Reader& _reader) 
   2.440 +	: reader(_reader) {}
   2.441 +
   2.442 +      virtual void read(istream& is, const Item& item) {
   2.443 +	Value value;
   2.444 +	reader.read(is, value);
   2.445 +	typename Inverse::iterator it = inverse.find(value);
   2.446 +	if (it == inverse.end()) {
   2.447 +	  inverse.insert(make_pair(value, item));
   2.448 +	} else {
   2.449 +	  throw DataFormatException("Multiple ID occurence");
   2.450 +	}
   2.451 +      }
   2.452 +
   2.453 +      virtual Item read(istream& is) {
   2.454 +	Value value;
   2.455 +	reader.read(is, value);	
   2.456 +	typename Inverse::const_iterator it = inverse.find(value);
   2.457 +	if (it != inverse.end()) {
   2.458 +	  return it->second;
   2.459 +	} else {
   2.460 +	  throw DataFormatException("Invalid ID");
   2.461 +	}
   2.462 +      }      
   2.463 +    private:
   2.464 +      Inverse inverse;
   2.465 +    };
   2.466 +
   2.467  
   2.468      template <typename _Item>    
   2.469 -    class MapReaderBase {
   2.470 +    class ReaderBase {
   2.471      public:
   2.472        typedef _Item Item;
   2.473        virtual void read(istream& is, const Item& item) = 0;
   2.474 +      virtual InverterBase<_Item>* getInverter() = 0;
   2.475      };
   2.476 -    
   2.477 +
   2.478      template <typename _Item, typename _Map, typename _Reader>
   2.479 -    class MapReader : public MapReaderBase<_Item> {
   2.480 +    class MapReader : public ReaderBase<_Item> {
   2.481      public:
   2.482        typedef _Map Map;
   2.483        typedef _Reader Reader;
   2.484 +      typedef typename Reader::Value Value;
   2.485        typedef _Item Item;
   2.486        
   2.487        Map& map;
   2.488 @@ -195,18 +459,50 @@
   2.489  
   2.490  
   2.491        virtual void read(istream& is, const Item& item) {
   2.492 -	typename Reader::Value value;
   2.493 +	Value value;
   2.494  	reader.read(is, value);
   2.495  	map.set(item, value);
   2.496        }
   2.497 +
   2.498 +      virtual InverterBase<_Item>* getInverter() {
   2.499 +	return new MapReaderInverter<Item, Map, Reader>(map, reader);
   2.500 +      }
   2.501      };
   2.502  
   2.503 -    typedef std::map<std::string, MapReaderBase<Node>* > NodeReaders;
   2.504 +
   2.505 +    template <typename _Item, typename _Reader>
   2.506 +    class SkipReader : public ReaderBase<_Item> {
   2.507 +    public:
   2.508 +      typedef _Reader Reader;
   2.509 +      typedef typename Reader::Value Value;
   2.510 +      typedef _Item Item;
   2.511 +
   2.512 +      Reader reader;
   2.513 +      SkipReader(const Reader& _reader) : reader(_reader) {}
   2.514 +
   2.515 +      virtual void read(istream& is, const Item& item) {
   2.516 +	Value value;
   2.517 +	reader.read(is, value);
   2.518 +      }      
   2.519 +
   2.520 +      virtual InverterBase<Item>* getInverter() {
   2.521 +	return new SkipReaderInverter<Item, Reader>(reader);
   2.522 +      }
   2.523 +    };
   2.524 +
   2.525 +
   2.526 +    typedef std::map<std::string, ReaderBase<Node>* > NodeReaders;
   2.527      NodeReaders node_readers;
   2.528  
   2.529 -    typedef std::map<std::string, MapReaderBase<Edge>* > EdgeReaders;
   2.530 +    typedef std::map<std::string, ReaderBase<Edge>* > EdgeReaders;
   2.531      EdgeReaders edge_readers;
   2.532  
   2.533 +    std::istream& is;
   2.534 +    Graph& graph;
   2.535 +
   2.536 +    SkipReader<Node, DefaultReader> nodeSkipper;
   2.537 +    SkipReader<Edge, DefaultReader> edgeSkipper;
   2.538 +
   2.539    };
   2.540  
   2.541  }
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/src/work/deba/test.cpp	Tue Dec 14 19:26:50 2004 +0000
     3.3 @@ -0,0 +1,51 @@
     3.4 +#include <iostream>
     3.5 +
     3.6 +using namespace std;
     3.7 +
     3.8 +
     3.9 +struct _EmptyList {
    3.10 +  void write() const {}
    3.11 +};
    3.12 +
    3.13 +template <typename _Item, typename _Next>
    3.14 +struct _AddNode {
    3.15 +  typedef _Next Next;
    3.16 +  typedef _Item Item;
    3.17 +  
    3.18 +  const Item item;
    3.19 +  const Next& next;
    3.20 +  
    3.21 +  _AddNode(const Item& _item, const Next& _next) 
    3.22 +    : item(_item), next(_next) {}
    3.23 +
    3.24 +  void write() const {
    3.25 +    next.write();
    3.26 +    cout << item << ' ';
    3.27 +  }
    3.28 +};
    3.29 +
    3.30 +template <typename _List = _EmptyList>
    3.31 +struct _Writer {
    3.32 +  typedef _List List;
    3.33 +
    3.34 +  const List list;
    3.35 +
    3.36 +  _Writer(const List& _list = List()) : list(_list) {}
    3.37 +
    3.38 +  
    3.39 +  template <typename Item> _Writer<_AddNode<Item, List> > add(Item item) const {
    3.40 +    return _Writer<_AddNode<Item, List> >(_AddNode<Item, List>(item, list));
    3.41 +  }
    3.42 +
    3.43 +  void write() const {
    3.44 +    list.write();
    3.45 +    cout << endl;
    3.46 +  }
    3.47 +};
    3.48 +
    3.49 +
    3.50 +typedef _Writer<> Writer;
    3.51 +
    3.52 +int main() {
    3.53 +  Writer().add(3).add("alpha").add(4.53).write();
    3.54 +}
     4.1 --- a/src/work/deba/test.lgf	Thu Dec 09 17:02:53 2004 +0000
     4.2 +++ b/src/work/deba/test.lgf	Tue Dec 14 19:26:50 2004 +0000
     4.3 @@ -1,30 +1,36 @@
     4.4 +@nodeset
     4.5 +id cost color description mmap
     4.6 +1 1 green "A -> B \t: 10" a
     4.7 +2 2 blue "A -> B \t: 10" b
     4.8 +# hatalom dicsoseg "A -> B \t: 10" c
     4.9 +3 1 red "A -> B \t: 10" d #adjkhj
    4.10 +4 2 red "A -> B \t: 10" e
    4.11 +5 1 green "A -> B \t: 10" f
    4.12 +10 1 green "A -> B \t: 10" g
    4.13 +    # hello - bello csucsok "A -> B \t: 10"
    4.14 +6 2 blue "A -> B \t: 10" h
    4.15 +7 1 blue "A -> B \t: 10" i
    4.16 +8 2 red "A -> B \t: 10" j
    4.17 +9 1 green "A -> B \t: 10" k
    4.18 +
    4.19 +@edgeset 
    4.20 +		id	weight 	description		mmap
    4.21 +1	4	1	10 	"A -> B \t: 101"	a
    4.22 +3 	5	5	29 	"A -> B \t: 10q"	b
    4.23 +3	4	2	92 	"A -> B \t: 10a"	c
    4.24 +2	3	6	92	"A -> B \t: 10d"	d
    4.25 +9	5	9 	49	"A -> B \t: 10c"	e
    4.26 +10	4	3	40	"A -> B \t: 10v"	f
    4.27 +1	3	8	84	"A -> B \t: 10g"	g
    4.28 +6	7	4	83 	"A -> B \t: 10h"	h
    4.29 +8	9	7	37 	"A -> B \t: 10j"	i
    4.30 +7	8	10	12 	"A -> B \t: 10g"	j
    4.31  
    4.32  @nodes
    4.33 +source 1
    4.34 +target 7
    4.35  
    4.36 -id cost color
    4.37 +@edges
    4.38 +newedge 7
    4.39  
    4.40 -1 1 green
    4.41 -2 2 blue
    4.42 -# hatalom dicsoseg
    4.43 -3 1 red
    4.44 -4 2 red
    4.45 -5 1 green
    4.46 -10 1 green # ez nem egy igazan jo sor
    4.47 -    # hello - bello csucsok
    4.48 -6 2 blue
    4.49 -7 1 blue
    4.50 -8 2 red
    4.51 -9 1 green
    4.52 -@edges
    4.53 -source target weight
    4.54 -1 4 10
    4.55 -3 5 29
    4.56 -3 4 92
    4.57 -2 3 92
    4.58 -9 5 49
    4.59 -10 4 40
    4.60 -1 3 84
    4.61 -6 7 83
    4.62 -8 9 37
    4.63 -7 8 89
    4.64  @end