lemon/lgf_reader.h
changeset 156 e561aa7675de
parent 148 4e2581021300
child 162 33247f6fff16
equal deleted inserted replaced
3:c601e1060f01 4:7b4f9985079f
   266 	}
   266 	}
   267       }
   267       }
   268       str = os.str();
   268       str = os.str();
   269       return is;
   269       return is;
   270     }
   270     }
   271 
       
   272     std::istream& readIdentifier(std::istream& is, std::string& str) {
       
   273       std::ostringstream os;
       
   274 
       
   275       char c;
       
   276       is >> std::ws;
       
   277       
       
   278       if (!is.get(c))
       
   279 	return is;
       
   280 
       
   281       if (!isIdentifierFirstChar(c))
       
   282 	throw DataFormatError("Wrong char in identifier");
       
   283       
       
   284       os << c;
       
   285       
       
   286       while (is.get(c) && !isWhiteSpace(c)) {
       
   287 	if (!isIdentifierChar(c)) 
       
   288 	  throw DataFormatError("Wrong char in identifier");	  
       
   289 	os << c;
       
   290       }
       
   291       if (!is) is.clear();
       
   292      
       
   293       str = os.str();
       
   294       return is;
       
   295     }
       
   296     
   271     
   297   }
   272   }
   298   
   273 
   299   /// \e
   274   /// \ingroup lemon_io
       
   275   ///  
       
   276   /// \brief LGF reader for directed graphs
       
   277   ///
       
   278   /// This utility reads an \ref lgf-format "LGF" file.
       
   279   ///
       
   280   /// The reading method does a batch processing. The user creates a
       
   281   /// reader object, then various reading rules can be added to the
       
   282   /// reader, and eventually the reading is executed with the \c run()
       
   283   /// member function. A map reading rule can be added to the reader
       
   284   /// with the \c nodeMap() or \c arcMap() members. An optional
       
   285   /// converter parameter can also be added as a standard functor converting from
       
   286   /// std::string to the value type of the map. If it is set, it will
       
   287   /// determine how the tokens in the file should be is converted to the map's
       
   288   /// value type. If the functor is not set, then a default conversion
       
   289   /// will be used. One map can be read into multiple map objects at the
       
   290   /// same time. The \c attribute(), \c node() and \c arc() functions
       
   291   /// are used to add attribute reading rules.
       
   292   ///
       
   293   ///\code
       
   294   ///     DigraphReader<Digraph>(std::cin, digraph).
       
   295   ///       nodeMap("coordinates", coord_map).
       
   296   ///       arcMap("capacity", cap_map).
       
   297   ///       node("source", src).
       
   298   ///       node("target", trg).
       
   299   ///       attribute("caption", caption).
       
   300   ///       run();
       
   301   ///\endcode
       
   302   ///
       
   303   /// By default the reader uses the first section in the file of the
       
   304   /// proper type. If a section has an optional name, then it can be
       
   305   /// selected for reading by giving an optional name parameter to
       
   306   /// the \c nodes(), \c arcs() or \c attributes()
       
   307   /// functions.
       
   308   ///
       
   309   /// The \c useNodes() and \c useArcs() functions are used to tell the reader
       
   310   /// that the nodes or arcs should not be constructed (added to the
       
   311   /// graph) during the reading, but instead the label map of the items
       
   312   /// are given as a parameter of these functions. An
       
   313   /// application of these function is multipass reading, which is
       
   314   /// important if two \e \@arcs sections must be read from the
       
   315   /// file. In this example the first phase would read the node set and one
       
   316   /// of the arc sets, while the second phase would read the second arc
       
   317   /// set into an \e ArcSet class (\c SmartArcSet or \c ListArcSet).
       
   318   /// The previously read label node map should be passed to the \c
       
   319   /// useNodes() functions. Another application of multipass reading when
       
   320   /// paths are given as a node map or an arc map. It is impossible read this in
       
   321   /// a single pass, because the arcs are not constructed when the node
       
   322   /// maps are read.
   300   template <typename _Digraph>
   323   template <typename _Digraph>
   301   class DigraphReader {
   324   class DigraphReader {
   302   public:
   325   public:
   303 
   326 
   304     typedef _Digraph Digraph;
   327     typedef _Digraph Digraph;
   339     int line_num;
   362     int line_num;
   340     std::istringstream line;
   363     std::istringstream line;
   341 
   364 
   342   public:
   365   public:
   343 
   366 
   344     /// \e
   367     /// \brief Constructor
       
   368     ///
       
   369     /// Construct a directed graph reader, which reads from the given
       
   370     /// input stream.
   345     DigraphReader(std::istream& is, Digraph& digraph) 
   371     DigraphReader(std::istream& is, Digraph& digraph) 
   346       : _is(&is), local_is(false), _digraph(digraph),
   372       : _is(&is), local_is(false), _digraph(digraph),
   347 	_use_nodes(false), _use_arcs(false) {}
   373 	_use_nodes(false), _use_arcs(false) {}
   348 
   374 
   349     /// \e
   375     /// \brief Constructor
       
   376     ///
       
   377     /// Construct a directed graph reader, which reads from the given
       
   378     /// file.
   350     DigraphReader(const std::string& fn, Digraph& digraph) 
   379     DigraphReader(const std::string& fn, Digraph& digraph) 
   351       : _is(new std::ifstream(fn.c_str())), local_is(true), _digraph(digraph),
   380       : _is(new std::ifstream(fn.c_str())), local_is(true), _digraph(digraph),
   352     	_use_nodes(false), _use_arcs(false) {}
   381     	_use_nodes(false), _use_arcs(false) {}
   353 
   382     
   354 
   383     /// \brief Constructor
   355     /// \e
   384     ///
       
   385     /// Construct a directed graph reader, which reads from the given
       
   386     /// file.
   356     DigraphReader(const char* fn, Digraph& digraph) 
   387     DigraphReader(const char* fn, Digraph& digraph) 
   357       : _is(new std::ifstream(fn)), local_is(true), _digraph(digraph),
   388       : _is(new std::ifstream(fn)), local_is(true), _digraph(digraph),
   358     	_use_nodes(false), _use_arcs(false) {}
   389     	_use_nodes(false), _use_arcs(false) {}
   359 
   390 
   360     /// \e
   391     /// \brief Copy constructor
       
   392     ///
       
   393     /// The copy constructor transfers all data from the other reader,
       
   394     /// therefore the copied reader will not be usable more. 
   361     DigraphReader(DigraphReader& other) 
   395     DigraphReader(DigraphReader& other) 
   362       : _is(other._is), local_is(other.local_is), _digraph(other._digraph),
   396       : _is(other._is), local_is(other.local_is), _digraph(other._digraph),
   363 	_use_nodes(other._use_nodes), _use_arcs(other._use_arcs) {
   397 	_use_nodes(other._use_nodes), _use_arcs(other._use_arcs) {
   364 
   398 
   365       other.is = 0;
   399       other.is = 0;
   375       _nodes_caption = other._nodes_caption;
   409       _nodes_caption = other._nodes_caption;
   376       _arcs_caption = other._arcs_caption;
   410       _arcs_caption = other._arcs_caption;
   377       _attributes_caption = other._attributes_caption;
   411       _attributes_caption = other._attributes_caption;
   378     }
   412     }
   379 
   413 
   380     /// \e
   414     /// \brief Destructor
   381     ~DigraphReader() {
   415     ~DigraphReader() {
   382       for (typename NodeMaps::iterator it = _node_maps.begin(); 
   416       for (typename NodeMaps::iterator it = _node_maps.begin(); 
   383 	   it != _node_maps.end(); ++it) {
   417 	   it != _node_maps.end(); ++it) {
   384 	delete it->second;
   418 	delete it->second;
   385       }
   419       }
   404     
   438     
   405     DigraphReader& operator=(const DigraphReader&);
   439     DigraphReader& operator=(const DigraphReader&);
   406 
   440 
   407   public:
   441   public:
   408 
   442 
   409     /// \e
   443     /// \name Reading rules
       
   444     /// @{
       
   445     
       
   446     /// \brief Node map reading rule
       
   447     ///
       
   448     /// Add a node map reading rule to the reader.
   410     template <typename Map>
   449     template <typename Map>
   411     DigraphReader& nodeMap(const std::string& caption, Map& map) {
   450     DigraphReader& nodeMap(const std::string& caption, Map& map) {
   412       checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
   451       checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
   413       _reader_bits::MapStorageBase<Node>* storage = 
   452       _reader_bits::MapStorageBase<Node>* storage = 
   414 	new _reader_bits::MapStorage<Node, Map>(map);
   453 	new _reader_bits::MapStorage<Node, Map>(map);
   415       _node_maps.push_back(std::make_pair(caption, storage));
   454       _node_maps.push_back(std::make_pair(caption, storage));
   416       return *this;
   455       return *this;
   417     }
   456     }
   418 
   457 
   419     /// \e
   458     /// \brief Node map reading rule
       
   459     ///
       
   460     /// Add a node map reading rule with specialized converter to the
       
   461     /// reader.
   420     template <typename Map, typename Converter>
   462     template <typename Map, typename Converter>
   421     DigraphReader& nodeMap(const std::string& caption, Map& map, 
   463     DigraphReader& nodeMap(const std::string& caption, Map& map, 
   422 			   const Converter& converter = Converter()) {
   464 			   const Converter& converter = Converter()) {
   423       checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
   465       checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
   424       _reader_bits::MapStorageBase<Node>* storage = 
   466       _reader_bits::MapStorageBase<Node>* storage = 
   425 	new _reader_bits::MapStorage<Node, Map, Converter>(map, converter);
   467 	new _reader_bits::MapStorage<Node, Map, Converter>(map, converter);
   426       _node_maps.push_back(std::make_pair(caption, storage));
   468       _node_maps.push_back(std::make_pair(caption, storage));
   427       return *this;
   469       return *this;
   428     }
   470     }
   429 
   471 
   430     /// \e
   472     /// \brief Arc map reading rule
       
   473     ///
       
   474     /// Add an arc map reading rule to the reader.
   431     template <typename Map>
   475     template <typename Map>
   432     DigraphReader& arcMap(const std::string& caption, Map& map) {
   476     DigraphReader& arcMap(const std::string& caption, Map& map) {
   433       checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
   477       checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
   434       _reader_bits::MapStorageBase<Arc>* storage = 
   478       _reader_bits::MapStorageBase<Arc>* storage = 
   435 	new _reader_bits::MapStorage<Arc, Map>(map);
   479 	new _reader_bits::MapStorage<Arc, Map>(map);
   436       _arc_maps.push_back(std::make_pair(caption, storage));
   480       _arc_maps.push_back(std::make_pair(caption, storage));
   437       return *this;
   481       return *this;
   438     }
   482     }
   439 
   483 
   440     /// \e
   484     /// \brief Arc map reading rule
       
   485     ///
       
   486     /// Add an arc map reading rule with specialized converter to the
       
   487     /// reader.
   441     template <typename Map, typename Converter>
   488     template <typename Map, typename Converter>
   442     DigraphReader& arcMap(const std::string& caption, Map& map, 
   489     DigraphReader& arcMap(const std::string& caption, Map& map, 
   443 			  const Converter& converter = Converter()) {
   490 			  const Converter& converter = Converter()) {
   444       checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
   491       checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
   445       _reader_bits::MapStorageBase<Arc>* storage = 
   492       _reader_bits::MapStorageBase<Arc>* storage = 
   446 	new _reader_bits::MapStorage<Arc, Map, Converter>(map, converter);
   493 	new _reader_bits::MapStorage<Arc, Map, Converter>(map, converter);
   447       _arc_maps.push_back(std::make_pair(caption, storage));
   494       _arc_maps.push_back(std::make_pair(caption, storage));
   448       return *this;
   495       return *this;
   449     }
   496     }
   450 
   497 
   451     /// \e
   498     /// \brief Attribute reading rule
       
   499     ///
       
   500     /// Add an attribute reading rule to the reader.
   452     template <typename Value>
   501     template <typename Value>
   453     DigraphReader& attribute(const std::string& caption, Value& value) {
   502     DigraphReader& attribute(const std::string& caption, Value& value) {
   454       _reader_bits::ValueStorageBase* storage = 
   503       _reader_bits::ValueStorageBase* storage = 
   455 	new _reader_bits::ValueStorage<Value>(value);
   504 	new _reader_bits::ValueStorage<Value>(value);
   456       _attributes.insert(std::make_pair(caption, storage));
   505       _attributes.insert(std::make_pair(caption, storage));
   457       return *this;
   506       return *this;
   458     }
   507     }
   459 
   508 
   460     /// \e
   509     /// \brief Attribute reading rule
       
   510     ///
       
   511     /// Add an attribute reading rule with specialized converter to the
       
   512     /// reader.
   461     template <typename Value, typename Converter>
   513     template <typename Value, typename Converter>
   462     DigraphReader& attribute(const std::string& caption, Value& value, 
   514     DigraphReader& attribute(const std::string& caption, Value& value, 
   463 			     const Converter& converter = Converter()) {
   515 			     const Converter& converter = Converter()) {
   464       _reader_bits::ValueStorageBase* storage = 
   516       _reader_bits::ValueStorageBase* storage = 
   465 	new _reader_bits::ValueStorage<Value, Converter>(value, converter);
   517 	new _reader_bits::ValueStorage<Value, Converter>(value, converter);
   466       _attributes.insert(std::make_pair(caption, storage));
   518       _attributes.insert(std::make_pair(caption, storage));
   467       return *this;
   519       return *this;
   468     }
   520     }
   469 
   521 
   470     /// \e
   522     /// \brief Node reading rule
       
   523     ///
       
   524     /// Add a node reading rule to reader.
   471     DigraphReader& node(const std::string& caption, Node& node) {
   525     DigraphReader& node(const std::string& caption, Node& node) {
   472       typedef _reader_bits::MapLookUpConverter<Node> Converter;
   526       typedef _reader_bits::MapLookUpConverter<Node> Converter;
   473       Converter converter(_node_index);
   527       Converter converter(_node_index);
   474       _reader_bits::ValueStorageBase* storage = 
   528       _reader_bits::ValueStorageBase* storage = 
   475 	new _reader_bits::ValueStorage<Node, Converter>(node, converter);
   529 	new _reader_bits::ValueStorage<Node, Converter>(node, converter);
   476       _attributes.insert(std::make_pair(caption, storage));
   530       _attributes.insert(std::make_pair(caption, storage));
   477       return *this;
   531       return *this;
   478     }
   532     }
   479 
   533 
   480     /// \e
   534     /// \brief Arc reading rule
       
   535     ///
       
   536     /// Add an arc reading rule to reader.
   481     DigraphReader& arc(const std::string& caption, Arc& arc) {
   537     DigraphReader& arc(const std::string& caption, Arc& arc) {
   482       typedef _reader_bits::MapLookUpConverter<Arc> Converter;
   538       typedef _reader_bits::MapLookUpConverter<Arc> Converter;
   483       Converter converter(_arc_index);
   539       Converter converter(_arc_index);
   484       _reader_bits::ValueStorageBase* storage = 
   540       _reader_bits::ValueStorageBase* storage = 
   485 	new _reader_bits::ValueStorage<Arc, Converter>(arc, converter);
   541 	new _reader_bits::ValueStorage<Arc, Converter>(arc, converter);
   486       _attributes.insert(std::make_pair(caption, storage));
   542       _attributes.insert(std::make_pair(caption, storage));
   487       return *this;
   543       return *this;
   488     }
   544     }
   489 
   545 
   490     /// \e
   546     /// @}
       
   547 
       
   548     /// \name Select section by name
       
   549     /// @{
       
   550 
       
   551     /// \brief Set \c \@nodes section to be read
       
   552     ///
       
   553     /// Set \c \@nodes section to be read
   491     DigraphReader& nodes(const std::string& caption) {
   554     DigraphReader& nodes(const std::string& caption) {
   492       _nodes_caption = caption;
   555       _nodes_caption = caption;
   493       return *this;
   556       return *this;
   494     }
   557     }
   495 
   558 
   496     /// \e
   559     /// \brief Set \c \@arcs section to be read
       
   560     ///
       
   561     /// Set \c \@arcs section to be read
   497     DigraphReader& arcs(const std::string& caption) {
   562     DigraphReader& arcs(const std::string& caption) {
   498       _arcs_caption = caption;
   563       _arcs_caption = caption;
   499       return *this;
   564       return *this;
   500     }
   565     }
   501 
   566 
   502     /// \e
   567     /// \brief Set \c \@attributes section to be read
       
   568     ///
       
   569     /// Set \c \@attributes section to be read
   503     DigraphReader& attributes(const std::string& caption) {
   570     DigraphReader& attributes(const std::string& caption) {
   504       _attributes_caption = caption;
   571       _attributes_caption = caption;
   505       return *this;
   572       return *this;
   506     }
   573     }
   507 
   574 
   508     /// \e
   575     /// @}
       
   576 
       
   577     /// \name Using previously constructed node or arc set
       
   578     /// @{
       
   579 
       
   580     /// \brief Use previously constructed node set
       
   581     ///
       
   582     /// Use previously constructed node set, and specify the node
       
   583     /// label map.
   509     template <typename Map>
   584     template <typename Map>
   510     DigraphReader& useNodes(const Map& map) {
   585     DigraphReader& useNodes(const Map& map) {
   511       checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
   586       checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
   512       LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member"); 
   587       LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member"); 
   513       _use_nodes = true;
   588       _use_nodes = true;
   516 	_node_index.insert(std::make_pair(converter(map[n]), n));
   591 	_node_index.insert(std::make_pair(converter(map[n]), n));
   517       }
   592       }
   518       return *this;
   593       return *this;
   519     }
   594     }
   520 
   595 
   521     /// \e
   596     /// \brief Use previously constructed node set
       
   597     ///
       
   598     /// Use previously constructed node set, and specify the node
       
   599     /// label map and a functor which converts the label map values to
       
   600     /// std::string.
   522     template <typename Map, typename Converter>
   601     template <typename Map, typename Converter>
   523     DigraphReader& useNodes(const Map& map, 
   602     DigraphReader& useNodes(const Map& map, 
   524 			    const Converter& converter = Converter()) {
   603 			    const Converter& converter = Converter()) {
   525       checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
   604       checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
   526       LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member"); 
   605       LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member"); 
   529 	_node_index.insert(std::make_pair(converter(map[n]), n));
   608 	_node_index.insert(std::make_pair(converter(map[n]), n));
   530       }
   609       }
   531       return *this;
   610       return *this;
   532     }
   611     }
   533 
   612 
   534     /// \e
   613     /// \brief Use previously constructed arc set
       
   614     ///
       
   615     /// Use previously constructed arc set, and specify the arc
       
   616     /// label map.
   535     template <typename Map>
   617     template <typename Map>
   536     DigraphReader& useArcs(const Map& map) {
   618     DigraphReader& useArcs(const Map& map) {
   537       checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
   619       checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
   538       LEMON_ASSERT(!_use_arcs, "Multiple usage of useArcs() member");
   620       LEMON_ASSERT(!_use_arcs, "Multiple usage of useArcs() member");
   539       _use_arcs = true;
   621       _use_arcs = true;
   542 	_arc_index.insert(std::make_pair(converter(map[a]), a));
   624 	_arc_index.insert(std::make_pair(converter(map[a]), a));
   543       }
   625       }
   544       return *this;
   626       return *this;
   545     }
   627     }
   546 
   628 
   547     /// \e
   629     /// \brief Use previously constructed arc set
       
   630     ///
       
   631     /// Use previously constructed arc set, and specify the arc
       
   632     /// label map and a functor which converts the label map values to
       
   633     /// std::string.
   548     template <typename Map, typename Converter>
   634     template <typename Map, typename Converter>
   549     DigraphReader& useArcs(const Map& map, 
   635     DigraphReader& useArcs(const Map& map, 
   550 			    const Converter& converter = Converter()) {
   636 			    const Converter& converter = Converter()) {
   551       checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
   637       checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
   552       LEMON_ASSERT(!_use_arcs, "Multiple usage of useArcs() member"); 
   638       LEMON_ASSERT(!_use_arcs, "Multiple usage of useArcs() member"); 
   555 	_arc_index.insert(std::make_pair(converter(map[a]), a));
   641 	_arc_index.insert(std::make_pair(converter(map[a]), a));
   556       }
   642       }
   557       return *this;
   643       return *this;
   558     }
   644     }
   559 
   645 
       
   646     /// @}
       
   647 
   560   private:
   648   private:
   561 
   649 
   562     bool readLine() {
   650     bool readLine() {
   563       std::string str;
   651       std::string str;
   564       while(++line_num, std::getline(*_is, str)) {
   652       while(++line_num, std::getline(*_is, str)) {
   595       {
   683       {
   596 	std::map<std::string, int> maps;
   684 	std::map<std::string, int> maps;
   597 	
   685 	
   598 	std::string map;
   686 	std::string map;
   599 	int index = 0;
   687 	int index = 0;
   600 	while (_reader_bits::readIdentifier(line, map)) {
   688 	while (_reader_bits::readToken(line, map)) {
   601 	  if (maps.find(map) != maps.end()) {
   689 	  if (maps.find(map) != maps.end()) {
   602 	    std::ostringstream msg;
   690 	    std::ostringstream msg;
   603 	    msg << "Multiple occurence of node map: " << map;
   691 	    msg << "Multiple occurence of node map: " << map;
   604 	    throw DataFormatError(msg.str().c_str());
   692 	    throw DataFormatError(msg.str().c_str());
   605 	  }
   693 	  }
   678       {
   766       {
   679 	std::map<std::string, int> maps;
   767 	std::map<std::string, int> maps;
   680 	
   768 	
   681 	std::string map;
   769 	std::string map;
   682 	int index = 0;
   770 	int index = 0;
   683 	while (_reader_bits::readIdentifier(line, map)) {
   771 	while (_reader_bits::readToken(line, map)) {
   684 	  if (maps.find(map) != maps.end()) {
   772 	  if (maps.find(map) != maps.end()) {
   685 	    std::ostringstream msg;
   773 	    std::ostringstream msg;
   686 	    msg << "Multiple occurence of arc map: " << map;
   774 	    msg << "Multiple occurence of arc map: " << map;
   687 	    throw DataFormatError(msg.str().c_str());
   775 	    throw DataFormatError(msg.str().c_str());
   688 	  }
   776 	  }
   785       char c;
   873       char c;
   786       while (readLine() && line >> c && c != '@') {
   874       while (readLine() && line >> c && c != '@') {
   787 	line.putback(c);
   875 	line.putback(c);
   788 	
   876 	
   789 	std::string attr, token;
   877 	std::string attr, token;
   790 	if (!_reader_bits::readIdentifier(line, attr))
   878 	if (!_reader_bits::readToken(line, attr))
   791 	  throw DataFormatError("Attribute name not found");
   879 	  throw DataFormatError("Attribute name not found");
   792 	if (!_reader_bits::readToken(line, token))
   880 	if (!_reader_bits::readToken(line, token))
   793 	  throw DataFormatError("Attribute value not found");
   881 	  throw DataFormatError("Attribute value not found");
   794 	if (line >> c)
   882 	if (line >> c)
   795 	  throw DataFormatError("Extra character on the end of line");	  
   883 	  throw DataFormatError("Extra character on the end of line");	  
   825 	}	
   913 	}	
   826       }
   914       }
   827     }
   915     }
   828 
   916 
   829   public:
   917   public:
   830     
   918 
   831     /// \e
   919     /// \name Execution of the reader    
       
   920     /// @{
       
   921 
       
   922     /// \brief Start the batch processing
       
   923     ///
       
   924     /// This function starts the batch processing
   832     void run() {
   925     void run() {
   833       
   926       
   834       LEMON_ASSERT(_is != 0, "This reader assigned to an other reader");
   927       LEMON_ASSERT(_is != 0, "This reader assigned to an other reader");
   835       
   928       
   836       bool nodes_done = false;
   929       bool nodes_done = false;
   844 	skipSection();
   937 	skipSection();
   845 	try {
   938 	try {
   846 	  char c;
   939 	  char c;
   847 	  std::string section, caption;
   940 	  std::string section, caption;
   848 	  line >> c;
   941 	  line >> c;
   849 	  _reader_bits::readIdentifier(line, section);
   942 	  _reader_bits::readToken(line, section);
   850 	  _reader_bits::readIdentifier(line, caption);
   943 	  _reader_bits::readToken(line, caption);
   851 
   944 
   852 	  if (line >> c) 
   945 	  if (line >> c) 
   853 	    throw DataFormatError("Extra character on the end of line");
   946 	    throw DataFormatError("Extra character on the end of line");
   854 
   947 
   855 	  if (section == "nodes" && !nodes_done) {
   948 	  if (section == "nodes" && !nodes_done) {
   889       if (!attributes_done && !_attributes.empty()) {
   982       if (!attributes_done && !_attributes.empty()) {
   890 	throw DataFormatError("Section @attributes not found");
   983 	throw DataFormatError("Section @attributes not found");
   891       }
   984       }
   892 
   985 
   893     }
   986     }
       
   987 
       
   988     /// @}
   894     
   989     
   895   };
   990   };
   896 
   991 
       
   992   /// \relates DigraphReader
   897   template <typename Digraph>
   993   template <typename Digraph>
   898   DigraphReader<Digraph> digraphReader(std::istream& is, Digraph& digraph) {
   994   DigraphReader<Digraph> digraphReader(std::istream& is, Digraph& digraph) {
   899     return DigraphReader<Digraph>(is, digraph);
   995     return DigraphReader<Digraph>(is, digraph);
   900   }
   996   }
   901 
   997 
       
   998   /// \relates DigraphReader
   902   template <typename Digraph>
   999   template <typename Digraph>
   903   DigraphReader<Digraph> digraphReader(const std::string& fn, 
  1000   DigraphReader<Digraph> digraphReader(const std::string& fn, 
   904 				       Digraph& digraph) {
  1001 				       Digraph& digraph) {
   905     return DigraphReader<Digraph>(fn, digraph);
  1002     return DigraphReader<Digraph>(fn, digraph);
   906   }
  1003   }
   907 
  1004 
       
  1005   /// \relates DigraphReader
   908   template <typename Digraph>
  1006   template <typename Digraph>
   909   DigraphReader<Digraph> digraphReader(const char* fn, Digraph& digraph) {
  1007   DigraphReader<Digraph> digraphReader(const char* fn, Digraph& digraph) {
   910     return DigraphReader<Digraph>(fn, digraph);
  1008     return DigraphReader<Digraph>(fn, digraph);
   911   }
  1009   }
   912 }
  1010 }