rley 0.3.04 → 0.3.05

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
@@ -1,4 +1,4 @@
1
- require_relative 'parse_tree_node' # Load superclass
1
+ require_relative 'parse_tree_node' # Load superclass
2
2
 
3
3
  module Rley # This module is used as a namespace
4
4
  module PTree # This module is used as a namespace
@@ -6,8 +6,8 @@ module Rley # This module is used as a namespace
6
6
  # let's assume that the integer literal '3' is the fifth input token and
7
7
  # that the '+' and '11' tokens are respectively at position 6 and 7;
8
8
  # then the token range associated with E is [5, 7]
9
- # While the parse tree/forest is being constructed the boundaries of the token range
10
- # can be temporarily undefined (= set to nil)
9
+ # While the parse tree/forest is being constructed the boundaries of the
10
+ # token range can be temporarily undefined (= set to nil)
11
11
  class TokenRange
12
12
  # The index of the lower bound of token range
13
13
  attr_reader(:low)
@@ -1,34 +1,32 @@
1
- require_relative 'composite_node'
2
-
3
- module Rley # This module is used as a namespace
4
- module SPPF # This module is used as a namespace
5
- # A node in a parse forest that is a child
6
- # of a parent node with :or refinement
7
- class AlternativeNode < CompositeNode
8
-
9
- # GFG vertex label
10
- attr_reader(:label)
11
-
12
- # Link to lhs symbol
13
- attr_reader(:symbol)
14
-
15
- # @param aVertex [ItemVertex] An GFG vertex that corresponds
16
- # a dotted item (with the dot at the end)for the alternative under
17
- # consideration.
18
- # @param aRange [TokenRange]
19
- def initialize(aVertex, aRange)
20
- super(aRange)
21
- @label = aVertex.label
22
- @symbol = aVertex.dotted_item.lhs
23
- end
24
-
25
- # Emit a (formatted) string representation of the node.
26
- # Mainly used for diagnosis/debugging purposes.
27
- def to_string(indentation)
28
- return "Alt(#{label})#{range.to_string(indentation)}"
29
- end
30
-
31
- end # class
32
- end # module
33
- end # module
34
- # End of file
1
+ require_relative 'composite_node'
2
+
3
+ module Rley # This module is used as a namespace
4
+ module SPPF # This module is used as a namespace
5
+ # A node in a parse forest that is a child
6
+ # of a parent node with :or refinement
7
+ class AlternativeNode < CompositeNode
8
+ # GFG vertex label
9
+ attr_reader(:label)
10
+
11
+ # Link to lhs symbol
12
+ attr_reader(:symbol)
13
+
14
+ # @param aVertex [ItemVertex] An GFG vertex that corresponds
15
+ # a dotted item (with the dot at the end)for the alternative under
16
+ # consideration.
17
+ # @param aRange [TokenRange]
18
+ def initialize(aVertex, aRange)
19
+ super(aRange)
20
+ @label = aVertex.label
21
+ @symbol = aVertex.dotted_item.lhs
22
+ end
23
+
24
+ # Emit a (formatted) string representation of the node.
25
+ # Mainly used for diagnosis/debugging purposes.
26
+ def to_string(indentation)
27
+ return "Alt(#{label})#{range.to_string(indentation)}"
28
+ end
29
+ end # class
30
+ end # module
31
+ end # module
32
+ # End of file
@@ -1,27 +1,27 @@
1
- require_relative 'sppf_node'
2
-
3
- module Rley # This module is used as a namespace
4
- module SPPF # This module is used as a namespace
5
- # Abstract class. The generalization for nodes that have
6
- # children node(s).
7
- class CompositeNode < SPPFNode
8
- # Array of sub-nodes.
9
- attr_reader(:subnodes)
10
-
11
- def initialize(aRange)
12
- super(aRange)
13
- @subnodes = []
14
- end
15
-
16
-
17
- def add_subnode(aSubnode)
18
- subnodes.unshift(aSubnode)
19
- end
20
-
21
- def key()
22
- @key ||= to_string(0)
23
- end
24
- end # class
25
- end # module
26
- end # module
27
- # End of file
1
+ require_relative 'sppf_node'
2
+
3
+ module Rley # This module is used as a namespace
4
+ module SPPF # This module is used as a namespace
5
+ # Abstract class. The generalization for nodes that have
6
+ # children node(s).
7
+ class CompositeNode < SPPFNode
8
+ # Array of sub-nodes.
9
+ attr_reader(:subnodes)
10
+
11
+ def initialize(aRange)
12
+ super(aRange)
13
+ @subnodes = []
14
+ end
15
+
16
+
17
+ def add_subnode(aSubnode)
18
+ subnodes.unshift(aSubnode)
19
+ end
20
+
21
+ def key()
22
+ @key ||= to_string(0)
23
+ end
24
+ end # class
25
+ end # module
26
+ end # module
27
+ # End of file
@@ -1,27 +1,26 @@
1
- require_relative 'leaf_node'
2
-
3
- module Rley # This module is used as a namespace
4
- module SPPF # This module is used as a namespace
5
- # A leaf node in a parse forest that matches an empty
6
- # string from the input
7
- class EpsilonNode < LeafNode
8
-
9
- # aPosition is the position of the token in the input stream.
10
- def initialize(aPosition)
11
- range = {low: aPosition, high: aPosition}
12
- super(range)
13
- end
14
-
15
- # Emit a (formatted) string representation of the node.
16
- # Mainly used for diagnosis/debugging purposes.
17
- def to_string(indentation)
18
- return "_#{range.to_string(indentation)}"
19
- end
20
-
21
- def key()
22
- @key ||= to_string(0)
23
- end
24
- end # class
25
- end # module
26
- end # module
27
- # End of file
1
+ require_relative 'leaf_node'
2
+
3
+ module Rley # This module is used as a namespace
4
+ module SPPF # This module is used as a namespace
5
+ # A leaf node in a parse forest that matches an empty
6
+ # string from the input
7
+ class EpsilonNode < LeafNode
8
+ # aPosition is the position of the token in the input stream.
9
+ def initialize(aPosition)
10
+ range = { low: aPosition, high: aPosition }
11
+ super(range)
12
+ end
13
+
14
+ # Emit a (formatted) string representation of the node.
15
+ # Mainly used for diagnosis/debugging purposes.
16
+ def to_string(indentation)
17
+ return "_#{range.to_string(indentation)}"
18
+ end
19
+
20
+ def key()
21
+ @key ||= to_string(0)
22
+ end
23
+ end # class
24
+ end # module
25
+ end # module
26
+ # End of file
@@ -1,12 +1,11 @@
1
- require_relative 'sppf_node'
2
-
3
- module Rley # This module is used as a namespace
4
- module SPPF # This module is used as a namespace
5
- # Abstract class. The generalization for nodes that don't have
6
- # child node.
7
- class LeafNode < SPPFNode
8
-
9
- end # class
10
- end # module
11
- end # module
12
- # End of file
1
+ require_relative 'sppf_node'
2
+
3
+ module Rley # This module is used as a namespace
4
+ module SPPF # This module is used as a namespace
5
+ # Abstract class. The generalization for nodes that don't have
6
+ # child node.
7
+ class LeafNode < SPPFNode
8
+ end # class
9
+ end # module
10
+ end # module
11
+ # End of file
@@ -1,38 +1,37 @@
1
- require_relative 'composite_node'
2
-
3
- module Rley # This module is used as a namespace
4
- module SPPF # This module is used as a namespace
5
- # A node in a parse forest that matches exactly one
6
- # non-terminal symbol
7
- class NonTerminalNode < CompositeNode
8
- # Link to the non-terminal symbol
9
- attr_reader(:symbol)
10
-
11
- # Indication on how the sub-nodes contribute to the 'success'
12
- # of parent node. Possible values: :and, :or
13
- attr_accessor :refinement
14
-
15
- def initialize(aNonTerminal, aRange)
16
- super(aRange)
17
- @symbol = aNonTerminal
18
- @refinement = :and
19
- end
20
-
21
- def add_subnode(aSubnode)
22
- if refinement == :or
23
- subnodes << aSubnode
24
- else
25
- super(aSubnode)
26
- end
27
- end
28
-
29
- # Emit a (formatted) string representation of the node.
30
- # Mainly used for diagnosis/debugging purposes.
31
- def to_string(indentation)
32
- return "#{symbol.name}#{range.to_string(indentation)}"
33
- end
34
-
35
- end # class
36
- end # module
37
- end # module
38
- # End of file
1
+ require_relative 'composite_node'
2
+
3
+ module Rley # This module is used as a namespace
4
+ module SPPF # This module is used as a namespace
5
+ # A node in a parse forest that matches exactly one
6
+ # non-terminal symbol
7
+ class NonTerminalNode < CompositeNode
8
+ # Link to the non-terminal symbol
9
+ attr_reader(:symbol)
10
+
11
+ # Indication on how the sub-nodes contribute to the 'success'
12
+ # of parent node. Possible values: :and, :or
13
+ attr_accessor :refinement
14
+
15
+ def initialize(aNonTerminal, aRange)
16
+ super(aRange)
17
+ @symbol = aNonTerminal
18
+ @refinement = :and
19
+ end
20
+
21
+ def add_subnode(aSubnode)
22
+ if refinement == :or
23
+ subnodes << aSubnode
24
+ else
25
+ super(aSubnode)
26
+ end
27
+ end
28
+
29
+ # Emit a (formatted) string representation of the node.
30
+ # Mainly used for diagnosis/debugging purposes.
31
+ def to_string(indentation)
32
+ return "#{symbol.name}#{range.to_string(indentation)}"
33
+ end
34
+ end # class
35
+ end # module
36
+ end # module
37
+ # End of file
@@ -21,4 +21,4 @@ module Rley # This module is used as a namespace
21
21
  end # class
22
22
  end # module
23
23
  end # module
24
- # End of file
24
+ # End of file
@@ -1,29 +1,29 @@
1
- require_relative 'leaf_node'
2
-
3
- module Rley # This module is used as a namespace
4
- module SPPF # This module is used as a namespace
5
- # A node in a parse forest that matches exactly one
6
- # token from the input
7
- class TokenNode < LeafNode
8
- attr_reader(:token)
9
-
10
- # aPosition is the position of the token in the input stream.
11
- def initialize(aToken, aPosition)
12
- range = {low: aPosition, high: aPosition + 1}
13
- super(range)
14
- @token = aToken
15
- end
16
-
17
- # Emit a (formatted) string representation of the node.
18
- # Mainly used for diagnosis/debugging purposes.
19
- def to_string(indentation)
20
- return "#{token.terminal.name}#{range.to_string(indentation)}"
21
- end
22
-
23
- def key()
24
- @key ||= to_string(0)
25
- end
26
- end # class
27
- end # module
28
- end # module
29
- # End of file
1
+ require_relative 'leaf_node'
2
+
3
+ module Rley # This module is used as a namespace
4
+ module SPPF # This module is used as a namespace
5
+ # A node in a parse forest that matches exactly one
6
+ # token from the input
7
+ class TokenNode < LeafNode
8
+ attr_reader(:token)
9
+
10
+ # aPosition is the position of the token in the input stream.
11
+ def initialize(aToken, aPosition)
12
+ range = { low: aPosition, high: aPosition + 1 }
13
+ super(range)
14
+ @token = aToken
15
+ end
16
+
17
+ # Emit a (formatted) string representation of the node.
18
+ # Mainly used for diagnosis/debugging purposes.
19
+ def to_string(indentation)
20
+ return "#{token.terminal.name}#{range.to_string(indentation)}"
21
+ end
22
+
23
+ def key()
24
+ @key ||= to_string(0)
25
+ end
26
+ end # class
27
+ end # module
28
+ end # module
29
+ # End of file
@@ -53,7 +53,7 @@ module Rley # This module is used as a namespace
53
53
  # Validation method. Return the validated list of productions
54
54
  def validate_productions(theProductions)
55
55
  msg = 'A grammar must have at least one production'
56
- fail StandardError, msg if theProductions.nil? || theProductions.empty?
56
+ raise StandardError, msg if theProductions.nil? || theProductions.empty?
57
57
  return theProductions
58
58
  end
59
59
 
@@ -112,8 +112,6 @@ module Rley # This module is used as a namespace
112
112
  return nullable
113
113
  end
114
114
 
115
- private
116
-
117
115
  def add_symbol(aSymbol)
118
116
  its_name = aSymbol.name
119
117
  return if name2symbol.include? its_name
@@ -70,16 +70,16 @@ module Rley # This module is used as a namespace
70
70
  # build the resulting grammar (if not yet done).
71
71
  def grammar()
72
72
  unless @grammar
73
- fail StandardError, 'No symbol found for grammar' if symbols.empty?
73
+ raise StandardError, 'No symbol found for grammar' if symbols.empty?
74
74
  if productions.empty?
75
- fail StandardError, 'No production found for grammar'
75
+ raise StandardError, 'No production found for grammar'
76
76
  end
77
77
 
78
78
  # Check that each non-terminal appears at least once in lhs.
79
79
  all_non_terminals = symbols.values.select { |s| s.is_a?(NonTerminal) }
80
80
  all_non_terminals.each do |n_term|
81
81
  next if productions.any? { |prod| n_term == prod.lhs }
82
- fail StandardError, "Nonterminal #{n_term.name} not rewritten"
82
+ raise StandardError, "Nonterminal #{n_term.name} not rewritten"
83
83
  end
84
84
 
85
85
  @grammar = Grammar.new(productions.dup)
@@ -114,11 +114,11 @@ module Rley # This module is used as a namespace
114
114
  # @param aSymbolArg [GrmSymbol-like or String]
115
115
  # @return [Array] list of grammar symbols
116
116
  def build_symbol(aClass, aSymbolArg)
117
- if aSymbolArg.kind_of?(GrmSymbol)
118
- a_symbol = aSymbolArg
119
- else
120
- a_symbol = aClass.new(aSymbolArg)
121
- end
117
+ a_symbol = if aSymbolArg.kind_of?(GrmSymbol)
118
+ aSymbolArg
119
+ else
120
+ aClass.new(aSymbolArg)
121
+ end
122
122
 
123
123
  return a_symbol
124
124
  end
@@ -6,15 +6,13 @@ module Rley # This module is used as a namespace
6
6
  # a composition of terminal or non-terminal symbols
7
7
  class NonTerminal < GrmSymbol
8
8
  attr_writer(:nullable)
9
-
9
+
10
10
  # Constructor.
11
11
  # @param aName [String] The name of the grammar symbol.
12
12
  def initialize(aName)
13
13
  super(aName)
14
14
  end
15
-
16
- public
17
-
15
+
18
16
  # @return [false/true] Return true if the symbol derives
19
17
  # the empty string. As non-terminal symbol is nullable when it can
20
18
  # can match to zero input token.
@@ -18,8 +18,8 @@ module Rley # This module is used as a namespace
18
18
 
19
19
  # Provide common alternate names to lhs and rhs accessors
20
20
 
21
- alias_method :body, :rhs
22
- alias_method :head, :lhs
21
+ alias body rhs
22
+ alias head lhs
23
23
 
24
24
  def initialize(aNonTerminal, theSymbols)
25
25
  @lhs = valid_lhs(aNonTerminal)
@@ -40,7 +40,7 @@ module Rley # This module is used as a namespace
40
40
  unless aNonTerminal.kind_of?(NonTerminal)
41
41
  msg_prefix = 'Left side of production must be a non-terminal symbol'
42
42
  msg_suffix = ", found a #{aNonTerminal.class} instead."
43
- fail StandardError, msg_prefix + msg_suffix
43
+ raise StandardError, msg_prefix + msg_suffix
44
44
  end
45
45
 
46
46
  return aNonTerminal