rley 0.8.14 → 0.9.01

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 (106) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +20 -2
  3. data/CHANGELOG.md +14 -0
  4. data/Gemfile +8 -0
  5. data/examples/general/calc_iter1/spec/calculator_spec.rb +9 -9
  6. data/examples/general/calc_iter2/spec/calculator_spec.rb +39 -39
  7. data/examples/general/recursive_right.rb +2 -2
  8. data/lib/rley/constants.rb +2 -2
  9. data/lib/rley/engine.rb +3 -1
  10. data/lib/rley/formatter/asciitree.rb +4 -1
  11. data/lib/rley/gfg/epsilon_edge.rb +0 -2
  12. data/lib/rley/gfg/grm_flow_graph.rb +7 -9
  13. data/lib/rley/gfg/item_vertex.rb +1 -1
  14. data/lib/rley/gfg/vertex.rb +11 -0
  15. data/lib/rley/lexical/token.rb +10 -3
  16. data/lib/rley/parse_forest_visitor.rb +3 -3
  17. data/lib/rley/parse_rep/ast_base_builder.rb +6 -5
  18. data/lib/rley/parse_rep/parse_forest_builder.rb +4 -2
  19. data/lib/rley/parse_rep/parse_tree_builder.rb +14 -2
  20. data/lib/rley/parse_rep/parse_tree_factory.rb +1 -1
  21. data/lib/rley/parser/error_reason.rb +2 -2
  22. data/lib/rley/parser/gfg_chart.rb +2 -2
  23. data/lib/rley/parser/gfg_earley_parser.rb +2 -2
  24. data/lib/rley/parser/gfg_parsing.rb +1 -1
  25. data/lib/rley/parser/parse_entry.rb +4 -4
  26. data/lib/rley/parser/parse_entry_set.rb +4 -2
  27. data/lib/rley/parser/parse_entry_tracker.rb +10 -7
  28. data/lib/rley/parser/parse_walker_factory.rb +9 -8
  29. data/lib/rley/ptree/parse_tree_node.rb +6 -0
  30. data/lib/rley/ptree/terminal_node.rb +1 -1
  31. data/lib/rley/rgn/ast_builder.rb +2 -2
  32. data/lib/rley/rgn/ast_node.rb +11 -1
  33. data/lib/rley/rgn/ast_visitor.rb +2 -2
  34. data/lib/rley/rgn/composite_node.rb +1 -1
  35. data/lib/rley/rgn/grammar_builder.rb +12 -14
  36. data/lib/rley/rgn/parser.rb +2 -2
  37. data/lib/rley/rgn/tokenizer.rb +1 -1
  38. data/lib/rley/rley_error.rb +0 -4
  39. data/lib/rley/sppf/composite_node.rb +6 -0
  40. data/lib/rley/sppf/parse_forest.rb +7 -7
  41. data/lib/rley/sppf/sppf_node.rb +15 -1
  42. data/lib/rley/syntax/base_grammar_builder.rb +3 -12
  43. data/lib/rley/syntax/grammar.rb +9 -4
  44. data/lib/rley/syntax/production.rb +1 -1
  45. data/spec/rley/base/dotted_item_spec.rb +46 -46
  46. data/spec/rley/base/grm_items_builder_spec.rb +1 -1
  47. data/spec/rley/engine_spec.rb +50 -50
  48. data/spec/rley/formatter/asciitree_spec.rb +8 -8
  49. data/spec/rley/formatter/bracket_notation_spec.rb +10 -10
  50. data/spec/rley/formatter/debug_spec.rb +10 -10
  51. data/spec/rley/formatter/json_spec.rb +6 -7
  52. data/spec/rley/gfg/call_edge_spec.rb +6 -6
  53. data/spec/rley/gfg/edge_spec.rb +8 -7
  54. data/spec/rley/gfg/end_vertex_spec.rb +8 -7
  55. data/spec/rley/gfg/epsilon_edge_spec.rb +5 -4
  56. data/spec/rley/gfg/grm_flow_graph_spec.rb +33 -34
  57. data/spec/rley/gfg/item_vertex_spec.rb +34 -36
  58. data/spec/rley/gfg/non_terminal_vertex_spec.rb +12 -12
  59. data/spec/rley/gfg/return_edge_spec.rb +6 -6
  60. data/spec/rley/gfg/scan_edge_spec.rb +7 -6
  61. data/spec/rley/gfg/shortcut_edge_spec.rb +15 -15
  62. data/spec/rley/gfg/start_vertex_spec.rb +8 -8
  63. data/spec/rley/gfg/vertex_spec.rb +18 -18
  64. data/spec/rley/lexical/literal_spec.rb +5 -5
  65. data/spec/rley/lexical/token_range_spec.rb +55 -55
  66. data/spec/rley/lexical/token_spec.rb +17 -16
  67. data/spec/rley/parse_forest_visitor_spec.rb +30 -32
  68. data/spec/rley/parse_rep/ambiguous_parse_spec.rb +2 -2
  69. data/spec/rley/parse_rep/ast_builder_spec.rb +30 -30
  70. data/spec/rley/parse_rep/cst_builder_spec.rb +85 -85
  71. data/spec/rley/parse_rep/groucho_spec.rb +23 -23
  72. data/spec/rley/parse_rep/parse_forest_builder_spec.rb +42 -42
  73. data/spec/rley/parse_rep/parse_forest_factory_spec.rb +10 -12
  74. data/spec/rley/parse_rep/parse_tree_factory_spec.rb +10 -15
  75. data/spec/rley/parse_tree_visitor_spec.rb +43 -46
  76. data/spec/rley/parser/dangling_else_spec.rb +12 -12
  77. data/spec/rley/parser/error_reason_spec.rb +37 -37
  78. data/spec/rley/parser/gfg_chart_spec.rb +27 -29
  79. data/spec/rley/parser/gfg_earley_parser_spec.rb +55 -56
  80. data/spec/rley/parser/gfg_parsing_spec.rb +106 -103
  81. data/spec/rley/parser/parse_entry_set_spec.rb +63 -61
  82. data/spec/rley/parser/parse_entry_spec.rb +73 -71
  83. data/spec/rley/parser/parse_walker_factory_spec.rb +14 -15
  84. data/spec/rley/ptree/non_terminal_node_spec.rb +16 -16
  85. data/spec/rley/ptree/parse_tree_node_spec.rb +11 -11
  86. data/spec/rley/ptree/parse_tree_spec.rb +6 -8
  87. data/spec/rley/ptree/terminal_node_spec.rb +6 -6
  88. data/spec/rley/rgn/grammar_builder_spec.rb +69 -67
  89. data/spec/rley/rgn/parser_spec.rb +63 -63
  90. data/spec/rley/rgn/repetition_node_spec.rb +15 -15
  91. data/spec/rley/rgn/sequence_node_spec.rb +10 -10
  92. data/spec/rley/rgn/symbol_node_spec.rb +5 -6
  93. data/spec/rley/rgn/tokenizer_spec.rb +68 -67
  94. data/spec/rley/sppf/alternative_node_spec.rb +16 -16
  95. data/spec/rley/sppf/non_terminal_node_spec.rb +20 -20
  96. data/spec/rley/sppf/token_node_spec.rb +13 -13
  97. data/spec/rley/syntax/base_grammar_builder_spec.rb +76 -86
  98. data/spec/rley/syntax/grammar_spec.rb +40 -78
  99. data/spec/rley/syntax/grm_symbol_spec.rb +7 -7
  100. data/spec/rley/syntax/match_closest_spec.rb +8 -8
  101. data/spec/rley/syntax/non_terminal_spec.rb +25 -25
  102. data/spec/rley/syntax/production_spec.rb +33 -33
  103. data/spec/rley/syntax/symbol_seq_spec.rb +27 -27
  104. data/spec/rley/syntax/terminal_spec.rb +12 -11
  105. data/spec/support/base_tokenizer_spec.rb +9 -8
  106. metadata +8 -25
@@ -148,7 +148,7 @@ module Rley # This module is used as a namespace
148
148
  # ... without changing current path
149
149
  create_epsilon_node(anEntry, anIndex)
150
150
  end
151
- curr_path.pop if curr_parent.kind_of?(SPPF::AlternativeNode)
151
+ curr_path.pop if curr_parent.is_a?(SPPF::AlternativeNode)
152
152
  end
153
153
 
154
154
  when :backtrack
@@ -172,7 +172,7 @@ module Rley # This module is used as a namespace
172
172
  # ... without changing current path
173
173
  create_epsilon_node(anEntry, anIndex)
174
174
  end
175
- curr_path.pop if curr_parent.kind_of?(SPPF::AlternativeNode)
175
+ curr_path.pop if curr_parent.is_a?(SPPF::AlternativeNode)
176
176
  end
177
177
  end
178
178
  end
@@ -221,6 +221,8 @@ module Rley # This module is used as a namespace
221
221
 
222
222
  def create_epsilon_node(anEntry, anIndex)
223
223
  new_node = SPPF::EpsilonNode.new(anIndex)
224
+
225
+ # @type var candidate : SPPF::EpsilonNode
224
226
  candidate = add_node_to_forest(new_node)
225
227
  entry2node[anEntry] = candidate
226
228
 
@@ -19,6 +19,7 @@ module Rley # This module is used as a namespace
19
19
  # @param aSymbol [Syntax::Symbol] A symbol from grammar.
20
20
  def initialize(aRange, aSymbol)
21
21
  super
22
+ # @type self:CSTRawNode
22
23
  self.range = aRange
23
24
  self.symbol = aSymbol
24
25
  self.children = nil
@@ -77,7 +78,7 @@ module Rley # This module is used as a namespace
77
78
 
78
79
  protected
79
80
 
80
- # Return the stack
81
+ # Return the stack of CSTRawNode
81
82
  attr_reader(:stack)
82
83
 
83
84
  # Overriding method.
@@ -180,6 +181,7 @@ module Rley # This module is used as a namespace
180
181
  # For debugging purposes
181
182
  raise StandardError if previous_tos.symbol != non_terminal
182
183
 
184
+ # @type var previous_tos : CSTRawNode
183
185
  new_node = new_parent_node(rule, previous_tos.range,
184
186
  tokens, previous_tos.children)
185
187
  if stack.empty?
@@ -207,7 +209,9 @@ module Rley # This module is used as a namespace
207
209
  # @param anEntry [ParseEntry] The entry being visited
208
210
  def terminal_before_dot?(anEntry)
209
211
  prev_symbol = anEntry.prev_symbol
210
- prev_symbol&.terminal?
212
+
213
+ # @type var prev_symbol : Syntax::GrmSymbol
214
+ prev_symbol.terminal?
211
215
  end
212
216
 
213
217
  # A terminal symbol was detected at left of dot.
@@ -262,6 +266,14 @@ module Rley # This module is used as a namespace
262
266
 
263
267
  non_terminal
264
268
  end
269
+
270
+ def new_leaf_node(_aProduction, _aTerminal, _aTokenPosition, _aToken)
271
+ raise NotImplementedError
272
+ end
273
+
274
+ def new_parent_node(_aProduction, _aRange, _theTokens, _theChildren)
275
+ raise NotImplementedError
276
+ end
265
277
  end # class
266
278
  end # module
267
279
  end # module
@@ -15,7 +15,7 @@ module Rley # This module is used as a namespace
15
15
  # that will create piece by piece the forest
16
16
  def builder(aParseResult, aBuilder = nil)
17
17
  if aBuilder
18
- aBuilder.new(aParseResult.tokens)
18
+ aBuilder.new(aParseResult.tokens) # steep:ignore UnexpectedPositionalArgument
19
19
  else
20
20
  CSTBuilder.new(aParseResult.tokens)
21
21
  end
@@ -7,11 +7,11 @@ module Rley # Module used as a namespace
7
7
  # detected by Rley.
8
8
  class ErrorReason
9
9
  # @!attribute [r] rank
10
- # @return [Fixnum] The rank number of the offending input token
10
+ # @return [Integer] The rank number of the offending input token
11
11
  attr_reader(:rank)
12
12
 
13
13
  # Constructor
14
- # @param aRank [Fixnum] The sequence number of the offending input token.
14
+ # @param aRank [Integer] The sequence number of the offending input token.
15
15
  def initialize(aRank)
16
16
  @rank = aRank
17
17
  end
@@ -98,7 +98,7 @@ module Rley # This module is used as a namespace
98
98
  new_entry = ParseEntry.new(aVertex, anOrigin)
99
99
  result = self[anIndex].push_entry(new_entry)
100
100
 
101
- if aVertex.kind_of?(GFG::ItemVertex) && aVertex.dotted_item.constraint
101
+ if aVertex.is_a?(GFG::ItemVertex) && aVertex.dotted_item.constraint
102
102
  ct = aVertex.dotted_item.constraint
103
103
 
104
104
  case ct
@@ -198,8 +198,8 @@ module Rley # This module is used as a namespace
198
198
  private
199
199
 
200
200
  def add_entry_set
201
- @sets << ParseEntrySet.new
202
201
  @constraints << []
202
+ @sets << ParseEntrySet.new
203
203
  end
204
204
 
205
205
  def update_match_closest(aConstraint, anIndex)
@@ -32,7 +32,7 @@ module Rley # This module is used as a namespace
32
32
 
33
33
  aTokenSequence.each_with_index do |token, i|
34
34
  parse_for_token(result, i)
35
- if token.terminal.kind_of?(String)
35
+ if token.terminal.is_a?(String)
36
36
  symb = grammar.name2symbol[token.terminal]
37
37
  token.instance_variable_set(:@terminal, symb)
38
38
  end
@@ -51,7 +51,7 @@ module Rley # This module is used as a namespace
51
51
  result.chart[index].each do |entry|
52
52
  # Is entry of the form? [A => alpha . B beta, k]...
53
53
  next_symbol = entry.next_symbol
54
- if next_symbol.kind_of?(Syntax::NonTerminal)
54
+ if next_symbol.is_a?(Syntax::NonTerminal)
55
55
  # ...apply the Call rule
56
56
  call_rule(result, entry, index)
57
57
  end
@@ -338,7 +338,7 @@ module Rley # This module is used as a namespace
338
338
  full_range = { low: 0, high: anIndex }
339
339
  start_production = chart.start_dotted_rule.production
340
340
 
341
- ParseForestBuilder.new(start_production, full_range)
341
+ ParseRep::ParseForestBuilder.new(start_production, full_range)
342
342
  end
343
343
 
344
344
  # Factory method. Creates and initializes a ParseEntryTracker instance.
@@ -62,13 +62,13 @@ module Rley # This module is used as a namespace
62
62
 
63
63
  # Returns true iff the vertex is a start vertex (i.e. of the form: .X)
64
64
  def start_entry?
65
- vertex.kind_of?(GFG::StartVertex)
65
+ vertex.is_a?(GFG::StartVertex)
66
66
  end
67
67
 
68
68
  # Returns true iff the vertex is at the start of rhs
69
69
  # (i.e. of the form: X => .Y
70
70
  def entry_entry?
71
- return false unless vertex.kind_of?(GFG::ItemVertex)
71
+ return false unless vertex.is_a?(GFG::ItemVertex)
72
72
 
73
73
  vertex.dotted_item.at_start?
74
74
  end
@@ -76,7 +76,7 @@ module Rley # This module is used as a namespace
76
76
  # Returns true iff the vertex corresponds to a dotted item
77
77
  # X => Y
78
78
  def dotted_entry?
79
- vertex.kind_of?(GFG::ItemVertex)
79
+ vertex.is_a?(GFG::ItemVertex)
80
80
  end
81
81
 
82
82
  # Returns true iff the vertex is at end of rhs (i.e. of the form: X => Y.)
@@ -86,7 +86,7 @@ module Rley # This module is used as a namespace
86
86
 
87
87
  # Returns true iff the vertex is an end vertex (i.e. of the form: X.)
88
88
  def end_entry?
89
- vertex.kind_of?(GFG::EndVertex)
89
+ vertex.is_a?(GFG::EndVertex)
90
90
  end
91
91
 
92
92
  # Return the symbol before the dot (if any)
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'forwardable' # For the Delegation pattern
4
- require 'set'
5
4
 
6
5
  require_relative '../syntax/terminal'
7
6
  require_relative '../syntax/non_terminal'
@@ -63,6 +62,7 @@ module Rley # This module is used as a namespace
63
62
  # @return [ParseEntry] the passed parse entry if it pushes it
64
63
  def push_entry(anEntry)
65
64
  entry_key = anEntry.hash
65
+ # @type var result : ParseEntry | false
66
66
  result = membership.fetch(entry_key, false)
67
67
  unless result
68
68
  @entries << anEntry
@@ -72,6 +72,7 @@ module Rley # This module is used as a namespace
72
72
  result = anEntry
73
73
  end
74
74
 
75
+ # @type var result : ParseEntry
75
76
  result
76
77
  end
77
78
 
@@ -112,9 +113,10 @@ module Rley # This module is used as a namespace
112
113
 
113
114
  def add_lookup4symbol(anEntry)
114
115
  symb = anEntry.next_symbol
115
- if symb.kind_of?(Syntax::Terminal)
116
+ if symb.is_a?(Syntax::Terminal)
116
117
  @entries4term[symb] << anEntry
117
118
  else
119
+ # @type var symb : Syntax::NonTerminal
118
120
  @entries4n_term[symb] << anEntry
119
121
  end
120
122
  end
@@ -21,31 +21,34 @@ module Rley # This module is used as a namespace
21
21
 
22
22
  # Write accessor. Sets the value of the entry set index
23
23
  def entry_set_index=(anIndex)
24
- @entry_set_index = anIndex
25
24
  @processed_entries = {}
25
+ @entry_set_index = anIndex
26
26
  end
27
27
 
28
28
  # Write accessor. Set the given parse entry as the current one.
29
29
  def parse_entry=(aParseEntry)
30
30
  raise StandardError, 'Nil parse entry' if aParseEntry.nil?
31
31
 
32
- @parse_entry = aParseEntry
32
+ # @type var parse_entry : Rley::Parser::ParseEntry
33
33
  processed_entries[parse_entry] = true
34
+ @parse_entry = aParseEntry
34
35
  end
35
36
 
36
37
  # Take the first provided entry that wasn't processed yet.
37
- def select_entry(theEntrys)
38
- a_entry = theEntrys.find { |st| !processed_entries.include?(st) }
39
- self.parse_entry = a_entry
38
+ def select_entry(entries)
39
+ a_entry = entries.find { |st| !processed_entries.include?(st) }
40
+ self.parse_entry = a_entry # steep:ignore
40
41
  end
41
42
 
42
43
  # The dotted item for the current parse entry.
44
+ # @return [Rley::Base::DottedItem, nil]
43
45
  def curr_dotted_item
44
- parse_entry.dotted_rule
46
+ parse_entry&.vertex.dotted_item # steep:ignore
45
47
  end
46
48
 
49
+ # @return [Syntax::GrmSymbol, nil] Return the symbol before the dot
47
50
  def symbol_on_left
48
- curr_dotted_item.prev_symbol
51
+ curr_dotted_item&.prev_symbol
49
52
  end
50
53
 
51
54
  # Notification that one begins with the previous entry set
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'set'
4
3
  require_relative '../gfg/call_edge'
5
4
  require_relative '../gfg/scan_edge'
6
5
  require_relative '../gfg/epsilon_edge'
@@ -119,8 +118,9 @@ module Rley # This module is used as a namespace
119
118
  # rubocop: disable Lint/DuplicateBranch
120
119
  def visit_entry(anEntry, aContext)
121
120
  index = aContext.entry_set_index
122
- aContext.nterm2start[[anEntry, index]] if anEntry.start_entry?
121
+ aContext.nterm2start[[anEntry, index]] if anEntry.start_entry? # steep:ignore
123
122
 
123
+ # @type var event : [Symbol, ParseEntry, Integer]
124
124
  if aContext.visitees.include?(anEntry) # Already visited?...
125
125
  case anEntry.vertex
126
126
  when GFG::EndVertex
@@ -156,8 +156,8 @@ module Rley # This module is used as a namespace
156
156
  end
157
157
  # rubocop: enable Lint/DuplicateBranch
158
158
 
159
- def detect_scan_edge(_ctx)
160
- nil unless aContext.curr_entry.dotted_entry?
159
+ def detect_scan_edge(ctx)
160
+ nil unless ctx.curr_entry.dotted_entry?
161
161
  end
162
162
 
163
163
  # Given the current entry from context object
@@ -179,22 +179,22 @@ module Rley # This module is used as a namespace
179
179
  new_entry = aContext.curr_entry.antecedents.first
180
180
  events = [new_entry]
181
181
  traversed_edge = new_entry.vertex.edges.first
182
- if new_entry.vertex.kind_of?(GFG::EndVertex)
182
+ if new_entry.vertex.is_a?(GFG::EndVertex)
183
183
  # Return edge encountered
184
184
  # Push current entry onto stack
185
185
  # puts "Push on return stack #{aContext.curr_entry}"
186
186
  aContext.return_stack << aContext.curr_entry
187
- elsif traversed_edge.kind_of?(GFG::CallEdge)
187
+ elsif traversed_edge.is_a?(GFG::CallEdge)
188
188
  # Pop top of stack
189
189
  err_msg = 'Return stack empty!'
190
190
  raise ScriptError, err_msg if aContext.return_stack.empty?
191
191
 
192
192
  aContext.return_stack.pop
193
193
  # puts "Pop from return stack matching entry #{new_entry}"
194
- elsif traversed_edge.kind_of?(GFG::ScanEdge)
194
+ elsif traversed_edge.is_a?(GFG::ScanEdge)
195
195
  # Scan edge encountered, decrease sigma set index
196
196
  aContext.entry_set_index -= 1
197
- elsif traversed_edge.kind_of?(GFG::EpsilonEdge)
197
+ elsif traversed_edge.is_a?(GFG::EpsilonEdge)
198
198
  # Do nothing
199
199
  else
200
200
  raise NotImplementedError, "edge is a #{traversed_edge.class}"
@@ -270,6 +270,7 @@ module Rley # This module is used as a namespace
270
270
  raise ScriptError, 'Empty return stack' if aContext.return_stack.empty?
271
271
 
272
272
  # Retrieve top of stack
273
+ # @type var tos : Rley::Parser::ParseEntry
273
274
  tos = aContext.return_stack.pop
274
275
  tos_dotted_item = tos.vertex.dotted_item
275
276
 
@@ -37,6 +37,12 @@ module Rley # This module is used as a namespace
37
37
  def to_s
38
38
  "#{symbol.name}#{range.to_string(0)}"
39
39
  end
40
+
41
+ # Part of the 'visitee' role in Visitor design pattern.
42
+ # @param aVisitor[ParseTreeVisitor] the visitor
43
+ def accept(aVisitor)
44
+ raise NotImplementedError
45
+ end
40
46
  end # class
41
47
  end # module
42
48
  end # module
@@ -14,7 +14,7 @@ module Rley # This module is used as a namespace
14
14
  # (major, minor) =
15
15
 
16
16
  # Use '1.class' trick to support both Integer and Fixnum classes
17
- range = aPos.kind_of?(1.class) ? { low: aPos, high: aPos + 1 } : aPos
17
+ range = aPos.is_a?(1.class) ? { low: aPos, high: aPos + 1 } : aPos
18
18
  super(aToken.terminal, range)
19
19
  @token = aToken
20
20
  end
@@ -29,7 +29,7 @@ module Rley
29
29
  protected
30
30
 
31
31
  def terminal2node
32
- Terminal2NodeClass
32
+ Terminal2NodeClass # steep:ignore UnknownConstant
33
33
  end
34
34
 
35
35
  # Method override
@@ -166,7 +166,7 @@ module Rley
166
166
  # rule('key_value' => 'KEY value')
167
167
  def reduce_raw_pair(_production, _range, _tokens, theChildren)
168
168
  key = theChildren[0].token.lexeme
169
- value = if theChildren[1].kind_of?(Rley::PTree::TerminalNode)
169
+ value = if theChildren[1].is_a?(Rley::PTree::TerminalNode)
170
170
  theChildren[1].token.lexeme
171
171
  else
172
172
  theChildren[1]
@@ -22,7 +22,7 @@ module Rley
22
22
  def annotation_to_text
23
23
  map_arr = []
24
24
  @annotation.each_pair do |key, val|
25
- literal = val.kind_of?(String) ? "'#{val}'" : val
25
+ literal = val.is_a?(String) ? "'#{val}'" : val
26
26
  map_arr << "#{key}: #{literal}"
27
27
  end
28
28
 
@@ -34,6 +34,16 @@ module Rley
34
34
  # Default: do nothing ...
35
35
  end
36
36
 
37
+ # @nodoc
38
+ def name
39
+ raise NotImplementedError
40
+ end
41
+
42
+ # @nodoc
43
+ def to_text
44
+ raise NotImplementedError
45
+ end
46
+
37
47
  # Abstract method (must be overriden in subclasses).
38
48
  # Part of the 'visitee' role in Visitor design pattern.
39
49
  # @param _visitor [ASTVisitor] the visitor
@@ -75,7 +75,7 @@ module Rley
75
75
 
76
76
  # Visit event. The visitor is about to visit the subnodes of a non
77
77
  # terminal node.
78
- # @param aParentNode [Ast::LocCompoundExpr] the parent node.
78
+ # @param aParentNode [CompositeNode] the parent node.
79
79
  def traverse_subnodes(aParentNode)
80
80
  subnodes = aParentNode.subnodes
81
81
  broadcast(:before_subnodes, aParentNode, subnodes)
@@ -88,7 +88,7 @@ module Rley
88
88
 
89
89
  # Visit event. The visitor is about to visit one given subnode of a non
90
90
  # terminal node.
91
- # @param aParentNode [Ast::LocCompoundExpr] the parent node.
91
+ # @param aParentNode [CompositeNode] the parent node.
92
92
  # @param index [integer] index of child subnode
93
93
  def traverse_given_subnode(aParentNode, index)
94
94
  subnode = aParentNode.subnodes[index]
@@ -10,7 +10,7 @@ module Rley
10
10
  # @return [Array<ASTNode>]
11
11
  attr_reader :subnodes
12
12
 
13
- # @return [Hash]
13
+ # @return [Array<Syntax::MatchClosest>]
14
14
  attr_accessor :constraints
15
15
 
16
16
  # @param children [Array<ASTNode>] sequence of children nodes
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'set'
4
-
5
3
  require_relative 'parser'
6
4
  require_relative 'ast_visitor'
7
5
  require_relative '../syntax/match_closest'
@@ -9,7 +7,7 @@ require_relative '../syntax/match_closest'
9
7
  module Rley # This module is used as a namespace
10
8
  # Namespace for classes that define RGN (Rley Grammar Notation)
11
9
  module RGN # This module is used as a namespace
12
- # Structure used by Rley to generate implicdit production rules.
10
+ # Structure used by Rley to generate implicit production rules.
13
11
  RawRule = Struct.new(:lhs, :rhs, :tag, :simple, :constraints)
14
12
 
15
13
  # Builder GoF pattern. Builder builds a complex object
@@ -67,10 +65,10 @@ module Rley # This module is used as a namespace
67
65
  # Add the given marker symbol to the grammar of the language
68
66
  # @param aMarkerSymbol [String] A marker symbol
69
67
  # @return [void]
70
- def add_marker(aMarkerSymbol)
71
- new_symb = build_symbol(Syntax::Marker, aMarkerSymbol)
72
- symbols[new_symb.name] = new_symb
73
- end
68
+ # def add_marker(aMarkerSymbol)
69
+ # new_symb = build_symbol(Syntax::Marker, aMarkerSymbol)
70
+ # symbols[new_symb.name] = new_symb
71
+ # end
74
72
 
75
73
  # Add a production rule in the grammar given one
76
74
  # key-value pair of the form: String => String.
@@ -87,7 +85,7 @@ module Rley # This module is used as a namespace
87
85
  def add_production(aProductionRepr)
88
86
  aProductionRepr.each_pair do |(lhs_name, rhs_repr)|
89
87
  lhs = get_grm_symbol(lhs_name)
90
- rhs = rhs_repr.kind_of?(Array) && rhs_repr.empty? ? '' : rhs_repr.strip
88
+ rhs = rhs_repr.is_a?(Array) && rhs_repr.empty? ? '' : rhs_repr.strip
91
89
  constraints = []
92
90
  if rhs.empty?
93
91
  rhs_members = []
@@ -98,7 +96,7 @@ module Rley # This module is used as a namespace
98
96
  visitor.subscribe(self)
99
97
  visitor.start
100
98
  root_node = ast.root
101
- constraints = root_node.constraints unless root_node.kind_of?(SymbolNode)
99
+ constraints = root_node.constraints unless root_node.is_a?(SymbolNode)
102
100
 
103
101
  rhs_members = visitor2rhs.delete(visitor)
104
102
  end
@@ -122,12 +120,12 @@ module Rley # This module is used as a namespace
122
120
 
123
121
  # Check that each terminal appears at least in a rhs of a production
124
122
  all_terminals = symbols.values.select do |a_symb|
125
- a_symb.kind_of?(Syntax::Terminal)
123
+ a_symb.is_a?(Syntax::Terminal)
126
124
  end
127
125
  in_use = Set.new
128
126
  productions.each do |prod|
129
127
  prod.rhs.members.each do |symb|
130
- in_use << symb if symb.kind_of?(Syntax::Terminal)
128
+ in_use << symb if symb.is_a?(Syntax::Terminal)
131
129
  end
132
130
  end
133
131
 
@@ -295,7 +293,7 @@ module Rley # This module is used as a namespace
295
293
  aProductionRepr.each_pair do |(lhs_name, rhs_repr)|
296
294
  lhs = get_grm_symbol(lhs_name)
297
295
 
298
- if rhs_repr.kind_of?(String)
296
+ if rhs_repr.is_a?(String)
299
297
  rhs = rhs_repr.strip.scan(/\S+/)
300
298
  else
301
299
  rhs = rhs_repr
@@ -340,7 +338,7 @@ module Rley # This module is used as a namespace
340
338
  # @param aSymbolArg [GrmSymbol-like or String]
341
339
  # @return [Array] list of grammar symbols
342
340
  def build_symbol(aClass, aSymbolArg)
343
- if aSymbolArg.kind_of?(Syntax::GrmSymbol)
341
+ if aSymbolArg.is_a?(Syntax::GrmSymbol)
344
342
  aSymbolArg
345
343
  else
346
344
  aClass.new(aSymbolArg)
@@ -387,7 +385,7 @@ module Rley # This module is used as a namespace
387
385
  end
388
386
 
389
387
  def node_base_name(aNode)
390
- if aNode.kind_of?(SymbolNode)
388
+ if aNode.is_a?(SymbolNode)
391
389
  aNode.name
392
390
  else
393
391
  sequence_name(aNode)
@@ -37,7 +37,7 @@ module Rley
37
37
 
38
38
  # Parse the given RGN snippet into a parse tree.
39
39
  # @param source [String] Snippet to parse
40
- # @return [Rley::ParseTree] A parse tree equivalent to the RGN input.
40
+ # @return [Rley::PTree::ParseTree] A parse tree equivalent to the RGN input.
41
41
  def parse(source)
42
42
  lexer = Tokenizer.new(source)
43
43
  result = engine.parse(lexer.tokens)
@@ -49,7 +49,7 @@ module Rley
49
49
  raise SyntaxError, line1 + line2
50
50
  end
51
51
 
52
- return engine.convert(result) # engine.to_ptree(result)
52
+ engine.convert(result) # engine.to_ptree(result)
53
53
  end
54
54
  end # class
55
55
  end # module
@@ -41,7 +41,7 @@ module Rley
41
41
  '?' => 'QUESTION_MARK',
42
42
  '*' => 'STAR',
43
43
  '..' => 'ELLIPSIS'
44
- }
44
+ }.freeze
45
45
 
46
46
  # Here are all the implemented Rley notation keywords
47
47
  @@keywords = %w[
@@ -1,12 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # File: rley_error.rb
4
-
5
3
  module Rley # Module used as a namespace
6
4
  # @abstract
7
5
  # Base class for any exception explicitly raised by Rley code.
8
6
  class RleyError < StandardError
9
7
  end # class
10
8
  end # module
11
-
12
- # End of file
@@ -34,6 +34,12 @@ module Rley # This module is used as a namespace
34
34
  def key
35
35
  @key ||= to_string(0)
36
36
  end
37
+
38
+ # Part of the 'visitee' role in Visitor design pattern.
39
+ # @param aVisitor[ParseTreeVisitor] the visitor
40
+ def accept(aVisitor)
41
+ raise NotImplementedError
42
+ end
37
43
  end # class
38
44
  end # module
39
45
  end # module
@@ -51,13 +51,13 @@ module Rley # This module is used as a namespace
51
51
  # parse trees. That enumerator will generate a parse tree when
52
52
  # called with `next` method.
53
53
  # @return [Enumerator]
54
- def to_ptree_enum
55
- # How to implement?
56
- # One visits the forest => beware of dependency
57
- # At each visited item create a corresponding tree node.
58
- # At end of visit & stack not empty
59
- # Re-generate another ptree
60
- end
54
+ # def to_ptree_enum
55
+ # # How to implement?
56
+ # # One visits the forest => beware of dependency
57
+ # # At each visited item create a corresponding tree node.
58
+ # # At end of visit & stack not empty
59
+ # # Re-generate another ptree
60
+ # end
61
61
 
62
62
  # Part of the 'visitee' role in the Visitor design pattern.
63
63
  # A visitee is expected to accept the visit from a visitor object
@@ -20,9 +20,23 @@ module Rley # This module is used as a namespace
20
20
  # Return the origin, that is, the index of the
21
21
  # first token matched by this node.
22
22
  # @return [Integer]
23
- def origin
23
+ def origin # steep:ignore MethodBodyTypeMismatch
24
24
  range.low
25
25
  end
26
+
27
+ # Emit a (formatted) string representation of the node.
28
+ # Mainly used for diagnosis/debugging purposes.
29
+ # @param indentation [Integer]
30
+ # @return [String]
31
+ def to_string(indentation)
32
+ raise NotImplementedError
33
+ end
34
+
35
+ # Part of the 'visitee' role in Visitor design pattern.
36
+ # @param aVisitor[ParseForestVisitor] the visitor
37
+ def accept(aVisitor)
38
+ raise NotImplementedError
39
+ end
26
40
  end # class
27
41
  end # module
28
42
  end # module
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'set'
4
3
  require_relative 'terminal'
5
4
  require_relative 'non_terminal'
6
5
  require_relative 'production'
@@ -54,14 +53,6 @@ module Rley # This module is used as a namespace
54
53
  symbols.merge!(new_symbs)
55
54
  end
56
55
 
57
- # Add the given marker symbol to the grammar of the language
58
- # @param aMarkerSymbol [Syntax::Marker] A mazker symbol
59
- # @return [void]
60
- def add_marker(aMarkerSymbol)
61
- new_symb = build_symbol(Marker, aMarkerSymbol)
62
- symbols[aMarkerSymbol.name] = new_symb
63
- end
64
-
65
56
  # Add a production rule in the grammar given one
66
57
  # key-value pair of the form: String => Array.
67
58
  # Where the key is the name of the non-terminal appearing in the
@@ -107,12 +98,12 @@ module Rley # This module is used as a namespace
107
98
 
108
99
  # Check that each terminal appears at least in a rhs of a production
109
100
  all_terminals = symbols.values.select do |a_symb|
110
- a_symb.kind_of?(Terminal)
101
+ a_symb.is_a?(Terminal)
111
102
  end
112
103
  in_use = Set.new
113
104
  productions.each do |prod|
114
105
  prod.rhs.members.each do |symb|
115
- in_use << symb if symb.kind_of?(Syntax::Terminal)
106
+ in_use << symb if symb.is_a?(Syntax::Terminal)
116
107
  end
117
108
  end
118
109
 
@@ -169,7 +160,7 @@ module Rley # This module is used as a namespace
169
160
  # @param aSymbolArg [GrmSymbol-like or String]
170
161
  # @return [Array] list of grammar symbols
171
162
  def build_symbol(aClass, aSymbolArg)
172
- if aSymbolArg.kind_of?(GrmSymbol)
163
+ if aSymbolArg.is_a?(GrmSymbol)
173
164
  aSymbolArg
174
165
  else
175
166
  aClass.new(aSymbolArg)