rley 0.7.03 → 0.7.08

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 (174) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +362 -62
  3. data/.travis.yml +6 -7
  4. data/CHANGELOG.md +20 -1
  5. data/LICENSE.txt +1 -1
  6. data/README.md +6 -7
  7. data/Rakefile +2 -0
  8. data/appveyor.yml +2 -4
  9. data/examples/NLP/benchmark_pico_en.rb +2 -0
  10. data/examples/NLP/engtagger.rb +193 -188
  11. data/examples/NLP/nano_eng/nano_en_demo.rb +2 -0
  12. data/examples/NLP/nano_eng/nano_grammar.rb +7 -5
  13. data/examples/NLP/pico_en_demo.rb +2 -0
  14. data/examples/data_formats/JSON/cli_options.rb +3 -1
  15. data/examples/data_formats/JSON/json_ast_builder.rb +14 -9
  16. data/examples/data_formats/JSON/json_ast_nodes.rb +14 -21
  17. data/examples/data_formats/JSON/json_demo.rb +2 -0
  18. data/examples/data_formats/JSON/json_grammar.rb +4 -2
  19. data/examples/data_formats/JSON/json_lexer.rb +10 -8
  20. data/examples/data_formats/JSON/json_minifier.rb +3 -1
  21. data/examples/general/calc_iter1/calc_ast_builder.rb +15 -10
  22. data/examples/general/calc_iter1/calc_ast_nodes.rb +25 -37
  23. data/examples/general/calc_iter1/calc_demo.rb +2 -0
  24. data/examples/general/calc_iter1/calc_grammar.rb +4 -2
  25. data/examples/general/calc_iter1/calc_lexer.rb +8 -4
  26. data/examples/general/calc_iter1/spec/calculator_spec.rb +7 -5
  27. data/examples/general/calc_iter2/calc_ast_builder.rb +7 -3
  28. data/examples/general/calc_iter2/calc_ast_nodes.rb +29 -43
  29. data/examples/general/calc_iter2/calc_demo.rb +2 -0
  30. data/examples/general/calc_iter2/calc_grammar.rb +5 -3
  31. data/examples/general/calc_iter2/calc_lexer.rb +13 -10
  32. data/examples/general/calc_iter2/spec/calculator_spec.rb +28 -26
  33. data/examples/general/left.rb +4 -2
  34. data/examples/general/right.rb +4 -2
  35. data/lib/rley.rb +2 -0
  36. data/lib/rley/base/base_parser.rb +2 -0
  37. data/lib/rley/base/dotted_item.rb +38 -41
  38. data/lib/rley/base/grm_items_builder.rb +2 -0
  39. data/lib/rley/constants.rb +5 -3
  40. data/lib/rley/engine.rb +22 -24
  41. data/lib/rley/formatter/asciitree.rb +6 -4
  42. data/lib/rley/formatter/base_formatter.rb +2 -0
  43. data/lib/rley/formatter/bracket_notation.rb +3 -8
  44. data/lib/rley/formatter/debug.rb +8 -6
  45. data/lib/rley/formatter/json.rb +4 -2
  46. data/lib/rley/gfg/call_edge.rb +3 -1
  47. data/lib/rley/gfg/edge.rb +7 -5
  48. data/lib/rley/gfg/end_vertex.rb +4 -6
  49. data/lib/rley/gfg/epsilon_edge.rb +3 -5
  50. data/lib/rley/gfg/grm_flow_graph.rb +31 -25
  51. data/lib/rley/gfg/item_vertex.rb +12 -22
  52. data/lib/rley/gfg/non_terminal_vertex.rb +6 -4
  53. data/lib/rley/gfg/return_edge.rb +2 -0
  54. data/lib/rley/gfg/scan_edge.rb +3 -1
  55. data/lib/rley/gfg/shortcut_edge.rb +4 -2
  56. data/lib/rley/gfg/start_vertex.rb +6 -8
  57. data/lib/rley/gfg/vertex.rb +47 -41
  58. data/lib/rley/lexical/token.rb +3 -1
  59. data/lib/rley/lexical/token_range.rb +8 -6
  60. data/lib/rley/parse_forest_visitor.rb +7 -5
  61. data/lib/rley/parse_rep/ast_base_builder.rb +11 -11
  62. data/lib/rley/parse_rep/cst_builder.rb +7 -4
  63. data/lib/rley/parse_rep/parse_forest_builder.rb +36 -25
  64. data/lib/rley/parse_rep/parse_forest_factory.rb +5 -3
  65. data/lib/rley/parse_rep/parse_rep_creator.rb +18 -13
  66. data/lib/rley/parse_rep/parse_tree_builder.rb +15 -15
  67. data/lib/rley/parse_rep/parse_tree_factory.rb +27 -25
  68. data/lib/rley/parse_tree_visitor.rb +3 -1
  69. data/lib/rley/parser/error_reason.rb +9 -8
  70. data/lib/rley/parser/gfg_chart.rb +54 -22
  71. data/lib/rley/parser/gfg_earley_parser.rb +3 -1
  72. data/lib/rley/parser/gfg_parsing.rb +51 -31
  73. data/lib/rley/parser/parse_entry.rb +29 -33
  74. data/lib/rley/parser/parse_entry_set.rb +32 -27
  75. data/lib/rley/parser/parse_entry_tracker.rb +6 -4
  76. data/lib/rley/parser/parse_state.rb +18 -21
  77. data/lib/rley/parser/parse_state_tracker.rb +6 -4
  78. data/lib/rley/parser/parse_tracer.rb +15 -13
  79. data/lib/rley/parser/parse_walker_factory.rb +28 -29
  80. data/lib/rley/parser/state_set.rb +11 -10
  81. data/lib/rley/ptree/non_terminal_node.rb +10 -6
  82. data/lib/rley/ptree/parse_tree.rb +6 -4
  83. data/lib/rley/ptree/parse_tree_node.rb +7 -5
  84. data/lib/rley/ptree/terminal_node.rb +9 -7
  85. data/lib/rley/rley_error.rb +12 -10
  86. data/lib/rley/sppf/alternative_node.rb +8 -6
  87. data/lib/rley/sppf/composite_node.rb +9 -7
  88. data/lib/rley/sppf/epsilon_node.rb +5 -3
  89. data/lib/rley/sppf/leaf_node.rb +5 -3
  90. data/lib/rley/sppf/non_terminal_node.rb +2 -0
  91. data/lib/rley/sppf/parse_forest.rb +19 -17
  92. data/lib/rley/sppf/sppf_node.rb +9 -8
  93. data/lib/rley/sppf/token_node.rb +5 -3
  94. data/lib/rley/syntax/grammar.rb +7 -5
  95. data/lib/rley/syntax/grammar_builder.rb +11 -9
  96. data/lib/rley/syntax/grm_symbol.rb +8 -6
  97. data/lib/rley/syntax/literal.rb +2 -0
  98. data/lib/rley/syntax/non_terminal.rb +11 -15
  99. data/lib/rley/syntax/production.rb +13 -11
  100. data/lib/rley/syntax/symbol_seq.rb +10 -10
  101. data/lib/rley/syntax/terminal.rb +6 -5
  102. data/lib/rley/syntax/verbatim_symbol.rb +5 -3
  103. data/lib/support/base_tokenizer.rb +23 -20
  104. data/spec/rley/base/dotted_item_spec.rb +4 -2
  105. data/spec/rley/base/grm_items_builder_spec.rb +2 -0
  106. data/spec/rley/engine_spec.rb +47 -9
  107. data/spec/rley/formatter/asciitree_spec.rb +11 -9
  108. data/spec/rley/formatter/bracket_notation_spec.rb +16 -14
  109. data/spec/rley/formatter/debug_spec.rb +4 -2
  110. data/spec/rley/formatter/json_spec.rb +5 -3
  111. data/spec/rley/gfg/call_edge_spec.rb +2 -0
  112. data/spec/rley/gfg/edge_spec.rb +2 -0
  113. data/spec/rley/gfg/end_vertex_spec.rb +7 -5
  114. data/spec/rley/gfg/epsilon_edge_spec.rb +2 -0
  115. data/spec/rley/gfg/grm_flow_graph_spec.rb +2 -0
  116. data/spec/rley/gfg/item_vertex_spec.rb +12 -10
  117. data/spec/rley/gfg/non_terminal_vertex_spec.rb +5 -3
  118. data/spec/rley/gfg/return_edge_spec.rb +2 -0
  119. data/spec/rley/gfg/scan_edge_spec.rb +2 -0
  120. data/spec/rley/gfg/shortcut_edge_spec.rb +3 -1
  121. data/spec/rley/gfg/start_vertex_spec.rb +7 -5
  122. data/spec/rley/gfg/vertex_spec.rb +5 -3
  123. data/spec/rley/lexical/token_range_spec.rb +18 -16
  124. data/spec/rley/lexical/token_spec.rb +4 -2
  125. data/spec/rley/parse_forest_visitor_spec.rb +167 -163
  126. data/spec/rley/parse_rep/ambiguous_parse_spec.rb +46 -44
  127. data/spec/rley/parse_rep/ast_builder_spec.rb +8 -6
  128. data/spec/rley/parse_rep/cst_builder_spec.rb +7 -5
  129. data/spec/rley/parse_rep/groucho_spec.rb +25 -25
  130. data/spec/rley/parse_rep/parse_forest_builder_spec.rb +28 -26
  131. data/spec/rley/parse_rep/parse_forest_factory_spec.rb +8 -6
  132. data/spec/rley/parse_rep/parse_tree_factory_spec.rb +4 -2
  133. data/spec/rley/parse_tree_visitor_spec.rb +12 -8
  134. data/spec/rley/parser/error_reason_spec.rb +8 -6
  135. data/spec/rley/parser/gfg_chart_spec.rb +17 -4
  136. data/spec/rley/parser/gfg_earley_parser_spec.rb +16 -11
  137. data/spec/rley/parser/gfg_parsing_spec.rb +41 -252
  138. data/spec/rley/parser/parse_entry_set_spec.rb +2 -0
  139. data/spec/rley/parser/parse_entry_spec.rb +21 -19
  140. data/spec/rley/parser/parse_state_spec.rb +7 -5
  141. data/spec/rley/parser/parse_tracer_spec.rb +16 -14
  142. data/spec/rley/parser/parse_walker_factory_spec.rb +10 -8
  143. data/spec/rley/parser/state_set_spec.rb +24 -22
  144. data/spec/rley/ptree/non_terminal_node_spec.rb +7 -3
  145. data/spec/rley/ptree/parse_tree_node_spec.rb +6 -4
  146. data/spec/rley/ptree/parse_tree_spec.rb +2 -0
  147. data/spec/rley/ptree/terminal_node_spec.rb +8 -6
  148. data/spec/rley/sppf/alternative_node_spec.rb +8 -6
  149. data/spec/rley/sppf/non_terminal_node_spec.rb +5 -3
  150. data/spec/rley/sppf/token_node_spec.rb +6 -4
  151. data/spec/rley/support/ambiguous_grammar_helper.rb +5 -4
  152. data/spec/rley/support/expectation_helper.rb +2 -0
  153. data/spec/rley/support/grammar_abc_helper.rb +4 -4
  154. data/spec/rley/support/grammar_ambig01_helper.rb +6 -5
  155. data/spec/rley/support/grammar_arr_int_helper.rb +6 -5
  156. data/spec/rley/support/grammar_b_expr_helper.rb +6 -5
  157. data/spec/rley/support/grammar_helper.rb +2 -0
  158. data/spec/rley/support/grammar_l0_helper.rb +15 -16
  159. data/spec/rley/support/grammar_pb_helper.rb +8 -5
  160. data/spec/rley/support/grammar_sppf_helper.rb +3 -1
  161. data/spec/rley/syntax/grammar_builder_spec.rb +7 -5
  162. data/spec/rley/syntax/grammar_spec.rb +8 -6
  163. data/spec/rley/syntax/grm_symbol_spec.rb +3 -1
  164. data/spec/rley/syntax/literal_spec.rb +2 -0
  165. data/spec/rley/syntax/non_terminal_spec.rb +10 -8
  166. data/spec/rley/syntax/production_spec.rb +15 -13
  167. data/spec/rley/syntax/symbol_seq_spec.rb +4 -2
  168. data/spec/rley/syntax/terminal_spec.rb +7 -5
  169. data/spec/rley/syntax/verbatim_symbol_spec.rb +3 -1
  170. data/spec/spec_helper.rb +2 -12
  171. data/spec/support/base_tokenizer_spec.rb +9 -2
  172. metadata +21 -63
  173. data/.simplecov +0 -7
  174. data/Gemfile +0 -8
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative '../../spec_helper'
2
4
 
3
5
  require_relative '../../../lib/rley/syntax/production'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative '../../spec_helper'
2
4
 
3
5
  require_relative '../../../lib/rley/syntax/terminal'
@@ -50,7 +52,7 @@ module Rley # Open this namespace to avoid module qualifier prefixes
50
52
  it 'should know the origin value' do
51
53
  expect(subject.origin).to eq(origin_val)
52
54
  end
53
-
55
+
54
56
  it 'should have not antecedent at creation' do
55
57
  expect(subject.antecedents).to be_empty
56
58
  expect(subject).to be_orphan
@@ -89,13 +91,13 @@ module Rley # Open this namespace to avoid module qualifier prefixes
89
91
  instance = ParseEntry.new(GFG::EndVertex.new('NT.'), 3)
90
92
  expect(instance).to be_end_entry
91
93
  end
92
-
94
+
93
95
  it 'should know if the entry is a dotted item vertex' do
94
96
  expect(subject).not_to be_dotted_entry
95
97
 
96
98
  instance = ParseEntry.new(GFG::ItemVertex.new('P => S.'), 3)
97
99
  expect(instance).to be_dotted_entry
98
- end
100
+ end
99
101
 
100
102
  it 'should know if the vertex is at end of production (if any)' do
101
103
  # Case: start vertex
@@ -118,7 +120,7 @@ module Rley # Open this namespace to avoid module qualifier prefixes
118
120
  instance4 = ParseEntry.new(v2, 3)
119
121
  expect(instance4).to be_exit_entry
120
122
  end
121
-
123
+
122
124
  it 'should know if the vertex is at begin of production (if any)' do
123
125
  # Case: start vertex
124
126
  instance1 = ParseEntry.new(GFG::StartVertex.new('.NT'), 3)
@@ -129,17 +131,17 @@ module Rley # Open this namespace to avoid module qualifier prefixes
129
131
  expect(instance2).not_to be_entry_entry
130
132
 
131
133
  # Case: item vertex not at begin of rhs
132
- d1 = Base::DottedItem.new(sample_prod, 1)
134
+ d1 = Base::DottedItem.new(sample_prod, 1)
133
135
  v1 = GFG::ItemVertex.new(d1)
134
136
  instance3 = ParseEntry.new(v1, 3)
135
137
  expect(instance3).not_to be_entry_entry
136
138
 
137
139
  # Case: item vertex at end of rhs
138
- d2 = Base::DottedItem.new(sample_prod, 0)
139
- v2 = GFG::ItemVertex.new(d2)
140
+ d2 = Base::DottedItem.new(sample_prod, 0)
141
+ v2 = GFG::ItemVertex.new(d2)
140
142
  instance4 = ParseEntry.new(v2, 3)
141
143
  expect(instance4).to be_entry_entry
142
- end
144
+ end
143
145
 
144
146
  it 'should know the symbol before the dot (if any)' do
145
147
  # Case: start vertex
@@ -149,20 +151,20 @@ module Rley # Open this namespace to avoid module qualifier prefixes
149
151
  # Case: end vertex
150
152
  instance2 = ParseEntry.new(GFG::EndVertex.new('NT.'), 3)
151
153
  expect(instance2.prev_symbol).to be_nil # Really correct?
152
-
154
+
153
155
  # Case: item vertex not at start of rhs
154
156
  v1 = double('vertex-not-at-start')
155
157
  expect(v1).to receive(:prev_symbol).and_return('symbol')
156
158
  instance3 = ParseEntry.new(v1, 3)
157
- expect(instance3.prev_symbol).to eq('symbol')
159
+ expect(instance3.prev_symbol).to eq('symbol')
158
160
 
159
161
  # Case: item vertex at start of rhs
160
162
  v2 = double('vertex-at-start')
161
163
  expect(v2).to receive(:prev_symbol).and_return(nil)
162
164
  instance4 = ParseEntry.new(v2, 0)
163
- expect(instance4.prev_symbol).to be_nil
165
+ expect(instance4.prev_symbol).to be_nil
164
166
  end
165
-
167
+
166
168
  it 'should know the next expected symbol (if any)' do
167
169
  # Case: start vertex
168
170
  instance1 = ParseEntry.new(GFG::StartVertex.new('.NT'), 3)
@@ -171,19 +173,19 @@ module Rley # Open this namespace to avoid module qualifier prefixes
171
173
  # Case: end vertex
172
174
  instance2 = ParseEntry.new(GFG::EndVertex.new('NT.'), 3)
173
175
  expect(instance2.next_symbol).to be_nil
174
-
176
+
175
177
  # Case: item vertex not at end of rhs
176
178
  v1 = double('vertex-not-at-end')
177
179
  expect(v1).to receive(:next_symbol).and_return('symbol')
178
180
  instance3 = ParseEntry.new(v1, 3)
179
- expect(instance3.next_symbol).to eq('symbol')
181
+ expect(instance3.next_symbol).to eq('symbol')
180
182
 
181
183
  # Case: item vertex at end of rhs
182
184
  v2 = double('vertex-at-end')
183
185
  expect(v2).to receive(:next_symbol).and_return(nil)
184
186
  instance4 = ParseEntry.new(v2, 3)
185
- expect(instance4.next_symbol).to be_nil
186
- end
187
+ expect(instance4.next_symbol).to be_nil
188
+ end
187
189
 
188
190
  it 'should accept antecedents' do
189
191
  antecedent = ParseEntry.new(vertex2, origin_val)
@@ -196,7 +198,7 @@ module Rley # Open this namespace to avoid module qualifier prefixes
196
198
  expected = '.sentence | 3'
197
199
  expect(subject.to_s).to eq(expected)
198
200
  end
199
-
201
+
200
202
  it 'should be inspectable' do
201
203
  subject.add_antecedent(subject) # Cheat for the good cause...
202
204
  # expected = '.sentence | 3'
@@ -207,8 +209,8 @@ module Rley # Open this namespace to avoid module qualifier prefixes
207
209
  pattern2 = /@origin=3 @antecedents=\[/
208
210
  expect(subject.inspect).to match(pattern2)
209
211
  suffix = /<Rley::GFG::StartVertex:\d+ label=\.sentence> @origin=3\]>$/
210
- expect(subject.inspect).to match(suffix)
211
- end
212
+ expect(subject.inspect).to match(suffix)
213
+ end
212
214
  end # context
213
215
  end # describe
214
216
  end # module
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative '../../spec_helper'
2
4
 
3
5
  require_relative '../../../lib/rley/syntax/terminal'
@@ -61,7 +63,7 @@ module Rley # Open this namespace to avoid module qualifier prefixes
61
63
  item = Base::DottedItem.new(aProd, aRank)
62
64
  ParseState.new(item, aVal)
63
65
  end
64
-
66
+
65
67
  it 'should compare with itself' do
66
68
  synonym = subject # Fool Rubocop
67
69
  expect(subject == synonym).to eq(true)
@@ -79,14 +81,14 @@ module Rley # Open this namespace to avoid module qualifier prefixes
79
81
  diff_rule = ParseState.new(other_dotted_rule, 3)
80
82
  expect(subject == diff_rule).to eq(false)
81
83
  end
82
-
84
+
83
85
  it 'should know if the parsing is at the start of the production' do
84
86
  expect(subject).not_to be_predicted
85
87
  at_start = Base::DottedItem.new(sample_prod, 0)
86
88
 
87
89
  instance = ParseState.new(at_start, 0)
88
90
  expect(instance).to be_predicted
89
- end
91
+ end
90
92
 
91
93
  it 'should know if the parsing reached the end of the production' do
92
94
  expect(subject).not_to be_complete
@@ -99,7 +101,7 @@ module Rley # Open this namespace to avoid module qualifier prefixes
99
101
  it 'should know the next expected symbol' do
100
102
  expect(subject.next_symbol).to eq(t_c)
101
103
  end
102
-
104
+
103
105
  it 'should know whether another instance follows this one' do
104
106
  expect(subject.precedes?(subject)).to eq(false)
105
107
  state1 = new_parse_state(sample_prod, 1, origin_val)
@@ -110,7 +112,7 @@ module Rley # Open this namespace to avoid module qualifier prefixes
110
112
  state3 = new_parse_state(sample_prod, 3, origin_val)
111
113
  expect(state3.precedes?(state0)).to eq(false)
112
114
  end
113
-
115
+
114
116
  it 'should know its text representation' do
115
117
  expected = 'sentence => A B . C | 3'
116
118
  expect(subject.to_s).to eq(expected)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative '../../spec_helper'
2
4
  require 'stringio'
3
5
 
@@ -14,7 +16,7 @@ require_relative '../../../lib/rley/parser/parse_tracer'
14
16
  module Rley # Open this namespace to avoid module qualifier prefixes
15
17
  module Parser # Open this namespace to avoid module qualifier prefixes
16
18
  describe ParseTracer do
17
- let(:output) { StringIO.new('', 'w') }
19
+ let(:output) { StringIO.new(+'', 'w') }
18
20
  let(:tpos) { Lexical::Position.new(3, 4) }
19
21
 
20
22
  let(:token_seq) do
@@ -82,7 +84,7 @@ SNIPPET
82
84
 
83
85
  it 'should render a scanning step' do
84
86
  # Case: token at the beginning
85
- subject.ostream.string = ''
87
+ subject.ostream.string = +''
86
88
  subject.trace_scanning(1, parse_state(0, dotted_rule))
87
89
  expectations = <<-SNIPPET
88
90
  |[------] . . . . .| [0:1] sentence => A B . C
@@ -90,7 +92,7 @@ SNIPPET
90
92
  expect(output.string).to eq(expectations)
91
93
 
92
94
  # Case: token in the middle
93
- subject.ostream.string = ''
95
+ subject.ostream.string = +''
94
96
  subject.trace_scanning(4, sample_parse_state)
95
97
  expectations = <<-SNIPPET
96
98
  |. . . [------] . .| [3:4] sentence => A B . C
@@ -98,7 +100,7 @@ SNIPPET
98
100
  expect(output.string).to eq(expectations)
99
101
 
100
102
  # Case: token at the end
101
- subject.ostream.string = ''
103
+ subject.ostream.string = +''
102
104
  subject.trace_scanning(6, parse_state(5, dotted_rule))
103
105
  expectations = <<-SNIPPET
104
106
  |. . . . . [------]| [5:6] sentence => A B . C
@@ -109,7 +111,7 @@ SNIPPET
109
111
 
110
112
  it 'should render a prediction step' do
111
113
  # Case: initial stateset
112
- subject.ostream.string = ''
114
+ subject.ostream.string = +''
113
115
  subject.trace_prediction(0, parse_state(0, dotted_rule))
114
116
  expectations = <<-SNIPPET
115
117
  |> . . . . . .| [0:0] sentence => A B . C
@@ -117,7 +119,7 @@ SNIPPET
117
119
  expect(output.string).to eq(expectations)
118
120
 
119
121
  # Case: stateset in the middle
120
- subject.ostream.string = ''
122
+ subject.ostream.string = +''
121
123
  subject.trace_prediction(3, sample_parse_state)
122
124
  expectations = <<-SNIPPET
123
125
  |. . . > . . .| [3:3] sentence => A B . C
@@ -125,7 +127,7 @@ SNIPPET
125
127
  expect(output.string).to eq(expectations)
126
128
 
127
129
  # Case: final stateset
128
- subject.ostream.string = ''
130
+ subject.ostream.string = +''
129
131
  subject.trace_prediction(6, parse_state(6, dotted_rule))
130
132
  expectations = <<-SNIPPET
131
133
  |. . . . . . >| [6:6] sentence => A B . C
@@ -135,7 +137,7 @@ SNIPPET
135
137
 
136
138
  it 'should render a completion step' do
137
139
  # Case: full parse completed
138
- subject.ostream.string = ''
140
+ subject.ostream.string = +''
139
141
  subject.trace_completion(6, parse_state(0, complete_rule))
140
142
  expectations = <<-SNIPPET
141
143
  |[=========================================]| [0:6] sentence => A B C .
@@ -143,7 +145,7 @@ SNIPPET
143
145
  expect(output.string).to eq(expectations)
144
146
 
145
147
  # Case: step at the start (complete)
146
- subject.ostream.string = ''
148
+ subject.ostream.string = +''
147
149
  subject.trace_completion(1, parse_state(0, complete_rule))
148
150
  expectations = <<-SNIPPET
149
151
  |[------] . . . . .| [0:1] sentence => A B C .
@@ -151,7 +153,7 @@ SNIPPET
151
153
  expect(output.string).to eq(expectations)
152
154
 
153
155
  # Case: step at the start (not complete)
154
- subject.ostream.string = ''
156
+ subject.ostream.string = +''
155
157
  subject.trace_completion(1, parse_state(0, dotted_rule))
156
158
  expectations = <<-SNIPPET
157
159
  |[------> . . . . .| [0:1] sentence => A B . C
@@ -159,7 +161,7 @@ SNIPPET
159
161
  expect(output.string).to eq(expectations)
160
162
 
161
163
  # Case: step at the middle (complete)
162
- subject.ostream.string = ''
164
+ subject.ostream.string = +''
163
165
  subject.trace_completion(4, parse_state(2, complete_rule))
164
166
  expectations = <<-SNIPPET
165
167
  |. . [-------------] . .| [2:4] sentence => A B C .
@@ -167,7 +169,7 @@ SNIPPET
167
169
  expect(output.string).to eq(expectations)
168
170
 
169
171
  # Case: step at the middle (not complete)
170
- subject.ostream.string = ''
172
+ subject.ostream.string = +''
171
173
  subject.trace_completion(4, parse_state(2, dotted_rule))
172
174
  expectations = <<-SNIPPET
173
175
  |. . [-------------> . .| [2:4] sentence => A B . C
@@ -175,7 +177,7 @@ SNIPPET
175
177
  expect(output.string).to eq(expectations)
176
178
 
177
179
  # Case: step at the end (complete)
178
- subject.ostream.string = ''
180
+ subject.ostream.string = +''
179
181
  subject.trace_completion(6, parse_state(3, complete_rule))
180
182
  expectations = <<-SNIPPET
181
183
  |. . . [--------------------]| [3:6] sentence => A B C .
@@ -183,7 +185,7 @@ SNIPPET
183
185
  expect(output.string).to eq(expectations)
184
186
 
185
187
  # Case: step at the end (not complete)
186
- subject.ostream.string = ''
188
+ subject.ostream.string = +''
187
189
  subject.trace_completion(6, parse_state(3, dotted_rule))
188
190
  expectations = <<-SNIPPET
189
191
  |. . . [-------------------->| [3:6] sentence => A B . C
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative '../../spec_helper'
2
4
 
3
5
  require_relative '../../../lib/rley/syntax/grammar_builder'
@@ -45,13 +47,13 @@ module Rley # Open this namespace to avoid module qualifier prefixes
45
47
  # contains a hidden left recursion and a cycle
46
48
  builder = Syntax::GrammarBuilder.new do
47
49
  add_terminals('a', 'b')
48
- rule'Phi' => 'S'
49
- rule'S' => %w[A T]
50
- rule'S' => %w[a T]
51
- rule'A' => 'a'
52
- rule'A' => %w[B A]
53
- rule'B' => []
54
- rule'T' => %w[b b b]
50
+ rule 'Phi' => 'S'
51
+ rule 'S' => %w[A T]
52
+ rule 'S' => %w[a T]
53
+ rule 'A' => 'a'
54
+ rule 'A' => %w[B A]
55
+ rule 'B' => []
56
+ rule 'T' => %w[b b b]
55
57
  end
56
58
  builder.grammar
57
59
  end
@@ -301,7 +303,7 @@ module Rley # Open this namespace to avoid module qualifier prefixes
301
303
  event18 = walker.next
302
304
  expectations = [:revisit, 'T. | 1', 4]
303
305
  event_expectations(event18, expectations)
304
-
306
+
305
307
  # Lazy walk: make start entry .T the current one
306
308
  # Multiple visit occurred: jump to antecedent of start entry
307
309
  event19 = walker.next
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative '../../spec_helper'
2
4
 
3
5
  require_relative '../../../lib/rley/parser/parse_state'
@@ -17,7 +19,7 @@ module Rley # Open this namespace to avoid module qualifier prefixes
17
19
  it 'should be created without argument' do
18
20
  expect { StateSet.new }.not_to raise_error
19
21
  end
20
-
22
+
21
23
  it 'should be empty at creation' do
22
24
  expect(subject.states).to be_empty
23
25
  end
@@ -31,19 +33,19 @@ module Rley # Open this namespace to avoid module qualifier prefixes
31
33
  subject.push_state(state2)
32
34
  expect(subject.states).to eq([state1, state2])
33
35
  end
34
-
36
+
35
37
  it 'should ignore a second push of a state' do
36
38
  expect(subject.states).to be_empty
37
39
  subject.push_state(state1)
38
40
  subject.push_state(state2)
39
41
  expect(subject.states).to eq([state1, state2])
40
-
42
+
41
43
  # One tries to push an already pushed state
42
44
  expect(subject.push_state(state1)).to be_falsy
43
-
45
+
44
46
  # ...It is not added
45
- expect(subject.states).to eq([state1, state2])
46
- end
47
+ expect(subject.states).to eq([state1, state2])
48
+ end
47
49
 
48
50
  it 'should list the states expecting a given terminal' do
49
51
  # Case of no state
@@ -71,52 +73,52 @@ module Rley # Open this namespace to avoid module qualifier prefixes
71
73
  expect(dotted_rule2).to receive(:production).and_return(a_prod)
72
74
  expect(subject.states_for(a_prod)).to eq([state2])
73
75
  end
74
-
76
+
75
77
  it 'should list the states that rewrite a given non-terminal' do
76
78
  non_term = double('fake-non-terminal')
77
79
  prod1 = double('fake-production1')
78
80
  prod2 = double('fake-production2')
79
-
81
+
80
82
  # Adding states
81
83
  subject.push_state(state1)
82
84
  subject.push_state(state2)
83
85
  expect(dotted_rule1).to receive(:production).and_return(prod1)
84
- expect(prod1).to receive(:lhs).and_return(:dummy)
86
+ expect(prod1).to receive(:lhs).and_return(:dummy)
85
87
  expect(dotted_rule2).to receive(:production).and_return(prod2)
86
88
  expect(dotted_rule2).to receive(:reduce_item?).and_return(true)
87
- expect(prod2).to receive(:lhs).and_return(non_term)
89
+ expect(prod2).to receive(:lhs).and_return(non_term)
88
90
  expect(subject.states_rewriting(non_term)).to eq([state2])
89
91
  end
90
-
92
+
91
93
  it 'should list of ambiguous states' do
92
94
  prod1 = double('fake-production1')
93
95
  prod2 = double('fake-production2')
94
96
  expect(subject.ambiguities.size).to eq(0)
95
-
97
+
96
98
  # Adding states
97
99
  subject.push_state(state1)
98
100
  allow(dotted_rule1).to receive(:production).and_return(prod1)
99
- allow(dotted_rule1).to receive(:"reduce_item?").and_return(true)
100
- allow(dotted_rule1).to receive(:lhs).and_return(:something)
101
+ allow(dotted_rule1).to receive(:reduce_item?).and_return(true)
102
+ allow(dotted_rule1).to receive(:lhs).and_return(:something)
101
103
  expect(subject.ambiguities.size).to eq(0)
102
104
  allow(dotted_rule2).to receive(:production).and_return(prod2)
103
- allow(dotted_rule2).to receive(:"reduce_item?").and_return(true)
104
- allow(dotted_rule2).to receive(:lhs).and_return(:something_else)
105
+ allow(dotted_rule2).to receive(:reduce_item?).and_return(true)
106
+ allow(dotted_rule2).to receive(:lhs).and_return(:something_else)
105
107
  subject.push_state(state2)
106
108
  expect(subject.ambiguities.size).to eq(0)
107
109
  dotted_rule3 = double('fake_dotted_rule3')
108
110
  allow(dotted_rule3).to receive(:production).and_return(prod2)
109
- allow(dotted_rule3).to receive(:"reduce_item?").and_return(true)
110
- allow(dotted_rule3).to receive(:lhs).and_return(:something_else)
111
+ allow(dotted_rule3).to receive(:reduce_item?).and_return(true)
112
+ allow(dotted_rule3).to receive(:lhs).and_return(:something_else)
111
113
  state3 = ParseState.new(dotted_rule3, 5)
112
- subject.push_state(state3)
113
- expect(subject.ambiguities[0]).to eq([state2, state3])
114
+ subject.push_state(state3)
115
+ expect(subject.ambiguities[0]).to eq([state2, state3])
114
116
  end
115
-
117
+
116
118
  it 'should complain when impossible predecessor of parse state' do
117
119
  subject.push_state(state1)
118
120
  subject.push_state(state2)
119
- expect(dotted_rule1).to receive(:prev_position).and_return(nil)
121
+ expect(dotted_rule1).to receive(:prev_position).and_return(nil)
120
122
  err = StandardError
121
123
  expect { subject.predecessor_state(state1) }.to raise_error(err)
122
124
  end