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.
- checksums.yaml +4 -4
- data/.rubocop.yml +362 -62
- data/.travis.yml +6 -7
- data/CHANGELOG.md +20 -1
- data/LICENSE.txt +1 -1
- data/README.md +6 -7
- data/Rakefile +2 -0
- data/appveyor.yml +2 -4
- data/examples/NLP/benchmark_pico_en.rb +2 -0
- data/examples/NLP/engtagger.rb +193 -188
- data/examples/NLP/nano_eng/nano_en_demo.rb +2 -0
- data/examples/NLP/nano_eng/nano_grammar.rb +7 -5
- data/examples/NLP/pico_en_demo.rb +2 -0
- data/examples/data_formats/JSON/cli_options.rb +3 -1
- data/examples/data_formats/JSON/json_ast_builder.rb +14 -9
- data/examples/data_formats/JSON/json_ast_nodes.rb +14 -21
- data/examples/data_formats/JSON/json_demo.rb +2 -0
- data/examples/data_formats/JSON/json_grammar.rb +4 -2
- data/examples/data_formats/JSON/json_lexer.rb +10 -8
- data/examples/data_formats/JSON/json_minifier.rb +3 -1
- data/examples/general/calc_iter1/calc_ast_builder.rb +15 -10
- data/examples/general/calc_iter1/calc_ast_nodes.rb +25 -37
- data/examples/general/calc_iter1/calc_demo.rb +2 -0
- data/examples/general/calc_iter1/calc_grammar.rb +4 -2
- data/examples/general/calc_iter1/calc_lexer.rb +8 -4
- data/examples/general/calc_iter1/spec/calculator_spec.rb +7 -5
- data/examples/general/calc_iter2/calc_ast_builder.rb +7 -3
- data/examples/general/calc_iter2/calc_ast_nodes.rb +29 -43
- data/examples/general/calc_iter2/calc_demo.rb +2 -0
- data/examples/general/calc_iter2/calc_grammar.rb +5 -3
- data/examples/general/calc_iter2/calc_lexer.rb +13 -10
- data/examples/general/calc_iter2/spec/calculator_spec.rb +28 -26
- data/examples/general/left.rb +4 -2
- data/examples/general/right.rb +4 -2
- data/lib/rley.rb +2 -0
- data/lib/rley/base/base_parser.rb +2 -0
- data/lib/rley/base/dotted_item.rb +38 -41
- data/lib/rley/base/grm_items_builder.rb +2 -0
- data/lib/rley/constants.rb +5 -3
- data/lib/rley/engine.rb +22 -24
- data/lib/rley/formatter/asciitree.rb +6 -4
- data/lib/rley/formatter/base_formatter.rb +2 -0
- data/lib/rley/formatter/bracket_notation.rb +3 -8
- data/lib/rley/formatter/debug.rb +8 -6
- data/lib/rley/formatter/json.rb +4 -2
- data/lib/rley/gfg/call_edge.rb +3 -1
- data/lib/rley/gfg/edge.rb +7 -5
- data/lib/rley/gfg/end_vertex.rb +4 -6
- data/lib/rley/gfg/epsilon_edge.rb +3 -5
- data/lib/rley/gfg/grm_flow_graph.rb +31 -25
- data/lib/rley/gfg/item_vertex.rb +12 -22
- data/lib/rley/gfg/non_terminal_vertex.rb +6 -4
- data/lib/rley/gfg/return_edge.rb +2 -0
- data/lib/rley/gfg/scan_edge.rb +3 -1
- data/lib/rley/gfg/shortcut_edge.rb +4 -2
- data/lib/rley/gfg/start_vertex.rb +6 -8
- data/lib/rley/gfg/vertex.rb +47 -41
- data/lib/rley/lexical/token.rb +3 -1
- data/lib/rley/lexical/token_range.rb +8 -6
- data/lib/rley/parse_forest_visitor.rb +7 -5
- data/lib/rley/parse_rep/ast_base_builder.rb +11 -11
- data/lib/rley/parse_rep/cst_builder.rb +7 -4
- data/lib/rley/parse_rep/parse_forest_builder.rb +36 -25
- data/lib/rley/parse_rep/parse_forest_factory.rb +5 -3
- data/lib/rley/parse_rep/parse_rep_creator.rb +18 -13
- data/lib/rley/parse_rep/parse_tree_builder.rb +15 -15
- data/lib/rley/parse_rep/parse_tree_factory.rb +27 -25
- data/lib/rley/parse_tree_visitor.rb +3 -1
- data/lib/rley/parser/error_reason.rb +9 -8
- data/lib/rley/parser/gfg_chart.rb +54 -22
- data/lib/rley/parser/gfg_earley_parser.rb +3 -1
- data/lib/rley/parser/gfg_parsing.rb +51 -31
- data/lib/rley/parser/parse_entry.rb +29 -33
- data/lib/rley/parser/parse_entry_set.rb +32 -27
- data/lib/rley/parser/parse_entry_tracker.rb +6 -4
- data/lib/rley/parser/parse_state.rb +18 -21
- data/lib/rley/parser/parse_state_tracker.rb +6 -4
- data/lib/rley/parser/parse_tracer.rb +15 -13
- data/lib/rley/parser/parse_walker_factory.rb +28 -29
- data/lib/rley/parser/state_set.rb +11 -10
- data/lib/rley/ptree/non_terminal_node.rb +10 -6
- data/lib/rley/ptree/parse_tree.rb +6 -4
- data/lib/rley/ptree/parse_tree_node.rb +7 -5
- data/lib/rley/ptree/terminal_node.rb +9 -7
- data/lib/rley/rley_error.rb +12 -10
- data/lib/rley/sppf/alternative_node.rb +8 -6
- data/lib/rley/sppf/composite_node.rb +9 -7
- data/lib/rley/sppf/epsilon_node.rb +5 -3
- data/lib/rley/sppf/leaf_node.rb +5 -3
- data/lib/rley/sppf/non_terminal_node.rb +2 -0
- data/lib/rley/sppf/parse_forest.rb +19 -17
- data/lib/rley/sppf/sppf_node.rb +9 -8
- data/lib/rley/sppf/token_node.rb +5 -3
- data/lib/rley/syntax/grammar.rb +7 -5
- data/lib/rley/syntax/grammar_builder.rb +11 -9
- data/lib/rley/syntax/grm_symbol.rb +8 -6
- data/lib/rley/syntax/literal.rb +2 -0
- data/lib/rley/syntax/non_terminal.rb +11 -15
- data/lib/rley/syntax/production.rb +13 -11
- data/lib/rley/syntax/symbol_seq.rb +10 -10
- data/lib/rley/syntax/terminal.rb +6 -5
- data/lib/rley/syntax/verbatim_symbol.rb +5 -3
- data/lib/support/base_tokenizer.rb +23 -20
- data/spec/rley/base/dotted_item_spec.rb +4 -2
- data/spec/rley/base/grm_items_builder_spec.rb +2 -0
- data/spec/rley/engine_spec.rb +47 -9
- data/spec/rley/formatter/asciitree_spec.rb +11 -9
- data/spec/rley/formatter/bracket_notation_spec.rb +16 -14
- data/spec/rley/formatter/debug_spec.rb +4 -2
- data/spec/rley/formatter/json_spec.rb +5 -3
- data/spec/rley/gfg/call_edge_spec.rb +2 -0
- data/spec/rley/gfg/edge_spec.rb +2 -0
- data/spec/rley/gfg/end_vertex_spec.rb +7 -5
- data/spec/rley/gfg/epsilon_edge_spec.rb +2 -0
- data/spec/rley/gfg/grm_flow_graph_spec.rb +2 -0
- data/spec/rley/gfg/item_vertex_spec.rb +12 -10
- data/spec/rley/gfg/non_terminal_vertex_spec.rb +5 -3
- data/spec/rley/gfg/return_edge_spec.rb +2 -0
- data/spec/rley/gfg/scan_edge_spec.rb +2 -0
- data/spec/rley/gfg/shortcut_edge_spec.rb +3 -1
- data/spec/rley/gfg/start_vertex_spec.rb +7 -5
- data/spec/rley/gfg/vertex_spec.rb +5 -3
- data/spec/rley/lexical/token_range_spec.rb +18 -16
- data/spec/rley/lexical/token_spec.rb +4 -2
- data/spec/rley/parse_forest_visitor_spec.rb +167 -163
- data/spec/rley/parse_rep/ambiguous_parse_spec.rb +46 -44
- data/spec/rley/parse_rep/ast_builder_spec.rb +8 -6
- data/spec/rley/parse_rep/cst_builder_spec.rb +7 -5
- data/spec/rley/parse_rep/groucho_spec.rb +25 -25
- data/spec/rley/parse_rep/parse_forest_builder_spec.rb +28 -26
- data/spec/rley/parse_rep/parse_forest_factory_spec.rb +8 -6
- data/spec/rley/parse_rep/parse_tree_factory_spec.rb +4 -2
- data/spec/rley/parse_tree_visitor_spec.rb +12 -8
- data/spec/rley/parser/error_reason_spec.rb +8 -6
- data/spec/rley/parser/gfg_chart_spec.rb +17 -4
- data/spec/rley/parser/gfg_earley_parser_spec.rb +16 -11
- data/spec/rley/parser/gfg_parsing_spec.rb +41 -252
- data/spec/rley/parser/parse_entry_set_spec.rb +2 -0
- data/spec/rley/parser/parse_entry_spec.rb +21 -19
- data/spec/rley/parser/parse_state_spec.rb +7 -5
- data/spec/rley/parser/parse_tracer_spec.rb +16 -14
- data/spec/rley/parser/parse_walker_factory_spec.rb +10 -8
- data/spec/rley/parser/state_set_spec.rb +24 -22
- data/spec/rley/ptree/non_terminal_node_spec.rb +7 -3
- data/spec/rley/ptree/parse_tree_node_spec.rb +6 -4
- data/spec/rley/ptree/parse_tree_spec.rb +2 -0
- data/spec/rley/ptree/terminal_node_spec.rb +8 -6
- data/spec/rley/sppf/alternative_node_spec.rb +8 -6
- data/spec/rley/sppf/non_terminal_node_spec.rb +5 -3
- data/spec/rley/sppf/token_node_spec.rb +6 -4
- data/spec/rley/support/ambiguous_grammar_helper.rb +5 -4
- data/spec/rley/support/expectation_helper.rb +2 -0
- data/spec/rley/support/grammar_abc_helper.rb +4 -4
- data/spec/rley/support/grammar_ambig01_helper.rb +6 -5
- data/spec/rley/support/grammar_arr_int_helper.rb +6 -5
- data/spec/rley/support/grammar_b_expr_helper.rb +6 -5
- data/spec/rley/support/grammar_helper.rb +2 -0
- data/spec/rley/support/grammar_l0_helper.rb +15 -16
- data/spec/rley/support/grammar_pb_helper.rb +8 -5
- data/spec/rley/support/grammar_sppf_helper.rb +3 -1
- data/spec/rley/syntax/grammar_builder_spec.rb +7 -5
- data/spec/rley/syntax/grammar_spec.rb +8 -6
- data/spec/rley/syntax/grm_symbol_spec.rb +3 -1
- data/spec/rley/syntax/literal_spec.rb +2 -0
- data/spec/rley/syntax/non_terminal_spec.rb +10 -8
- data/spec/rley/syntax/production_spec.rb +15 -13
- data/spec/rley/syntax/symbol_seq_spec.rb +4 -2
- data/spec/rley/syntax/terminal_spec.rb +7 -5
- data/spec/rley/syntax/verbatim_symbol_spec.rb +3 -1
- data/spec/spec_helper.rb +2 -12
- data/spec/support/base_tokenizer_spec.rb +9 -2
- metadata +21 -63
- data/.simplecov +0 -7
- 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/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(:
|
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(:
|
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(:
|
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
|