rley 0.7.03 → 0.7.08
Sign up to get free protection for your applications and to get access to all the features.
- 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
|