rley 0.7.08 → 0.8.03

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 (72) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +29 -5
  3. data/CHANGELOG.md +28 -4
  4. data/README.md +4 -5
  5. data/examples/NLP/nano_eng/nano_en_demo.rb +7 -11
  6. data/examples/NLP/nano_eng/nano_grammar.rb +18 -18
  7. data/examples/data_formats/JSON/json_ast_builder.rb +9 -18
  8. data/examples/data_formats/JSON/json_demo.rb +1 -2
  9. data/examples/data_formats/JSON/json_grammar.rb +11 -11
  10. data/examples/general/calc_iter1/calc_grammar.rb +5 -4
  11. data/examples/general/calc_iter2/calc_grammar.rb +9 -9
  12. data/examples/general/left.rb +1 -1
  13. data/examples/general/right.rb +1 -1
  14. data/lib/rley/base/dotted_item.rb +5 -0
  15. data/lib/rley/base/grm_items_builder.rb +6 -0
  16. data/lib/rley/constants.rb +1 -1
  17. data/lib/rley/engine.rb +2 -2
  18. data/lib/rley/interface.rb +16 -0
  19. data/lib/rley/notation/all_notation_nodes.rb +4 -0
  20. data/lib/rley/notation/ast_builder.rb +185 -0
  21. data/lib/rley/notation/ast_node.rb +44 -0
  22. data/lib/rley/notation/ast_visitor.rb +115 -0
  23. data/lib/rley/notation/grammar.rb +49 -0
  24. data/lib/rley/notation/grammar_builder.rb +505 -0
  25. data/lib/rley/notation/grouping_node.rb +23 -0
  26. data/lib/rley/notation/parser.rb +56 -0
  27. data/lib/rley/notation/sequence_node.rb +35 -0
  28. data/lib/rley/notation/symbol_node.rb +29 -0
  29. data/lib/rley/notation/tokenizer.rb +180 -0
  30. data/lib/rley/parse_rep/ast_base_builder.rb +44 -0
  31. data/lib/rley/parser/gfg_chart.rb +101 -6
  32. data/lib/rley/parser/gfg_earley_parser.rb +1 -1
  33. data/lib/rley/parser/gfg_parsing.rb +5 -3
  34. data/lib/rley/parser/parse_entry_set.rb +1 -1
  35. data/lib/rley/syntax/{grammar_builder.rb → base_grammar_builder.rb} +53 -15
  36. data/lib/rley/syntax/grm_symbol.rb +1 -1
  37. data/lib/rley/syntax/match_closest.rb +43 -0
  38. data/lib/rley/syntax/production.rb +6 -0
  39. data/lib/rley.rb +1 -1
  40. data/spec/rley/engine_spec.rb +6 -6
  41. data/spec/rley/gfg/grm_flow_graph_spec.rb +2 -2
  42. data/spec/rley/notation/grammar_builder_spec.rb +302 -0
  43. data/spec/rley/notation/parser_spec.rb +183 -0
  44. data/spec/rley/notation/tokenizer_spec.rb +364 -0
  45. data/spec/rley/parse_rep/ast_builder_spec.rb +0 -1
  46. data/spec/rley/parse_rep/groucho_spec.rb +1 -1
  47. data/spec/rley/parse_rep/parse_forest_builder_spec.rb +1 -1
  48. data/spec/rley/parse_rep/parse_forest_factory_spec.rb +2 -2
  49. data/spec/rley/parse_rep/parse_tree_factory_spec.rb +1 -1
  50. data/spec/rley/parser/dangling_else_spec.rb +447 -0
  51. data/spec/rley/parser/gfg_earley_parser_spec.rb +118 -10
  52. data/spec/rley/parser/gfg_parsing_spec.rb +2 -1
  53. data/spec/rley/parser/parse_walker_factory_spec.rb +2 -2
  54. data/spec/rley/support/ambiguous_grammar_helper.rb +2 -2
  55. data/spec/rley/support/grammar_abc_helper.rb +2 -2
  56. data/spec/rley/support/grammar_ambig01_helper.rb +2 -2
  57. data/spec/rley/support/grammar_arr_int_helper.rb +2 -2
  58. data/spec/rley/support/grammar_b_expr_helper.rb +2 -2
  59. data/spec/rley/support/grammar_int_seq_helper.rb +51 -0
  60. data/spec/rley/support/grammar_l0_helper.rb +2 -2
  61. data/spec/rley/support/grammar_pb_helper.rb +2 -2
  62. data/spec/rley/support/grammar_sppf_helper.rb +2 -2
  63. data/spec/rley/syntax/{grammar_builder_spec.rb → base_grammar_builder_spec.rb} +29 -11
  64. data/spec/rley/syntax/match_closest_spec.rb +46 -0
  65. data/spec/rley/syntax/production_spec.rb +4 -0
  66. metadata +29 -14
  67. data/lib/rley/parser/parse_state.rb +0 -78
  68. data/lib/rley/parser/parse_state_tracker.rb +0 -59
  69. data/lib/rley/parser/state_set.rb +0 -100
  70. data/spec/rley/parser/parse_state_spec.rb +0 -125
  71. data/spec/rley/parser/parse_tracer_spec.rb +0 -200
  72. data/spec/rley/parser/state_set_spec.rb +0 -130
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../spec_helper'
4
+
5
+ require_relative '../../../lib/rley/syntax/terminal'
6
+ require_relative '../../../lib/rley/syntax/non_terminal'
7
+ require_relative '../../../lib/rley/syntax/symbol_seq'
8
+
9
+ # Load the class under test
10
+ require_relative '../../../lib/rley/syntax/production'
11
+
12
+ # Load the class under test
13
+ require_relative '../../../lib/rley/syntax/match_closest'
14
+
15
+ module Rley # Open this namespace to avoid module qualifier prefixes
16
+ module Syntax # Open this namespace to avoid module qualifier prefixes
17
+ describe MatchClosest do
18
+ # 'stmt' => 'IF boolean THEN stmt ELSE stmt'
19
+ let(:boolean) { NonTerminal.new('boolean') }
20
+ let(:stmt) { NonTerminal.new('stmt') }
21
+ let(:if_t) { Terminal.new('IF') }
22
+ let(:then_t) { Terminal.new('THEN') }
23
+ let(:else_t) { Terminal.new('ELSE') }
24
+ let(:sequence) { [if_t, boolean, then_t, stmt, else_t, stmt] }
25
+ let(:prod) { Production.new(stmt, sequence) }
26
+
27
+ subject { MatchClosest.new(prod.rhs.members, 4, 'IF') }
28
+
29
+ context 'Initialization:' do
30
+ it 'should be created with an symbol seq., an indice and a name' do
31
+ expect { MatchClosest.new(prod.rhs.members, 4, 'IF') }.not_to raise_error
32
+ end
33
+
34
+ it 'should know the index argument' do
35
+ expect(subject.idx_symbol).to eq(4) # ELSE at position 4
36
+ end
37
+
38
+ it 'should know the name of preceding symbol to pair with' do
39
+ expect(subject.closest_symb).to eq('IF')
40
+ end
41
+ end # context
42
+ end # describe
43
+ end # module
44
+ end # module
45
+
46
+ # End of file
@@ -43,6 +43,10 @@ module Rley # Open this namespace to avoid module qualifier prefixes
43
43
  expect(subject.body).to eq(sequence)
44
44
  end
45
45
 
46
+ it 'should be free from constraints at start' do
47
+ expect(subject.constraints).to be_empty
48
+ end
49
+
46
50
  it 'should know whether its rhs is empty' do
47
51
  expect(subject).not_to be_empty
48
52
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rley
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.08
4
+ version: 0.8.03
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dimitri Geshef
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-05-30 00:00:00.000000000 Z
11
+ date: 2021-08-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -136,8 +136,20 @@ files:
136
136
  - lib/rley/gfg/shortcut_edge.rb
137
137
  - lib/rley/gfg/start_vertex.rb
138
138
  - lib/rley/gfg/vertex.rb
139
+ - lib/rley/interface.rb
139
140
  - lib/rley/lexical/token.rb
140
141
  - lib/rley/lexical/token_range.rb
142
+ - lib/rley/notation/all_notation_nodes.rb
143
+ - lib/rley/notation/ast_builder.rb
144
+ - lib/rley/notation/ast_node.rb
145
+ - lib/rley/notation/ast_visitor.rb
146
+ - lib/rley/notation/grammar.rb
147
+ - lib/rley/notation/grammar_builder.rb
148
+ - lib/rley/notation/grouping_node.rb
149
+ - lib/rley/notation/parser.rb
150
+ - lib/rley/notation/sequence_node.rb
151
+ - lib/rley/notation/symbol_node.rb
152
+ - lib/rley/notation/tokenizer.rb
141
153
  - lib/rley/parse_forest_visitor.rb
142
154
  - lib/rley/parse_rep/ast_base_builder.rb
143
155
  - lib/rley/parse_rep/cst_builder.rb
@@ -154,11 +166,8 @@ files:
154
166
  - lib/rley/parser/parse_entry.rb
155
167
  - lib/rley/parser/parse_entry_set.rb
156
168
  - lib/rley/parser/parse_entry_tracker.rb
157
- - lib/rley/parser/parse_state.rb
158
- - lib/rley/parser/parse_state_tracker.rb
159
169
  - lib/rley/parser/parse_tracer.rb
160
170
  - lib/rley/parser/parse_walker_factory.rb
161
- - lib/rley/parser/state_set.rb
162
171
  - lib/rley/ptree/non_terminal_node.rb
163
172
  - lib/rley/ptree/parse_tree.rb
164
173
  - lib/rley/ptree/parse_tree_node.rb
@@ -172,10 +181,11 @@ files:
172
181
  - lib/rley/sppf/parse_forest.rb
173
182
  - lib/rley/sppf/sppf_node.rb
174
183
  - lib/rley/sppf/token_node.rb
184
+ - lib/rley/syntax/base_grammar_builder.rb
175
185
  - lib/rley/syntax/grammar.rb
176
- - lib/rley/syntax/grammar_builder.rb
177
186
  - lib/rley/syntax/grm_symbol.rb
178
187
  - lib/rley/syntax/literal.rb
188
+ - lib/rley/syntax/match_closest.rb
179
189
  - lib/rley/syntax/non_terminal.rb
180
190
  - lib/rley/syntax/production.rb
181
191
  - lib/rley/syntax/symbol_seq.rb
@@ -203,6 +213,9 @@ files:
203
213
  - spec/rley/gfg/vertex_spec.rb
204
214
  - spec/rley/lexical/token_range_spec.rb
205
215
  - spec/rley/lexical/token_spec.rb
216
+ - spec/rley/notation/grammar_builder_spec.rb
217
+ - spec/rley/notation/parser_spec.rb
218
+ - spec/rley/notation/tokenizer_spec.rb
206
219
  - spec/rley/parse_forest_visitor_spec.rb
207
220
  - spec/rley/parse_rep/ambiguous_parse_spec.rb
208
221
  - spec/rley/parse_rep/ast_builder_spec.rb
@@ -212,16 +225,14 @@ files:
212
225
  - spec/rley/parse_rep/parse_forest_factory_spec.rb
213
226
  - spec/rley/parse_rep/parse_tree_factory_spec.rb
214
227
  - spec/rley/parse_tree_visitor_spec.rb
228
+ - spec/rley/parser/dangling_else_spec.rb
215
229
  - spec/rley/parser/error_reason_spec.rb
216
230
  - spec/rley/parser/gfg_chart_spec.rb
217
231
  - spec/rley/parser/gfg_earley_parser_spec.rb
218
232
  - spec/rley/parser/gfg_parsing_spec.rb
219
233
  - spec/rley/parser/parse_entry_set_spec.rb
220
234
  - spec/rley/parser/parse_entry_spec.rb
221
- - spec/rley/parser/parse_state_spec.rb
222
- - spec/rley/parser/parse_tracer_spec.rb
223
235
  - spec/rley/parser/parse_walker_factory_spec.rb
224
- - spec/rley/parser/state_set_spec.rb
225
236
  - spec/rley/ptree/non_terminal_node_spec.rb
226
237
  - spec/rley/ptree/parse_tree_node_spec.rb
227
238
  - spec/rley/ptree/parse_tree_spec.rb
@@ -236,13 +247,15 @@ files:
236
247
  - spec/rley/support/grammar_arr_int_helper.rb
237
248
  - spec/rley/support/grammar_b_expr_helper.rb
238
249
  - spec/rley/support/grammar_helper.rb
250
+ - spec/rley/support/grammar_int_seq_helper.rb
239
251
  - spec/rley/support/grammar_l0_helper.rb
240
252
  - spec/rley/support/grammar_pb_helper.rb
241
253
  - spec/rley/support/grammar_sppf_helper.rb
242
- - spec/rley/syntax/grammar_builder_spec.rb
254
+ - spec/rley/syntax/base_grammar_builder_spec.rb
243
255
  - spec/rley/syntax/grammar_spec.rb
244
256
  - spec/rley/syntax/grm_symbol_spec.rb
245
257
  - spec/rley/syntax/literal_spec.rb
258
+ - spec/rley/syntax/match_closest_spec.rb
246
259
  - spec/rley/syntax/non_terminal_spec.rb
247
260
  - spec/rley/syntax/production_spec.rb
248
261
  - spec/rley/syntax/symbol_seq_spec.rb
@@ -299,16 +312,17 @@ test_files:
299
312
  - spec/rley/gfg/vertex_spec.rb
300
313
  - spec/rley/lexical/token_range_spec.rb
301
314
  - spec/rley/lexical/token_spec.rb
315
+ - spec/rley/notation/grammar_builder_spec.rb
316
+ - spec/rley/notation/parser_spec.rb
317
+ - spec/rley/notation/tokenizer_spec.rb
318
+ - spec/rley/parser/dangling_else_spec.rb
302
319
  - spec/rley/parser/error_reason_spec.rb
303
320
  - spec/rley/parser/gfg_chart_spec.rb
304
321
  - spec/rley/parser/gfg_earley_parser_spec.rb
305
322
  - spec/rley/parser/gfg_parsing_spec.rb
306
323
  - spec/rley/parser/parse_entry_set_spec.rb
307
324
  - spec/rley/parser/parse_entry_spec.rb
308
- - spec/rley/parser/parse_state_spec.rb
309
- - spec/rley/parser/parse_tracer_spec.rb
310
325
  - spec/rley/parser/parse_walker_factory_spec.rb
311
- - spec/rley/parser/state_set_spec.rb
312
326
  - spec/rley/parse_forest_visitor_spec.rb
313
327
  - spec/rley/parse_rep/ambiguous_parse_spec.rb
314
328
  - spec/rley/parse_rep/ast_builder_spec.rb
@@ -325,10 +339,11 @@ test_files:
325
339
  - spec/rley/sppf/alternative_node_spec.rb
326
340
  - spec/rley/sppf/non_terminal_node_spec.rb
327
341
  - spec/rley/sppf/token_node_spec.rb
328
- - spec/rley/syntax/grammar_builder_spec.rb
342
+ - spec/rley/syntax/base_grammar_builder_spec.rb
329
343
  - spec/rley/syntax/grammar_spec.rb
330
344
  - spec/rley/syntax/grm_symbol_spec.rb
331
345
  - spec/rley/syntax/literal_spec.rb
346
+ - spec/rley/syntax/match_closest_spec.rb
332
347
  - spec/rley/syntax/non_terminal_spec.rb
333
348
  - spec/rley/syntax/production_spec.rb
334
349
  - spec/rley/syntax/symbol_seq_spec.rb
@@ -1,78 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Rley # This module is used as a namespace
4
- module Parser # This module is used as a namespace
5
- class ParseState
6
- attr_reader(:dotted_rule)
7
-
8
- # the position in the input that matches the beginning of the rhs
9
- # of the production.
10
- attr_reader(:origin)
11
-
12
- def initialize(aDottedRule, theOrigin)
13
- @dotted_rule = valid_dotted_rule(aDottedRule)
14
- @origin = theOrigin
15
- end
16
-
17
- # Equality comparison. A parse state behaves as a value object.
18
- def ==(other)
19
- return true if equal?(other)
20
-
21
- (dotted_rule == other.dotted_rule) &&
22
- (origin == other.origin)
23
- end
24
-
25
- # Returns true if the dot is at the end of the rhs of the production.
26
- # In other words, the complete rhs matches the input.
27
- def complete?
28
- dotted_rule.reduce_item?
29
- end
30
-
31
- # Returns true if the dot is at the start of the rhs of the production.
32
- def predicted?
33
- dotted_rule.predicted_item?
34
- end
35
-
36
- # Next expected symbol in the production
37
- def next_symbol
38
- dotted_rule.next_symbol
39
- end
40
-
41
- # Does this parse state have the 'other' as successor?
42
- def precedes?(other)
43
- return false if other == self
44
-
45
- return false unless origin == other.origin
46
-
47
- other_production = other.dotted_rule.production
48
- return false unless dotted_rule.production == other_production
49
-
50
- prev_position = other.dotted_rule.prev_position
51
- if prev_position.nil?
52
- false
53
- else
54
- dotted_rule.position == prev_position
55
- end
56
- end
57
-
58
- # Give a String representation of itself.
59
- # The format of the text representation is
60
- # "format of dotted rule" + " | " + origin
61
- # @return [String]
62
- def to_s
63
- dotted_rule.to_s + " | #{origin}"
64
- end
65
-
66
- private
67
-
68
- # Return the validated dotted item(rule)
69
- def valid_dotted_rule(aDottedRule)
70
- raise StandardError, 'Dotted item cannot be nil' if aDottedRule.nil?
71
-
72
- aDottedRule
73
- end
74
- end # class
75
- end # module
76
- end # module
77
-
78
- # End of file
@@ -1,59 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Rley # This module is used as a namespace
4
- module Parser # This module is used as a namespace
5
- # Helper class that keeps track of the parse states used
6
- # while a Parsing instance is constructing a parse tree.
7
- class ParseStateTracker
8
- # The index of the current state set
9
- attr_reader(:state_set_index)
10
-
11
- # The current parse state
12
- attr_reader(:parse_state)
13
-
14
- # The already processed states from current state set
15
- attr_reader(:processed_states)
16
-
17
- # Constructor. Refined variant of the inherited constructor.
18
- def initialize(aStateSetIndex)
19
- self.state_set_index = aStateSetIndex
20
- end
21
-
22
- # Write accessor. Sets the value of the state set index
23
- def state_set_index=(anIndex)
24
- @state_set_index = anIndex
25
- @processed_states = {}
26
- end
27
-
28
- # Write accessor. Set the given parse state as the current one.
29
- def parse_state=(aParseState)
30
- raise StandardError, 'Nil parse state' if aParseState.nil?
31
-
32
- @parse_state = aParseState
33
- processed_states[parse_state] = true
34
- end
35
-
36
- # Take the first provided state that wasn't processed yet.
37
- def select_state(theStates)
38
- a_state = theStates.find { |st| !processed_states.include?(st) }
39
- self.parse_state = a_state
40
- end
41
-
42
- # The dotted item for the current parse state.
43
- def curr_dotted_item
44
- parse_state.dotted_rule
45
- end
46
-
47
- def symbol_on_left
48
- return curr_dotted_item.prev_symbol
49
- end
50
-
51
- # Notification that one begins with the previous state set
52
- def to_prev_state_set
53
- self.state_set_index = state_set_index - 1
54
- end
55
- end # class
56
- end # module
57
- end # module
58
-
59
- # End of file
@@ -1,100 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'forwardable' # Delegation
4
-
5
- module Rley # This module is used as a namespace
6
- module Parser # This module is used as a namespace
7
- class StateSet
8
- extend Forwardable
9
- def_delegators :states, :empty?, :size, :first, :each
10
-
11
- # The set of parse states
12
- attr_reader(:states)
13
-
14
- def initialize
15
- @states = []
16
- end
17
-
18
- # Append the given state (if it isn't yet in the set)
19
- # to the list of states
20
- # @param aState [ParseState] the state to push.
21
- # @return [TrueClass/FalseClass] true when the state is really added
22
- def push_state(aState)
23
- if include?(aState)
24
- result = false
25
- else
26
- @states << aState
27
- result = true
28
- end
29
-
30
- return result
31
- end
32
-
33
- # The list of ParseState that expect the given symbol.
34
- # @param aSymbol [GrmSymbol] the expected symbol
35
- # (=on the right of the dot)
36
- def states_expecting(aSymbol)
37
- states.select { |s| s.dotted_rule.next_symbol == aSymbol }
38
- end
39
-
40
- # The list of complete ParseState that have the given non-terminal
41
- # symbol as the lhs of their production.
42
- def states_rewriting(aNonTerm)
43
- return states.select do |s|
44
- (s.dotted_rule.production.lhs == aNonTerm) && s.complete?
45
- end
46
- end
47
-
48
- # The list of ParseState that involve the given production
49
- def states_for(aProduction)
50
- states.select { |s| s.dotted_rule.production == aProduction }
51
- end
52
-
53
- # Retrieve the parse state that is the predecessor of the given one.
54
- def predecessor_state(aPState)
55
- dotted_rule = aPState.dotted_rule
56
- raise StandardError, aPState.to_s unless dotted_rule.prev_position
57
-
58
- states.find { |s| s.precedes?(aPState) }
59
- end
60
-
61
- # The list of distinct expected terminal symbols. An expected symbol
62
- # is on the left of a dot in a parse state of the parse set.
63
- def expected_terminals
64
- expecting_terminals = states.select do |s|
65
- s.dotted_rule.next_symbol.kind_of?(Rley::Syntax::Terminal)
66
- end
67
-
68
- terminals = expecting_terminals.map { |s| s.dotted_rule.next_symbol }
69
- terminals.uniq
70
- end
71
-
72
- # Return an Array of Arrays of ambiguous parse states.
73
- def ambiguities
74
- complete_states = states.select(&:complete?)
75
- return [] if complete_states.size <= 1
76
-
77
- # Group parse state by lhs symbol and origin
78
- groupings = complete_states.group_by do |st|
79
- st.dotted_rule.lhs.object_id.to_s
80
- end
81
-
82
- # Retain the groups having more than one element.
83
- ambiguous_groups = []
84
- groupings.each_value do |a_group|
85
- ambiguous_groups << a_group if a_group.size > 1
86
- end
87
-
88
- ambiguous_groups
89
- end
90
-
91
- private
92
-
93
- def include?(aState)
94
- # TODO: make it better than linear search
95
- states.include?(aState)
96
- end
97
- end # class
98
- end # module
99
- end # module
100
- # End of file
@@ -1,125 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative '../../spec_helper'
4
-
5
- require_relative '../../../lib/rley/syntax/terminal'
6
- require_relative '../../../lib/rley/syntax/non_terminal'
7
- require_relative '../../../lib/rley/syntax/production'
8
- require_relative '../../../lib/rley/base/dotted_item'
9
-
10
- # Load the class under test
11
- require_relative '../../../lib/rley/parser/parse_state'
12
-
13
- module Rley # Open this namespace to avoid module qualifier prefixes
14
- module Parser # Open this namespace to avoid module qualifier prefixes
15
- describe ParseState do
16
- let(:t_a) { Syntax::Terminal.new('A') }
17
- let(:t_b) { Syntax::Terminal.new('B') }
18
- let(:t_c) { Syntax::Terminal.new('C') }
19
- let(:nt_sentence) { Syntax::NonTerminal.new('sentence') }
20
-
21
- let(:sample_prod) do
22
- Syntax::Production.new(nt_sentence, [t_a, t_b, t_c])
23
- end
24
-
25
- let(:other_prod) do
26
- Syntax::Production.new(nt_sentence, [t_a])
27
- end
28
-
29
- let(:empty_prod) do
30
- Syntax::Production.new(nt_sentence, [])
31
- end
32
-
33
- let(:origin_val) { 3 }
34
- let(:dotted_rule) { Base::DottedItem.new(sample_prod, 2) }
35
- let(:other_dotted_rule) { double('mock-dotted-item') }
36
-
37
- # Default instantiation rule
38
- subject { ParseState.new(dotted_rule, origin_val) }
39
-
40
- context 'Initialization:' do
41
- it 'should be created with a dotted item and a origin position' do
42
- args = [dotted_rule, origin_val]
43
- expect { ParseState.new(*args) }.not_to raise_error
44
- end
45
-
46
- it 'should complain when the dotted rule is nil' do
47
- err = StandardError
48
- msg = 'Dotted item cannot be nil'
49
- expect { ParseState.new(nil, 2) }.to raise_error(err, msg)
50
- end
51
-
52
- it 'should know the related dotted rule' do
53
- expect(subject.dotted_rule).to eq(dotted_rule)
54
- end
55
-
56
- it 'should know the origin value' do
57
- expect(subject.origin).to eq(origin_val)
58
- end
59
- end # context
60
-
61
- context 'Provided services:' do
62
- def new_parse_state(aProd, aRank, aVal)
63
- item = Base::DottedItem.new(aProd, aRank)
64
- ParseState.new(item, aVal)
65
- end
66
-
67
- it 'should compare with itself' do
68
- synonym = subject # Fool Rubocop
69
- expect(subject == synonym).to eq(true)
70
- end
71
-
72
- it 'should compare with another' do
73
- equal = ParseState.new(dotted_rule, origin_val)
74
- expect(subject == equal).to eq(true)
75
-
76
- # Same dotted_rule, different origin
77
- diff_origin = ParseState.new(dotted_rule, 2)
78
- expect(subject == diff_origin).to eq(false)
79
-
80
- # Different dotted item, same origin
81
- diff_rule = ParseState.new(other_dotted_rule, 3)
82
- expect(subject == diff_rule).to eq(false)
83
- end
84
-
85
- it 'should know if the parsing is at the start of the production' do
86
- expect(subject).not_to be_predicted
87
- at_start = Base::DottedItem.new(sample_prod, 0)
88
-
89
- instance = ParseState.new(at_start, 0)
90
- expect(instance).to be_predicted
91
- end
92
-
93
- it 'should know if the parsing reached the end of the production' do
94
- expect(subject).not_to be_complete
95
- at_end = Base::DottedItem.new(sample_prod, 3)
96
-
97
- instance = ParseState.new(at_end, 2)
98
- expect(instance).to be_complete
99
- end
100
-
101
- it 'should know the next expected symbol' do
102
- expect(subject.next_symbol).to eq(t_c)
103
- end
104
-
105
- it 'should know whether another instance follows this one' do
106
- expect(subject.precedes?(subject)).to eq(false)
107
- state1 = new_parse_state(sample_prod, 1, origin_val)
108
- expect(state1.precedes?(subject)).to eq(true)
109
- state0 = new_parse_state(sample_prod, 0, origin_val)
110
- expect(state0.precedes?(state1)).to eq(true)
111
- expect(state0.precedes?(subject)).to eq(false)
112
- state3 = new_parse_state(sample_prod, 3, origin_val)
113
- expect(state3.precedes?(state0)).to eq(false)
114
- end
115
-
116
- it 'should know its text representation' do
117
- expected = 'sentence => A B . C | 3'
118
- expect(subject.to_s).to eq(expected)
119
- end
120
- end # context
121
- end # describe
122
- end # module
123
- end # module
124
-
125
- # End of file