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
@@ -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