rley 0.7.08 → 0.8.03
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +29 -5
- data/CHANGELOG.md +28 -4
- data/README.md +4 -5
- data/examples/NLP/nano_eng/nano_en_demo.rb +7 -11
- data/examples/NLP/nano_eng/nano_grammar.rb +18 -18
- data/examples/data_formats/JSON/json_ast_builder.rb +9 -18
- data/examples/data_formats/JSON/json_demo.rb +1 -2
- data/examples/data_formats/JSON/json_grammar.rb +11 -11
- data/examples/general/calc_iter1/calc_grammar.rb +5 -4
- data/examples/general/calc_iter2/calc_grammar.rb +9 -9
- data/examples/general/left.rb +1 -1
- data/examples/general/right.rb +1 -1
- data/lib/rley/base/dotted_item.rb +5 -0
- data/lib/rley/base/grm_items_builder.rb +6 -0
- data/lib/rley/constants.rb +1 -1
- data/lib/rley/engine.rb +2 -2
- data/lib/rley/interface.rb +16 -0
- data/lib/rley/notation/all_notation_nodes.rb +4 -0
- data/lib/rley/notation/ast_builder.rb +185 -0
- data/lib/rley/notation/ast_node.rb +44 -0
- data/lib/rley/notation/ast_visitor.rb +115 -0
- data/lib/rley/notation/grammar.rb +49 -0
- data/lib/rley/notation/grammar_builder.rb +505 -0
- data/lib/rley/notation/grouping_node.rb +23 -0
- data/lib/rley/notation/parser.rb +56 -0
- data/lib/rley/notation/sequence_node.rb +35 -0
- data/lib/rley/notation/symbol_node.rb +29 -0
- data/lib/rley/notation/tokenizer.rb +180 -0
- data/lib/rley/parse_rep/ast_base_builder.rb +44 -0
- data/lib/rley/parser/gfg_chart.rb +101 -6
- data/lib/rley/parser/gfg_earley_parser.rb +1 -1
- data/lib/rley/parser/gfg_parsing.rb +5 -3
- data/lib/rley/parser/parse_entry_set.rb +1 -1
- data/lib/rley/syntax/{grammar_builder.rb → base_grammar_builder.rb} +53 -15
- data/lib/rley/syntax/grm_symbol.rb +1 -1
- data/lib/rley/syntax/match_closest.rb +43 -0
- data/lib/rley/syntax/production.rb +6 -0
- data/lib/rley.rb +1 -1
- data/spec/rley/engine_spec.rb +6 -6
- data/spec/rley/gfg/grm_flow_graph_spec.rb +2 -2
- data/spec/rley/notation/grammar_builder_spec.rb +302 -0
- data/spec/rley/notation/parser_spec.rb +183 -0
- data/spec/rley/notation/tokenizer_spec.rb +364 -0
- data/spec/rley/parse_rep/ast_builder_spec.rb +0 -1
- data/spec/rley/parse_rep/groucho_spec.rb +1 -1
- data/spec/rley/parse_rep/parse_forest_builder_spec.rb +1 -1
- data/spec/rley/parse_rep/parse_forest_factory_spec.rb +2 -2
- data/spec/rley/parse_rep/parse_tree_factory_spec.rb +1 -1
- data/spec/rley/parser/dangling_else_spec.rb +447 -0
- data/spec/rley/parser/gfg_earley_parser_spec.rb +118 -10
- data/spec/rley/parser/gfg_parsing_spec.rb +2 -1
- data/spec/rley/parser/parse_walker_factory_spec.rb +2 -2
- data/spec/rley/support/ambiguous_grammar_helper.rb +2 -2
- data/spec/rley/support/grammar_abc_helper.rb +2 -2
- data/spec/rley/support/grammar_ambig01_helper.rb +2 -2
- data/spec/rley/support/grammar_arr_int_helper.rb +2 -2
- data/spec/rley/support/grammar_b_expr_helper.rb +2 -2
- data/spec/rley/support/grammar_int_seq_helper.rb +51 -0
- data/spec/rley/support/grammar_l0_helper.rb +2 -2
- data/spec/rley/support/grammar_pb_helper.rb +2 -2
- data/spec/rley/support/grammar_sppf_helper.rb +2 -2
- data/spec/rley/syntax/{grammar_builder_spec.rb → base_grammar_builder_spec.rb} +29 -11
- data/spec/rley/syntax/match_closest_spec.rb +46 -0
- data/spec/rley/syntax/production_spec.rb +4 -0
- metadata +29 -14
- data/lib/rley/parser/parse_state.rb +0 -78
- data/lib/rley/parser/parse_state_tracker.rb +0 -59
- data/lib/rley/parser/state_set.rb +0 -100
- data/spec/rley/parser/parse_state_spec.rb +0 -125
- data/spec/rley/parser/parse_tracer_spec.rb +0 -200
- 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.
|
4
|
+
version: 0.8.03
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dimitri Geshef
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-08-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -136,8 +136,20 @@ files:
|
|
136
136
|
- lib/rley/gfg/shortcut_edge.rb
|
137
137
|
- lib/rley/gfg/start_vertex.rb
|
138
138
|
- lib/rley/gfg/vertex.rb
|
139
|
+
- lib/rley/interface.rb
|
139
140
|
- lib/rley/lexical/token.rb
|
140
141
|
- lib/rley/lexical/token_range.rb
|
142
|
+
- lib/rley/notation/all_notation_nodes.rb
|
143
|
+
- lib/rley/notation/ast_builder.rb
|
144
|
+
- lib/rley/notation/ast_node.rb
|
145
|
+
- lib/rley/notation/ast_visitor.rb
|
146
|
+
- lib/rley/notation/grammar.rb
|
147
|
+
- lib/rley/notation/grammar_builder.rb
|
148
|
+
- lib/rley/notation/grouping_node.rb
|
149
|
+
- lib/rley/notation/parser.rb
|
150
|
+
- lib/rley/notation/sequence_node.rb
|
151
|
+
- lib/rley/notation/symbol_node.rb
|
152
|
+
- lib/rley/notation/tokenizer.rb
|
141
153
|
- lib/rley/parse_forest_visitor.rb
|
142
154
|
- lib/rley/parse_rep/ast_base_builder.rb
|
143
155
|
- lib/rley/parse_rep/cst_builder.rb
|
@@ -154,11 +166,8 @@ files:
|
|
154
166
|
- lib/rley/parser/parse_entry.rb
|
155
167
|
- lib/rley/parser/parse_entry_set.rb
|
156
168
|
- lib/rley/parser/parse_entry_tracker.rb
|
157
|
-
- lib/rley/parser/parse_state.rb
|
158
|
-
- lib/rley/parser/parse_state_tracker.rb
|
159
169
|
- lib/rley/parser/parse_tracer.rb
|
160
170
|
- lib/rley/parser/parse_walker_factory.rb
|
161
|
-
- lib/rley/parser/state_set.rb
|
162
171
|
- lib/rley/ptree/non_terminal_node.rb
|
163
172
|
- lib/rley/ptree/parse_tree.rb
|
164
173
|
- lib/rley/ptree/parse_tree_node.rb
|
@@ -172,10 +181,11 @@ files:
|
|
172
181
|
- lib/rley/sppf/parse_forest.rb
|
173
182
|
- lib/rley/sppf/sppf_node.rb
|
174
183
|
- lib/rley/sppf/token_node.rb
|
184
|
+
- lib/rley/syntax/base_grammar_builder.rb
|
175
185
|
- lib/rley/syntax/grammar.rb
|
176
|
-
- lib/rley/syntax/grammar_builder.rb
|
177
186
|
- lib/rley/syntax/grm_symbol.rb
|
178
187
|
- lib/rley/syntax/literal.rb
|
188
|
+
- lib/rley/syntax/match_closest.rb
|
179
189
|
- lib/rley/syntax/non_terminal.rb
|
180
190
|
- lib/rley/syntax/production.rb
|
181
191
|
- lib/rley/syntax/symbol_seq.rb
|
@@ -203,6 +213,9 @@ files:
|
|
203
213
|
- spec/rley/gfg/vertex_spec.rb
|
204
214
|
- spec/rley/lexical/token_range_spec.rb
|
205
215
|
- spec/rley/lexical/token_spec.rb
|
216
|
+
- spec/rley/notation/grammar_builder_spec.rb
|
217
|
+
- spec/rley/notation/parser_spec.rb
|
218
|
+
- spec/rley/notation/tokenizer_spec.rb
|
206
219
|
- spec/rley/parse_forest_visitor_spec.rb
|
207
220
|
- spec/rley/parse_rep/ambiguous_parse_spec.rb
|
208
221
|
- spec/rley/parse_rep/ast_builder_spec.rb
|
@@ -212,16 +225,14 @@ files:
|
|
212
225
|
- spec/rley/parse_rep/parse_forest_factory_spec.rb
|
213
226
|
- spec/rley/parse_rep/parse_tree_factory_spec.rb
|
214
227
|
- spec/rley/parse_tree_visitor_spec.rb
|
228
|
+
- spec/rley/parser/dangling_else_spec.rb
|
215
229
|
- spec/rley/parser/error_reason_spec.rb
|
216
230
|
- spec/rley/parser/gfg_chart_spec.rb
|
217
231
|
- spec/rley/parser/gfg_earley_parser_spec.rb
|
218
232
|
- spec/rley/parser/gfg_parsing_spec.rb
|
219
233
|
- spec/rley/parser/parse_entry_set_spec.rb
|
220
234
|
- spec/rley/parser/parse_entry_spec.rb
|
221
|
-
- spec/rley/parser/parse_state_spec.rb
|
222
|
-
- spec/rley/parser/parse_tracer_spec.rb
|
223
235
|
- spec/rley/parser/parse_walker_factory_spec.rb
|
224
|
-
- spec/rley/parser/state_set_spec.rb
|
225
236
|
- spec/rley/ptree/non_terminal_node_spec.rb
|
226
237
|
- spec/rley/ptree/parse_tree_node_spec.rb
|
227
238
|
- spec/rley/ptree/parse_tree_spec.rb
|
@@ -236,13 +247,15 @@ files:
|
|
236
247
|
- spec/rley/support/grammar_arr_int_helper.rb
|
237
248
|
- spec/rley/support/grammar_b_expr_helper.rb
|
238
249
|
- spec/rley/support/grammar_helper.rb
|
250
|
+
- spec/rley/support/grammar_int_seq_helper.rb
|
239
251
|
- spec/rley/support/grammar_l0_helper.rb
|
240
252
|
- spec/rley/support/grammar_pb_helper.rb
|
241
253
|
- spec/rley/support/grammar_sppf_helper.rb
|
242
|
-
- spec/rley/syntax/
|
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/
|
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
|