rley 0.3.04 → 0.3.05

Sign up to get free protection for your applications and to get access to all the features.
Files changed (99) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +7 -3
  3. data/CHANGELOG.md +3 -0
  4. data/Rakefile +30 -30
  5. data/examples/parsers/parsing_L0.rb +1 -1
  6. data/examples/parsers/parsing_L1.rb +1 -1
  7. data/examples/parsers/parsing_abc.rb +1 -1
  8. data/examples/parsers/parsing_ambig.rb +1 -1
  9. data/examples/parsers/parsing_another.rb +1 -1
  10. data/examples/parsers/parsing_b_expr.rb +1 -1
  11. data/examples/parsers/parsing_err_expr.rb +1 -1
  12. data/examples/parsers/parsing_groucho.rb +1 -1
  13. data/examples/parsers/parsing_right_recursive.rb +1 -1
  14. data/examples/parsers/parsing_tricky.rb +1 -1
  15. data/lib/rley/constants.rb +2 -2
  16. data/lib/rley/formatter/base_formatter.rb +0 -2
  17. data/lib/rley/formatter/debug.rb +0 -2
  18. data/lib/rley/formatter/json.rb +1 -3
  19. data/lib/rley/gfg/call_edge.rb +31 -30
  20. data/lib/rley/gfg/edge.rb +22 -23
  21. data/lib/rley/gfg/end_vertex.rb +22 -24
  22. data/lib/rley/gfg/epsilon_edge.rb +20 -21
  23. data/lib/rley/gfg/grm_flow_graph.rb +39 -39
  24. data/lib/rley/gfg/item_vertex.rb +16 -17
  25. data/lib/rley/gfg/non_terminal_vertex.rb +3 -4
  26. data/lib/rley/gfg/return_edge.rb +32 -31
  27. data/lib/rley/gfg/scan_edge.rb +25 -26
  28. data/lib/rley/gfg/shortcut_edge.rb +25 -26
  29. data/lib/rley/gfg/start_vertex.rb +0 -2
  30. data/lib/rley/gfg/vertex.rb +8 -8
  31. data/lib/rley/parse_forest_visitor.rb +113 -115
  32. data/lib/rley/parse_tree_visitor.rb +0 -2
  33. data/lib/rley/parser/base_parser.rb +27 -27
  34. data/lib/rley/parser/chart.rb +14 -14
  35. data/lib/rley/parser/dotted_item.rb +33 -33
  36. data/lib/rley/parser/earley_parser.rb +6 -6
  37. data/lib/rley/parser/gfg_chart.rb +8 -15
  38. data/lib/rley/parser/gfg_earley_parser.rb +15 -13
  39. data/lib/rley/parser/gfg_parsing.rb +26 -22
  40. data/lib/rley/parser/grm_items_builder.rb +3 -2
  41. data/lib/rley/parser/parse_entry.rb +3 -9
  42. data/lib/rley/parser/parse_entry_set.rb +14 -19
  43. data/lib/rley/parser/parse_entry_tracker.rb +56 -56
  44. data/lib/rley/parser/parse_forest_builder.rb +215 -214
  45. data/lib/rley/parser/parse_forest_factory.rb +57 -56
  46. data/lib/rley/parser/parse_state.rb +8 -11
  47. data/lib/rley/parser/parse_state_tracker.rb +56 -56
  48. data/lib/rley/parser/parse_tracer.rb +3 -3
  49. data/lib/rley/parser/parse_tree_builder.rb +10 -10
  50. data/lib/rley/parser/parse_walker_factory.rb +30 -33
  51. data/lib/rley/parser/parsing.rb +8 -8
  52. data/lib/rley/parser/state_set.rb +23 -26
  53. data/lib/rley/ptree/non_terminal_node.rb +1 -1
  54. data/lib/rley/ptree/token_range.rb +2 -2
  55. data/lib/rley/sppf/alternative_node.rb +32 -34
  56. data/lib/rley/sppf/composite_node.rb +27 -27
  57. data/lib/rley/sppf/epsilon_node.rb +26 -27
  58. data/lib/rley/sppf/leaf_node.rb +11 -12
  59. data/lib/rley/sppf/non_terminal_node.rb +37 -38
  60. data/lib/rley/sppf/sppf_node.rb +1 -1
  61. data/lib/rley/sppf/token_node.rb +29 -29
  62. data/lib/rley/syntax/grammar.rb +1 -3
  63. data/lib/rley/syntax/grammar_builder.rb +8 -8
  64. data/lib/rley/syntax/non_terminal.rb +2 -4
  65. data/lib/rley/syntax/production.rb +3 -3
  66. data/lib/rley/syntax/symbol_seq.rb +1 -1
  67. data/spec/rley/gfg/call_edge_spec.rb +50 -51
  68. data/spec/rley/gfg/edge_spec.rb +33 -33
  69. data/spec/rley/gfg/end_vertex_spec.rb +26 -27
  70. data/spec/rley/gfg/epsilon_edge_spec.rb +25 -25
  71. data/spec/rley/gfg/grm_flow_graph_spec.rb +1 -1
  72. data/spec/rley/gfg/item_vertex_spec.rb +3 -4
  73. data/spec/rley/gfg/return_edge_spec.rb +51 -51
  74. data/spec/rley/gfg/scan_edge_spec.rb +32 -30
  75. data/spec/rley/gfg/shortcut_edge_spec.rb +1 -1
  76. data/spec/rley/gfg/vertex_spec.rb +3 -3
  77. data/spec/rley/parse_forest_visitor_spec.rb +239 -238
  78. data/spec/rley/parser/dotted_item_spec.rb +1 -1
  79. data/spec/rley/parser/earley_parser_spec.rb +16 -16
  80. data/spec/rley/parser/gfg_earley_parser_spec.rb +30 -31
  81. data/spec/rley/parser/gfg_parsing_spec.rb +11 -10
  82. data/spec/rley/parser/grm_items_builder_spec.rb +2 -2
  83. data/spec/rley/parser/parse_entry_set_spec.rb +4 -4
  84. data/spec/rley/parser/parse_entry_spec.rb +0 -2
  85. data/spec/rley/parser/parse_forest_builder_spec.rb +82 -57
  86. data/spec/rley/parser/parse_forest_factory_spec.rb +84 -82
  87. data/spec/rley/parser/parse_walker_factory_spec.rb +10 -9
  88. data/spec/rley/parser/parsing_spec.rb +0 -1
  89. data/spec/rley/sppf/alternative_node_spec.rb +2 -2
  90. data/spec/rley/sppf/non_terminal_node_spec.rb +0 -1
  91. data/spec/rley/support/ambiguous_grammar_helper.rb +1 -1
  92. data/spec/rley/support/expectation_helper.rb +37 -36
  93. data/spec/rley/support/grammar_abc_helper.rb +17 -17
  94. data/spec/rley/support/grammar_b_expr_helper.rb +40 -39
  95. data/spec/rley/support/grammar_helper.rb +2 -1
  96. data/spec/rley/support/{grammar_L0_helper.rb → grammar_l0_helper.rb} +82 -81
  97. data/spec/rley/support/grammar_sppf_helper.rb +24 -25
  98. data/spec/rley/syntax/grammar_spec.rb +1 -1
  99. metadata +2 -2
@@ -11,17 +11,17 @@ module Rley # This module is used as a namespace
11
11
  module GFG # This module is used as a namespace
12
12
  # TODO: add definition
13
13
  class GrmFlowGraph
14
- # The set of all vertices in the graph
15
- attr_reader :vertices
14
+ # The set of all vertices in the graph
15
+ attr_reader :vertices
16
16
 
17
- # The vertex marked as start node of the graph
18
- attr_reader :start_vertex
17
+ # The vertex marked as start node of the graph
18
+ attr_reader :start_vertex
19
19
 
20
- # A Hash with pairs of the form: non-terminal symbol => start node
21
- attr_reader :start_vertex_for
20
+ # A Hash with pairs of the form: non-terminal symbol => start node
21
+ attr_reader :start_vertex_for
22
22
 
23
- # A Hash with pairs of the form: non-terminal symbol => end node
24
- attr_reader :end_vertex_for
23
+ # A Hash with pairs of the form: non-terminal symbol => end node
24
+ attr_reader :end_vertex_for
25
25
 
26
26
  def initialize(theDottedItems)
27
27
  @vertices = []
@@ -30,15 +30,16 @@ module Rley # This module is used as a namespace
30
30
 
31
31
  build_graph(theDottedItems)
32
32
  end
33
-
33
+
34
34
  # Return the vertex with given vertex label.
35
35
  def find_vertex(aVertexLabel)
36
36
  vertices.find { |a_vertex| a_vertex.label == aVertexLabel }
37
37
  end
38
38
 
39
- private
39
+ private
40
+
40
41
  def add_vertex(aVertex)
41
- fail StandardError, 'GFG vertex cannot be nil' if aVertex.nil?
42
+ raise StandardError, 'GFG vertex cannot be nil' if aVertex.nil?
42
43
 
43
44
  # TODO: make setting of start vertex more robust
44
45
  @start_vertex = aVertex if vertices.empty?
@@ -48,19 +49,16 @@ private
48
49
  def build_graph(theDottedItems)
49
50
  build_all_starts_ends(theDottedItems)
50
51
 
51
- curr_production = nil
52
+ curr_prod = nil
52
53
  theDottedItems.each_with_index do |d_item, index_item|
53
- if curr_production.nil? || curr_production != d_item.production
54
- # Another production found...
55
- curr_production = d_item.production
56
- lhs = curr_production.lhs
57
- # build_start_end_for(lhs) #Build start/end vertex per non-terminal
58
- if curr_production.empty?
59
- add_single_item(d_item)
60
- else
61
- # Add vertices and edges for dotted items of production
62
- augment_graph(theDottedItems, index_item)
63
- end
54
+ next unless curr_prod.nil? || curr_prod != d_item.production
55
+ # Another production found...
56
+ curr_prod = d_item.production
57
+ if curr_prod.empty?
58
+ add_single_item(d_item)
59
+ else
60
+ # Add vertices and edges for dotted items of production
61
+ augment_graph(theDottedItems, index_item)
64
62
  end
65
63
  end
66
64
  end
@@ -77,15 +75,15 @@ private
77
75
  # add a start vertex labelled .N
78
76
  # add an end vertex labelled N.
79
77
  def build_start_end_for(aNonTerminal)
80
- unless start_vertex_for.include?(aNonTerminal)
81
- new_start_vertex = StartVertex.new(aNonTerminal)
82
- start_vertex_for[aNonTerminal] = new_start_vertex
83
- add_vertex(new_start_vertex)
84
-
85
- new_end_vertex = EndVertex.new(aNonTerminal)
86
- end_vertex_for[aNonTerminal] = new_end_vertex
87
- add_vertex(new_end_vertex)
88
- end
78
+ return if start_vertex_for.include?(aNonTerminal)
79
+
80
+ new_start_vertex = StartVertex.new(aNonTerminal)
81
+ start_vertex_for[aNonTerminal] = new_start_vertex
82
+ add_vertex(new_start_vertex)
83
+
84
+ new_end_vertex = EndVertex.new(aNonTerminal)
85
+ end_vertex_for[aNonTerminal] = new_end_vertex
86
+ add_vertex(new_end_vertex)
89
87
  end
90
88
 
91
89
 
@@ -99,7 +97,8 @@ private
99
97
  # Add vertices and edges for dotted items derived from same production
100
98
  # production of the form: N => α[1] ... α[n] (non-empty rhs):
101
99
  # # Rule 3
102
- # create n+1 nodes labelled: N => . α[1] ... α[n], N => α[1] . ... α[n], ..., N => α[1] ... α[n] .
100
+ # create n+1 nodes labelled:
101
+ # N => . α[1] ... α[n], N => α[1] . ... α[n], ..., N => α[1] ... α[n] .
103
102
  # add an epsilon entry edge: .N -> N => . α[1] ... α[n]
104
103
  # add an epsilon exit edge: N => α[1] ... α[n] . -> N.
105
104
  # For each symbol in rhs:
@@ -110,14 +109,15 @@ private
110
109
  # Rule 5
111
110
  # add a call edge: N => α[1] .A α[n] -> .A
112
111
  # add a return edge: A. -> N => α[1] A. α[n]
113
- # add a shortcut edge: ( N => α[1] .A α[n] ) -> ( N => α[1] A. α[n] )
112
+ # add a shortcut edge:
113
+ # ( N => α[1] .A α[n] ) -> ( N => α[1] A. α[n] )
114
114
  def augment_graph(theDottedItems, firstItemPos)
115
115
  production = theDottedItems[firstItemPos].production
116
116
  max_index = production.rhs.size + 1
117
117
  prev_vertex = nil
118
-
118
+
119
119
  (0...max_index).each do |index|
120
- current_item = theDottedItems[firstItemPos+index]
120
+ current_item = theDottedItems[firstItemPos + index]
121
121
  new_vertex = ItemVertex.new(current_item)
122
122
  add_vertex(new_vertex)
123
123
  build_exit_edge(new_vertex) if current_item.reduce_item? # At end?
@@ -134,7 +134,7 @@ private
134
134
  build_call_return_edges(vertices[-2], new_vertex)
135
135
  end
136
136
  end
137
-
137
+
138
138
  prev_symbol = current_item.prev_symbol
139
139
  if prev_symbol && prev_symbol.kind_of?(Syntax::NonTerminal)
140
140
  build_shortcut_edge(prev_vertex, new_vertex)
@@ -181,7 +181,7 @@ private
181
181
  # Create an edge end vertex -> return vertex
182
182
  ReturnEdge.new(end_vertex, return_vertex)
183
183
  end
184
-
184
+
185
185
  def build_shortcut_edge(fromVertex, toVertex)
186
186
  ShortcutEdge.new(fromVertex, toVertex)
187
187
  end
@@ -189,4 +189,4 @@ private
189
189
  end # module
190
190
  end # module
191
191
 
192
- # End of file
192
+ # End of file
@@ -10,39 +10,39 @@ module Rley # This module is used as a namespace
10
10
  # Responsibilities (in addition to inherited ones):
11
11
  # - Know its related non-terminal symbol
12
12
  class ItemVertex < Vertex
13
- # Link to the dotted item object
14
- attr_reader :dotted_item
13
+ # Link to the dotted item object
14
+ attr_reader :dotted_item
15
15
 
16
- # Optional link to a "shortcut" edge.
17
- # Applicable only if the dotted expects a non-terminal symbol.
18
- attr_reader :shortcut
16
+ # Optional link to a "shortcut" edge.
17
+ # Applicable only if the dotted expects a non-terminal symbol.
18
+ attr_reader :shortcut
19
19
 
20
20
  def initialize(aDottedItem)
21
21
  super()
22
22
  @dotted_item = aDottedItem
23
23
  end
24
-
24
+
25
25
  # Set the "shortcut" edge.
26
26
  def shortcut=(aShortcut)
27
27
  unless aShortcut.kind_of?(ShortcutEdge)
28
- fail StandardError, 'Invalid shortcut argument'
28
+ raise StandardError, 'Invalid shortcut argument'
29
29
  end
30
30
  =begin
31
31
  unless next_symbol && next_symbol.kind_of?(Syntax::NonTerminal)
32
- fail StandardError, 'Invalid shortcut usage'
32
+ raise StandardError, 'Invalid shortcut usage'
33
33
  end
34
-
34
+
35
35
  shortcut_d_item = aShortcut.successor.dotted_item
36
36
  unless (dotted_item.production == shortcut_d_item.production) &&
37
37
  (dotted_item.position == shortcut_d_item.prev_position)
38
- fail StandardError, 'Shortcut refers to wrong vertex'
38
+ raise StandardError, 'Shortcut refers to wrong vertex'
39
39
  end
40
- =end
40
+ =end
41
41
  @shortcut = aShortcut
42
42
  end
43
43
 
44
44
  def label()
45
- return "#{dotted_item}"
45
+ return dotted_item.to_s
46
46
  end
47
47
 
48
48
  # Returns true if the dotted item has a dot at the end of the production.
@@ -53,20 +53,19 @@ module Rley # This module is used as a namespace
53
53
  # Return the symbol before the dot else nil.
54
54
  def prev_symbol()
55
55
  return dotted_item.prev_symbol
56
- end
57
-
56
+ end
57
+
58
58
  # Return the symbol after the dot else nil.
59
59
  def next_symbol()
60
60
  return dotted_item.next_symbol
61
61
  end
62
-
62
+
63
63
  # Return the non-terminal symbol at the left-hand side of the production
64
64
  def lhs()
65
65
  return dotted_item.lhs
66
66
  end
67
-
68
67
  end # class
69
68
  end # module
70
69
  end # module
71
70
 
72
- # End of file
71
+ # End of file
@@ -8,23 +8,22 @@ module Rley # This module is used as a namespace
8
8
  # Responsibilities (in addition to inherited ones):
9
9
  # - Know its related non-terminal symbol
10
10
  class NonTerminalVertex < Vertex
11
- attr_reader :non_terminal
11
+ attr_reader :non_terminal
12
12
 
13
13
  def initialize(aNonTerminal)
14
14
  super()
15
15
  @non_terminal = aNonTerminal
16
16
  end
17
17
 
18
- protected
18
+ protected
19
19
 
20
20
  # Validation method for adding an outgoing edge to the vertex.
21
21
  # A start vertex may accept an indegree and outdegree greater than one
22
22
  def check_add_edge(anEdge)
23
23
  return anEdge
24
24
  end
25
-
26
25
  end # class
27
26
  end # module
28
27
  end # module
29
28
 
30
- # End of file
29
+ # End of file
@@ -1,31 +1,32 @@
1
- require_relative 'edge'
2
-
3
- module Rley # This module is used as a namespace
4
- module GFG # This module is used as a namespace
5
- # Specialization of an edge in a grammar flow graph
6
- # that has a end vertex (X.) as its head
7
- # and an item vertex as its tail
8
-
9
- # Responsibilities:
10
- # - To know the successor vertex (tail)
11
- class ReturnEdge < Edge
12
- attr_reader(:key)
13
-
14
- # Pre-condition: thePredecessor is an EndVertex
15
- # Pre-condition: theSuccessor is an ItemVertex
16
- def initialize(thePredecessor, theSuccessor)
17
- super(thePredecessor, theSuccessor)
18
- do_set_key(thePredecessor, theSuccessor)
19
- end
20
-
21
- private
22
- def do_set_key(thePredecessor, theSuccessor)
23
- tail_d_item = theSuccessor.dotted_item
24
- @key = "RET_#{tail_d_item.production.object_id}_#{tail_d_item.prev_position}"
25
- end
26
-
27
- end # class
28
- end # module
29
- end # module
30
-
31
- # End of file
1
+ require_relative 'edge'
2
+
3
+ module Rley # This module is used as a namespace
4
+ module GFG # This module is used as a namespace
5
+ # Specialization of an edge in a grammar flow graph
6
+ # that has a end vertex (X.) as its head
7
+ # and an item vertex as its tail
8
+
9
+ # Responsibilities:
10
+ # - To know the successor vertex (tail)
11
+ class ReturnEdge < Edge
12
+ attr_reader(:key)
13
+
14
+ # Pre-condition: thePredecessor is an EndVertex
15
+ # Pre-condition: theSuccessor is an ItemVertex
16
+ def initialize(thePredecessor, theSuccessor)
17
+ super(thePredecessor, theSuccessor)
18
+ do_set_key(thePredecessor, theSuccessor)
19
+ end
20
+
21
+ private
22
+
23
+ def do_set_key(_thePredecessor, theSuccessor)
24
+ tail_d_item = theSuccessor.dotted_item
25
+ prefix = "RET_#{tail_d_item.production.object_id}_"
26
+ @key = prefix + tail_d_item.prev_position.to_s
27
+ end
28
+ end # class
29
+ end # module
30
+ end # module
31
+
32
+ # End of file
@@ -1,26 +1,25 @@
1
- require_relative 'edge'
2
-
3
- module Rley # This module is used as a namespace
4
- module GFG # This module is used as a namespace
5
- # Specialization of an edge in a grammar flow graph
6
- # that is taken as a consequence of a scan rule.
7
- # Responsibilities:
8
- # - To know the successor vertex
9
- class ScanEdge < Edge
10
- # The terminal symbol expected from the input stream
11
- attr_reader :terminal
12
-
13
- def initialize(thePredecessor, theSuccessor, aTerminal)
14
- super(thePredecessor, theSuccessor)
15
- @terminal = aTerminal
16
- end
17
-
18
- def to_s()
19
- " -#{terminal}-> #{successor.label}"
20
- end
21
-
22
- end # class
23
- end # module
24
- end # module
25
-
26
- # End of file
1
+ require_relative 'edge'
2
+
3
+ module Rley # This module is used as a namespace
4
+ module GFG # This module is used as a namespace
5
+ # Specialization of an edge in a grammar flow graph
6
+ # that is taken as a consequence of a scan rule.
7
+ # Responsibilities:
8
+ # - To know the successor vertex
9
+ class ScanEdge < Edge
10
+ # The terminal symbol expected from the input stream
11
+ attr_reader :terminal
12
+
13
+ def initialize(thePredecessor, theSuccessor, aTerminal)
14
+ super(thePredecessor, theSuccessor)
15
+ @terminal = aTerminal
16
+ end
17
+
18
+ def to_s()
19
+ " -#{terminal}-> #{successor.label}"
20
+ end
21
+ end # class
22
+ end # module
23
+ end # module
24
+
25
+ # End of file
@@ -1,26 +1,25 @@
1
- require_relative 'edge'
2
-
3
- module Rley # This module is used as a namespace
4
- module GFG # This module is used as a namespace
5
- # Abstract class. Represents an edge in a grammar flow graph
6
- # Responsibilities:
7
- # - To know the successor vertex
8
- class ShortcutEdge < Edge
9
- # The terminal symbol expected from the input stream
10
- attr_reader :nonterminal
11
-
12
- def initialize(thePredecessor, theSuccessor)
13
- @successor = theSuccessor
14
- @nonterminal = thePredecessor.next_symbol
15
- thePredecessor.shortcut = self
16
- end
17
-
18
- def to_s()
19
- " -#{nonterminal}-> #{successor.label}"
20
- end
21
-
22
- end # class
23
- end # module
24
- end # module
25
-
26
- # End of file
1
+ require_relative 'edge'
2
+
3
+ module Rley # This module is used as a namespace
4
+ module GFG # This module is used as a namespace
5
+ # Abstract class. Represents an edge in a grammar flow graph
6
+ # Responsibilities:
7
+ # - To know the successor vertex
8
+ class ShortcutEdge < Edge
9
+ # The terminal symbol expected from the input stream
10
+ attr_reader :nonterminal
11
+
12
+ def initialize(thePredecessor, theSuccessor)
13
+ @successor = theSuccessor
14
+ @nonterminal = thePredecessor.next_symbol
15
+ thePredecessor.shortcut = self
16
+ end
17
+
18
+ def to_s()
19
+ " -#{nonterminal}-> #{successor.label}"
20
+ end
21
+ end # class
22
+ end # module
23
+ end # module
24
+
25
+ # End of file
@@ -8,7 +8,6 @@ module Rley # This module is used as a namespace
8
8
  # Responsibilities (in addition to inherited ones):
9
9
  # - Know its related non-terminal symbol
10
10
  class StartVertex < NonTerminalVertex
11
-
12
11
  def initialize(aNonTerminal)
13
12
  super(aNonTerminal)
14
13
  end
@@ -16,7 +15,6 @@ module Rley # This module is used as a namespace
16
15
  def label()
17
16
  return ".#{non_terminal}"
18
17
  end
19
-
20
18
  end # class
21
19
  end # module
22
20
  end # module
@@ -18,31 +18,31 @@ module Rley # This module is used as a namespace
18
18
  edges << arrow
19
19
  end
20
20
 
21
- # Returns true iff the vertex corresponds to an dotted item that has its dot
22
- # at the end of a production (i.e. is a reduced item).
21
+ # Returns true iff the vertex corresponds to an dotted item that has
22
+ # its dot at the end of a production (i.e. is a reduced item).
23
23
  def complete?()
24
- return false # Default implementation
24
+ return false # Default implementation
25
25
  end
26
26
 
27
27
  # Return the symbol before the dot else nil.
28
28
  def prev_symbol()
29
- return nil # Default implementation
29
+ return nil # Default implementation
30
30
  end
31
31
 
32
32
  # Return the symbol after the dot else nil.
33
33
  def next_symbol()
34
- return nil # Default implementation
34
+ return nil # Default implementation
35
35
  end
36
36
 
37
- protected
37
+ protected
38
+
38
39
  # Validation method for adding an outgoing edge to the vertex.
39
40
  # Vertices will accept an indegree and outdegree of at most one
40
41
  # unless this method is overridden in subclasses
41
42
  def check_add_edge(anEdge)
42
- fail StandardError, 'At most one edge accepted' unless edges.empty?
43
+ raise StandardError, 'At most one edge accepted' unless edges.empty?
43
44
  return anEdge
44
45
  end
45
-
46
46
  end # class
47
47
  end # module
48
48
  end # module