gravatar
alpar (Alpar Juttner)
alpar@cs.elte.hu
More flexible header names in .lgf + largely improved doc
0 4 1
default
5 files changed with 387 insertions and 100 deletions:
↑ Collapse diff ↑
Show white space 6 line context
1
/* -*- C++ -*-
2
 *
3
 * This file is a part of LEMON, a generic C++ optimization library
4
 *
5
 * Copyright (C) 2003-2008
6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8
 *
9
 * Permission to use, modify and distribute this software is granted
10
 * provided that this copyright notice appears in all copies. For
11
 * precise terms see the accompanying LICENSE file.
12
 *
13
 * This software is provided "AS IS" with no warranty of any kind,
14
 * express or implied, and with no claim as to its suitability for any
15
 * purpose.
16
 *
17
 */
18

	
19
namespace lemon {
20
/*!
21

	
22

	
23

	
24
\page lgf-format Lemon Graph Format (LGF)
25

	
26
The \e LGF is a <em>column oriented</em>
27
file format for storing graphs and associated data like
28
node and edge maps.
29

	
30
Each line with \c '#' first non-whitespace
31
character is considered as a comment line.
32

	
33
Otherwise the file consists of sections starting with
34
a header line. The header lines starts with an \c '@' character followed by the
35
type of section. The standard section types are \c \@nodes, \c
36
\@arcs and \c \@edges
37
and \@attributes. Each header line may also have an optional
38
\e name, which can be use to distinguish the sections of the same
39
type.
40

	
41
The standard sections are column oriented, each line consists of
42
<em>token</em>s separated by whitespaces. A token can be \e plain or
43
\e quoted. A plain token is just a sequence of non-whitespace characters,
44
while a quoted token is a
45
character sequence surrounded by double quotes, and it can also
46
contain whitespaces and escape sequences. 
47

	
48
The \c \@nodes section describes a set of nodes and associated
49
maps. The first is a header line, it columns are the names of the
50
maps appearing in the following lines.
51
One of the maps must be called \c
52
"label", which plays special role in the file.
53
The following
54
non-empty lines until the next section describes nodes of the
55
graph. Each line contains the values of the node maps
56
associated to the current node.
57

	
58
\code
59
 @nodes
60
 label   coordinates size    title
61
 1       (10,20)     10      "First node"
62
 2       (80,80)     8       "Second node"
63
 3       (40,10)     10      "Third node"
64
\endcode
65

	
66
The \c \@arcs section is very similar to the \c \@nodes section,
67
it again starts with a header line describing the names of the arc,
68
but the \c "label" map is not obligatory here. The following lines
69
describe the arcs. The first two tokens of each line are
70
the source and the target node of the arc, respectively, then come the map
71
values. The source and target tokens must be node labels.
72

	
73
\code
74
 @arcs
75
 	      capacity
76
 1   2   16
77
 1   3   12
78
 2   3   18
79
\endcode
80

	
81
The \c \@edges is just a synonym of \c \@arcs.
82

	
83
The \c \@attributes section contains key-value pairs, each line
84
consists of two tokens, an attribute name, and then an attribute value.
85

	
86
\code
87
 @attributes
88
 source 1
89
 target 3
90
 caption "LEMON test digraph"
91
\endcode
92

	
93
*/
94
}
95

	
96
//  LocalWords:  whitespace whitespaces
Ignore white space 6 line context
... ...
@@ -5,2 +5,3 @@
5 5
	doc/groups.dox \
6
	doc/lgf.dox \
6 7
	doc/license.dox \
Ignore white space 6 line context
... ...
@@ -485,21 +485,2 @@
485 485
/**
486
@defgroup section_io Section readers and writers
487
@ingroup lemon_io
488
\brief Section readers and writers for LEMON Input-Output.
489

	
490
This group describes section reader and writer classes that can be 
491
attached to \ref LemonReader and \ref LemonWriter.
492
*/
493

	
494
/**
495
@defgroup item_io Item readers and writers
496
@ingroup lemon_io
497
\brief Item readers and writers for LEMON Input-Output.
498

	
499
This group describes reader and writer classes for various data types
500
(e.g. map or attribute values). These classes can be attached to
501
\ref LemonReader and \ref LemonWriter.
502
*/
503

	
504
/**
505 486
@defgroup eps_io Postscript exporting
Ignore white space 6 line context
... ...
@@ -270,31 +270,54 @@
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
  
299
  /// \e
273

	
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 323
  template <typename _Digraph>
... ...
@@ -343,3 +366,6 @@
343 366

	
344
    /// \e
367
    /// \brief Constructor
368
    ///
369
    /// Construct a directed graph reader, which reads from the given
370
    /// input stream.
345 371
    DigraphReader(std::istream& is, Digraph& digraph) 
... ...
@@ -348,3 +374,6 @@
348 374

	
349
    /// \e
375
    /// \brief Constructor
376
    ///
377
    /// Construct a directed graph reader, which reads from the given
378
    /// file.
350 379
    DigraphReader(const std::string& fn, Digraph& digraph) 
... ...
@@ -352,5 +381,7 @@
352 381
    	_use_nodes(false), _use_arcs(false) {}
353

	
354

	
355
    /// \e
382
    
383
    /// \brief Constructor
384
    ///
385
    /// Construct a directed graph reader, which reads from the given
386
    /// file.
356 387
    DigraphReader(const char* fn, Digraph& digraph) 
... ...
@@ -359,3 +390,6 @@
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 395
    DigraphReader(DigraphReader& other) 
... ...
@@ -379,3 +413,3 @@
379 413

	
380
    /// \e
414
    /// \brief Destructor
381 415
    ~DigraphReader() {
... ...
@@ -408,3 +442,8 @@
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 449
    template <typename Map>
... ...
@@ -418,3 +457,6 @@
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 462
    template <typename Map, typename Converter>
... ...
@@ -429,3 +471,5 @@
429 471

	
430
    /// \e
472
    /// \brief Arc map reading rule
473
    ///
474
    /// Add an arc map reading rule to the reader.
431 475
    template <typename Map>
... ...
@@ -439,3 +483,6 @@
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 488
    template <typename Map, typename Converter>
... ...
@@ -450,3 +497,5 @@
450 497

	
451
    /// \e
498
    /// \brief Attribute reading rule
499
    ///
500
    /// Add an attribute reading rule to the reader.
452 501
    template <typename Value>
... ...
@@ -459,3 +508,6 @@
459 508

	
460
    /// \e
509
    /// \brief Attribute reading rule
510
    ///
511
    /// Add an attribute reading rule with specialized converter to the
512
    /// reader.
461 513
    template <typename Value, typename Converter>
... ...
@@ -469,3 +521,5 @@
469 521

	
470
    /// \e
522
    /// \brief Node reading rule
523
    ///
524
    /// Add a node reading rule to reader.
471 525
    DigraphReader& node(const std::string& caption, Node& node) {
... ...
@@ -479,3 +533,5 @@
479 533

	
480
    /// \e
534
    /// \brief Arc reading rule
535
    ///
536
    /// Add an arc reading rule to reader.
481 537
    DigraphReader& arc(const std::string& caption, Arc& arc) {
... ...
@@ -489,3 +545,10 @@
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 554
    DigraphReader& nodes(const std::string& caption) {
... ...
@@ -495,3 +558,5 @@
495 558

	
496
    /// \e
559
    /// \brief Set \c \@arcs section to be read
560
    ///
561
    /// Set \c \@arcs section to be read
497 562
    DigraphReader& arcs(const std::string& caption) {
... ...
@@ -501,3 +566,5 @@
501 566

	
502
    /// \e
567
    /// \brief Set \c \@attributes section to be read
568
    ///
569
    /// Set \c \@attributes section to be read
503 570
    DigraphReader& attributes(const std::string& caption) {
... ...
@@ -507,3 +574,11 @@
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 584
    template <typename Map>
... ...
@@ -520,3 +595,7 @@
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 601
    template <typename Map, typename Converter>
... ...
@@ -533,3 +612,6 @@
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 617
    template <typename Map>
... ...
@@ -546,3 +628,7 @@
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 634
    template <typename Map, typename Converter>
... ...
@@ -559,2 +645,4 @@
559 645

	
646
    /// @}
647

	
560 648
  private:
... ...
@@ -599,3 +687,3 @@
599 687
	int index = 0;
600
	while (_reader_bits::readIdentifier(line, map)) {
688
	while (_reader_bits::readToken(line, map)) {
601 689
	  if (maps.find(map) != maps.end()) {
... ...
@@ -682,3 +770,3 @@
682 770
	int index = 0;
683
	while (_reader_bits::readIdentifier(line, map)) {
771
	while (_reader_bits::readToken(line, map)) {
684 772
	  if (maps.find(map) != maps.end()) {
... ...
@@ -789,3 +877,3 @@
789 877
	std::string attr, token;
790
	if (!_reader_bits::readIdentifier(line, attr))
878
	if (!_reader_bits::readToken(line, attr))
791 879
	  throw DataFormatError("Attribute name not found");
... ...
@@ -829,4 +917,9 @@
829 917
  public:
830
    
831
    /// \e
918

	
919
    /// \name Execution of the reader    
920
    /// @{
921

	
922
    /// \brief Start the batch processing
923
    ///
924
    /// This function starts the batch processing
832 925
    void run() {
... ...
@@ -848,4 +941,4 @@
848 941
	  line >> c;
849
	  _reader_bits::readIdentifier(line, section);
850
	  _reader_bits::readIdentifier(line, caption);
942
	  _reader_bits::readToken(line, section);
943
	  _reader_bits::readToken(line, caption);
851 944

	
... ...
@@ -893,2 +986,4 @@
893 986
    }
987

	
988
    /// @}
894 989
    
... ...
@@ -896,2 +991,3 @@
896 991

	
992
  /// \relates DigraphReader
897 993
  template <typename Digraph>
... ...
@@ -901,2 +997,3 @@
901 997

	
998
  /// \relates DigraphReader
902 999
  template <typename Digraph>
... ...
@@ -907,2 +1004,3 @@
907 1004

	
1005
  /// \relates DigraphReader
908 1006
  template <typename Digraph>
Ignore white space 6 line context
... ...
@@ -206,2 +206,3 @@
206 206
    bool requireEscape(const std::string& str) {
207
      if (str.empty() || str[0] == '@') return true;
207 208
      std::istringstream is(str);
... ...
@@ -233,3 +234,46 @@
233 234
  
234
  /// \e
235
  /// \ingroup lemon_io
236
  ///  
237
  /// \brief LGF writer for directed graphs
238
  ///
239
  /// This utility writes an \ref lgf-format "LGF" file.
240
  ///
241
  /// The writing method does a batch processing. The user creates a
242
  /// writer object, then various writing rules can be added to the
243
  /// writer, and eventually the writing is executed with the \c run()
244
  /// member function. A map writing rule can be added to the writer
245
  /// with the \c nodeMap() or \c arcMap() members. An optional
246
  /// converter parameter can also be added as a standard functor converting from
247
  /// the value type of the map to std::string. If it is set, it will
248
  /// determine how the map's value type is written to the output
249
  /// stream. If the functor is not set, then a default conversion
250
  /// will be used. The \c attribute(), \c node() and \c arc() functions
251
  /// are used to add attribute writing rules.
252
  ///
253
  ///\code
254
  ///     DigraphWriter<Digraph>(std::cout, digraph).
255
  ///       nodeMap("coordinates", coord_map).
256
  ///       nodeMap("size", size).
257
  ///       nodeMap("title", title).
258
  ///       arcMap("capacity", cap_map).
259
  ///       node("source", src).
260
  ///       node("target", trg).
261
  ///       attribute("caption", caption).
262
  ///       run();
263
  ///\endcode
264
  ///
265
  ///
266
  /// By default, the writer does not write additional captions to the
267
  /// sections, but they can be give as an optional parameter of
268
  /// the \c nodes(), \c arcs() or \c
269
  /// attributes() functions.
270
  ///
271
  /// The \c skipNodes() and \c skipArcs() functions forbid the
272
  /// writing of the sections. If two arc sections should be written to the
273
  /// output, it can be done in two passes, the first pass writes the
274
  /// node section and the first arc section, then the second pass
275
  /// skips the node section and writes just the arc section to the
276
  /// stream. The output stream can be retrieved with the \c ostream()
277
  /// function, hence the second pass can append its output to the output of the
278
  /// first pass.
235 279
  template <typename _Digraph>
... ...
@@ -275,3 +319,6 @@
275 319

	
276
    /// \e
320
    /// \brief Constructor
321
    ///
322
    /// Construct a directed graph writer, which writes to the given
323
    /// output stream.
277 324
    DigraphWriter(std::ostream& is, Digraph& digraph) 
... ...
@@ -280,3 +327,6 @@
280 327

	
281
    /// \e
328
    /// \brief Constructor
329
    ///
330
    /// Construct a directed graph writer, which writes to the given
331
    /// output file.
282 332
    DigraphWriter(const std::string& fn, Digraph& digraph) 
... ...
@@ -285,3 +335,6 @@
285 335

	
286
    /// \e
336
    /// \brief Constructor
337
    ///
338
    /// Construct a directed graph writer, which writes to the given
339
    /// output file.
287 340
    DigraphWriter(const char* fn, Digraph& digraph) 
... ...
@@ -290,2 +343,6 @@
290 343

	
344
    /// \brief Copy constructor
345
    ///
346
    /// The copy constructor transfers all data from the other writer,
347
    /// therefore the copied writer will not be usable more. 
291 348
    DigraphWriter(DigraphWriter& other) 
... ...
@@ -309,3 +366,3 @@
309 366

	
310
    /// \e
367
    /// \brief Destructor
311 368
    ~DigraphWriter() {
... ...
@@ -337,3 +394,8 @@
337 394

	
338
    /// \e
395
    /// \name Writing rules
396
    /// @{
397
    
398
    /// \brief Node map reading rule
399
    ///
400
    /// Add a node map reading rule to the writer.
339 401
    template <typename Map>
... ...
@@ -347,3 +409,6 @@
347 409

	
348
    /// \e
410
    /// \brief Node map writing rule
411
    ///
412
    /// Add a node map writing rule with specialized converter to the
413
    /// writer.
349 414
    template <typename Map, typename Converter>
... ...
@@ -358,3 +423,5 @@
358 423

	
359
    /// \e
424
    /// \brief Arc map writing rule
425
    ///
426
    /// Add an arc map writing rule to the writer.
360 427
    template <typename Map>
... ...
@@ -368,3 +435,6 @@
368 435

	
369
    /// \e
436
    /// \brief Arc map writing rule
437
    ///
438
    /// Add an arc map writing rule with specialized converter to the
439
    /// writer.
370 440
    template <typename Map, typename Converter>
... ...
@@ -379,3 +449,5 @@
379 449

	
380
    /// \e
450
    /// \brief Attribute writing rule
451
    ///
452
    /// Add an attribute writing rule to the writer.
381 453
    template <typename Value>
... ...
@@ -388,3 +460,6 @@
388 460

	
389
    /// \e
461
    /// \brief Attribute writing rule
462
    ///
463
    /// Add an attribute writing rule with specialized converter to the
464
    /// writer.
390 465
    template <typename Value, typename Converter>
... ...
@@ -398,3 +473,5 @@
398 473

	
399
    /// \e
474
    /// \brief Node writing rule
475
    ///
476
    /// Add a node writing rule to the writer.
400 477
    DigraphWriter& node(const std::string& caption, const Node& node) {
... ...
@@ -408,3 +485,5 @@
408 485

	
409
    /// \e
486
    /// \brief Arc writing rule
487
    ///
488
    /// Add an arc writing rule to writer.
410 489
    DigraphWriter& arc(const std::string& caption, const Arc& arc) {
... ...
@@ -418,3 +497,8 @@
418 497

	
419
    /// \e
498
    /// \name Select section by name
499
    /// @{
500

	
501
    /// \brief Set \c \@nodes section to be read
502
    ///
503
    /// Set \c \@nodes section to be read
420 504
    DigraphWriter& nodes(const std::string& caption) {
... ...
@@ -424,3 +508,5 @@
424 508

	
425
    /// \e
509
    /// \brief Set \c \@arcs section to be read
510
    ///
511
    /// Set \c \@arcs section to be read
426 512
    DigraphWriter& arcs(const std::string& caption) {
... ...
@@ -430,3 +516,5 @@
430 516

	
431
    /// \e
517
    /// \brief Set \c \@attributes section to be read
518
    ///
519
    /// Set \c \@attributes section to be read
432 520
    DigraphWriter& attributes(const std::string& caption) {
... ...
@@ -436,2 +524,8 @@
436 524

	
525
    /// \name Skipping section
526
    /// @{
527

	
528
    /// \brief Skip writing the node set
529
    ///
530
    /// The \c \@nodes section will be not written to the stream.
437 531
    DigraphWriter& skipNodes() {
... ...
@@ -441,2 +535,5 @@
441 535

	
536
    /// \brief Skip writing arc set
537
    ///
538
    /// The \c \@arcs section will be not written to the stream.
442 539
    DigraphWriter& skipArcs() {
... ...
@@ -446,2 +543,4 @@
446 543

	
544
    /// @}
545

	
447 546
  private:
... ...
@@ -460,3 +559,3 @@
460 559
      if (!_nodes_caption.empty()) {
461
	*_os << ' ' << _nodes_caption;
560
	_writer_bits::writeToken(*_os << ' ', _nodes_caption);
462 561
      }
... ...
@@ -469,3 +568,3 @@
469 568
	   it != _node_maps.end(); ++it) {
470
	*_os << it->first << '\t';
569
	_writer_bits::writeToken(*_os, it->first) << '\t';
471 570
      }
... ...
@@ -520,3 +619,3 @@
520 619
      if (!_arcs_caption.empty()) {
521
	*_os << ' ' << _arcs_caption;
620
	_writer_bits::writeToken(*_os << ' ', _arcs_caption);
522 621
      }
... ...
@@ -530,3 +629,3 @@
530 629
	   it != _arc_maps.end(); ++it) {
531
	*_os << it->first << '\t';
630
	_writer_bits::writeToken(*_os, it->first) << '\t';
532 631
      }
... ...
@@ -579,3 +678,3 @@
579 678
      if (!_attributes_caption.empty()) {
580
	*_os << ' ' << _attributes_caption;
679
	_writer_bits::writeToken(*_os << ' ', _attributes_caption);
581 680
      }
... ...
@@ -584,3 +683,3 @@
584 683
	   it != _attributes.end(); ++it) {
585
	*_os << it->first << ' ';
684
	_writer_bits::writeToken(*_os, it->first) << ' ';
586 685
	_writer_bits::writeToken(*_os, it->second->get());
... ...
@@ -592,3 +691,8 @@
592 691
    
593
    /// \e
692
    /// \name Execution of the writer    
693
    /// @{
694

	
695
    /// \brief Start the batch processing
696
    ///
697
    /// This function starts the batch processing
594 698
    void run() {
... ...
@@ -603,8 +707,13 @@
603 707

	
604
    /// \e
605
    std::ostream& stream() {
708
    /// \brief Gives back the stream of the writer
709
    ///
710
    /// Gives back the stream of the writer
711
    std::ostream& ostream() {
606 712
      return *_os;
607 713
    }
714

	
715
    /// @}
608 716
  };
609 717

	
718
  /// \relates DigraphWriter
610 719
  template <typename Digraph>
... ...
@@ -614,2 +723,3 @@
614 723

	
724
  /// \relates DigraphWriter
615 725
  template <typename Digraph>
... ...
@@ -620,2 +730,3 @@
620 730

	
731
  /// \relates DigraphWriter
621 732
  template <typename Digraph>
0 comments (0 inline)