rley 0.7.08 → 0.8.00

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +6 -0
  3. data/README.md +4 -5
  4. data/examples/NLP/nano_eng/nano_en_demo.rb +7 -11
  5. data/examples/NLP/nano_eng/nano_grammar.rb +18 -18
  6. data/examples/NLP/pico_en_demo.rb +2 -2
  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.rb +1 -1
  15. data/lib/rley/base/dotted_item.rb +5 -0
  16. data/lib/rley/base/grm_items_builder.rb +6 -0
  17. data/lib/rley/constants.rb +1 -1
  18. data/lib/rley/engine.rb +2 -2
  19. data/lib/rley/interface.rb +16 -0
  20. data/lib/rley/notation/all_notation_nodes.rb +2 -0
  21. data/lib/rley/notation/ast_builder.rb +191 -0
  22. data/lib/rley/notation/ast_node.rb +44 -0
  23. data/lib/rley/notation/ast_visitor.rb +113 -0
  24. data/lib/rley/notation/grammar.rb +49 -0
  25. data/lib/rley/notation/grammar_builder.rb +451 -0
  26. data/lib/rley/notation/grouping_node.rb +23 -0
  27. data/lib/rley/notation/parser.rb +56 -0
  28. data/lib/rley/notation/sequence_node.rb +35 -0
  29. data/lib/rley/notation/symbol_node.rb +29 -0
  30. data/lib/rley/notation/tokenizer.rb +192 -0
  31. data/lib/rley/parse_rep/ast_base_builder.rb +13 -0
  32. data/lib/rley/parser/gfg_chart.rb +100 -6
  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} +45 -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/spec/rley/engine_spec.rb +6 -6
  40. data/spec/rley/gfg/grm_flow_graph_spec.rb +2 -2
  41. data/spec/rley/notation/grammar_builder_spec.rb +295 -0
  42. data/spec/rley/notation/parser_spec.rb +184 -0
  43. data/spec/rley/notation/tokenizer_spec.rb +370 -0
  44. data/spec/rley/parse_rep/ast_builder_spec.rb +0 -1
  45. data/spec/rley/parse_rep/groucho_spec.rb +1 -1
  46. data/spec/rley/parse_rep/parse_forest_builder_spec.rb +1 -1
  47. data/spec/rley/parse_rep/parse_forest_factory_spec.rb +2 -2
  48. data/spec/rley/parse_rep/parse_tree_factory_spec.rb +1 -1
  49. data/spec/rley/parser/dangling_else_spec.rb +445 -0
  50. data/spec/rley/parser/gfg_earley_parser_spec.rb +95 -9
  51. data/spec/rley/parser/gfg_parsing_spec.rb +1 -1
  52. data/spec/rley/parser/parse_walker_factory_spec.rb +2 -2
  53. data/spec/rley/support/ambiguous_grammar_helper.rb +2 -2
  54. data/spec/rley/support/grammar_abc_helper.rb +2 -2
  55. data/spec/rley/support/grammar_ambig01_helper.rb +2 -2
  56. data/spec/rley/support/grammar_arr_int_helper.rb +2 -2
  57. data/spec/rley/support/grammar_b_expr_helper.rb +2 -2
  58. data/spec/rley/support/grammar_int_seq_helper.rb +51 -0
  59. data/spec/rley/support/grammar_l0_helper.rb +2 -2
  60. data/spec/rley/support/grammar_pb_helper.rb +2 -2
  61. data/spec/rley/support/grammar_sppf_helper.rb +2 -2
  62. data/spec/rley/syntax/{grammar_builder_spec.rb → base_grammar_builder_spec.rb} +30 -11
  63. data/spec/rley/syntax/match_closest_spec.rb +46 -0
  64. data/spec/rley/syntax/production_spec.rb +4 -0
  65. metadata +29 -14
  66. data/lib/rley/parser/parse_state.rb +0 -78
  67. data/lib/rley/parser/parse_state_tracker.rb +0 -59
  68. data/lib/rley/parser/state_set.rb +0 -100
  69. data/spec/rley/parser/parse_state_spec.rb +0 -125
  70. data/spec/rley/parser/parse_tracer_spec.rb +0 -200
  71. 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.00
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-15 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