rley 0.0.17 → 0.0.18
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 +8 -8
- data/lib/rley/constants.rb +1 -1
- data/lib/rley/parser/earley_parser.rb +5 -1
- data/lib/rley/parser/state_set.rb +9 -9
- data/lib/rley/syntax/grammar.rb +2 -2
- data/lib/rley/syntax/non_terminal.rb +1 -8
- data/lib/rley/syntax/terminal.rb +3 -3
- data/spec/rley/parser/dotted_item_spec.rb +1 -1
- data/spec/rley/parser/earley_parser_spec.rb +104 -77
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
N2Y1Yjg4Mzg5ZWI5YjU1NzBkMzYzOWNkNTMzMzA4NGJjYjgwYWE2Yw==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
NDk0ZDFjNTkxZjNjZTE0NTRhNGFkMTc3YzYxNjY3NWExNzI0ZWMzOQ==
|
7
7
|
!binary "U0hBNTEy":
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
ZGRkMzE5Y2ExNmIwNThkNmZhYmVmZTNmMTc5ZjQxODEyZjU0MTdkZDMyNGVl
|
10
|
+
ZmNlYzc4MjY4ZDJjNTA0NzU2MWUzMTFhNTVjNjAxZWVhYTMxYmM3NDI0MjM1
|
11
|
+
Yjg0MTA3ODkzNTA5MjQ2NTVhNDY2ODdmNWIyMTAxNDlmMmJiMWE=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
NGQ4NjBkNGExZTdlNTkxMDEzNDAwYWEyNjE5NTJlZjhlYWI2Mjc0OTdjNjVl
|
14
|
+
YWU2MzJiOWJkZmViNGMyNGJhZTYxM2Q4Y2FkMGJhOTM0YjJkNjczOTExYTgy
|
15
|
+
NjQwNDVhODZiODUwY2EwOTBlMzJhY2JjODc3OTZkY2QwZTQ3MWE=
|
data/lib/rley/constants.rb
CHANGED
@@ -37,6 +37,7 @@ module Rley # This module is used as a namespace
|
|
37
37
|
result = Parsing.new(start_dotted_item, aTokenSequence)
|
38
38
|
last_token_index = aTokenSequence.size
|
39
39
|
(0..last_token_index).each do |i|
|
40
|
+
predicted = Set.new
|
40
41
|
result.chart[i].each do |state|
|
41
42
|
if state.complete?
|
42
43
|
# parse reached end of production
|
@@ -44,7 +45,10 @@ module Rley # This module is used as a namespace
|
|
44
45
|
else
|
45
46
|
next_symbol = state.next_symbol
|
46
47
|
if next_symbol.kind_of?(Syntax::NonTerminal)
|
47
|
-
|
48
|
+
unless predicted.include? next_symbol
|
49
|
+
prediction(result, state, next_symbol, i)
|
50
|
+
predicted << next_symbol # Avoid repeated predictions
|
51
|
+
end
|
48
52
|
elsif i < last_token_index
|
49
53
|
# Expecting a terminal symbol
|
50
54
|
scanning(result, next_symbol, i)
|
@@ -5,34 +5,34 @@ module Rley # This module is used as a namespace
|
|
5
5
|
class StateSet
|
6
6
|
extend Forwardable
|
7
7
|
def_delegators :states, :empty?, :size, :first, :each
|
8
|
-
|
8
|
+
|
9
9
|
# The set of parse states
|
10
10
|
attr_reader(:states)
|
11
|
-
|
12
|
-
|
11
|
+
|
12
|
+
|
13
13
|
def initialize()
|
14
14
|
@states = []
|
15
15
|
end
|
16
|
-
|
17
|
-
# Append the given state (if it isn't yet in the set)
|
16
|
+
|
17
|
+
# Append the given state (if it isn't yet in the set)
|
18
18
|
# to the list of states
|
19
19
|
# @param aState [ParseState] the state to push.
|
20
20
|
def push_state(aState)
|
21
21
|
@states << aState unless include?(aState)
|
22
22
|
end
|
23
|
-
|
23
|
+
|
24
24
|
# The list of ParseState that expect the given terminal
|
25
25
|
def states_expecting(aTerminal)
|
26
26
|
return states.select { |s| s.dotted_rule.next_symbol == aTerminal }
|
27
27
|
end
|
28
|
-
|
28
|
+
|
29
29
|
# The list of ParseState that involve the given production
|
30
30
|
def states_for(aProduction)
|
31
31
|
return states.select { |s| s.dotted_rule.production == aProduction }
|
32
32
|
end
|
33
|
-
|
33
|
+
|
34
34
|
private
|
35
|
-
|
35
|
+
|
36
36
|
def include?(aState)
|
37
37
|
# TODO: make it better than linear search
|
38
38
|
return states.include?(aState)
|
data/lib/rley/syntax/grammar.rb
CHANGED
@@ -77,7 +77,7 @@ module Rley # This module is used as a namespace
|
|
77
77
|
new_nullables = Set.new
|
78
78
|
filtered_rules.each do |a_prod|
|
79
79
|
rhs_nullable = a_prod.rhs.members.all? do |symb|
|
80
|
-
nullable_sets[i-1].include? symb
|
80
|
+
nullable_sets[i - 1].include? symb
|
81
81
|
end
|
82
82
|
if rhs_nullable
|
83
83
|
a_prod.lhs.nullable = true
|
@@ -86,7 +86,7 @@ module Rley # This module is used as a namespace
|
|
86
86
|
end
|
87
87
|
break if new_nullables.empty?
|
88
88
|
filtered_rules.reject! { |prod| prod.lhs.nullable? }
|
89
|
-
nullable_sets[i] = nullable_sets[i-1].merge(new_nullables)
|
89
|
+
nullable_sets[i] = nullable_sets[i - 1].merge(new_nullables)
|
90
90
|
end
|
91
91
|
end
|
92
92
|
|
@@ -5,6 +5,7 @@ module Rley # This module is used as a namespace
|
|
5
5
|
# A non-terminal symbol (sometimes called a syntactic variable) represents
|
6
6
|
# a composition of terminal or non-terminal symbols
|
7
7
|
class NonTerminal < GrmSymbol
|
8
|
+
attr_writer(:nullable)
|
8
9
|
|
9
10
|
# Constructor.
|
10
11
|
# @param aName [String] The name of the grammar symbol.
|
@@ -22,14 +23,6 @@ module Rley # This module is used as a namespace
|
|
22
23
|
def nullable?()
|
23
24
|
return @nullable
|
24
25
|
end
|
25
|
-
|
26
|
-
# Set the nullable flag.
|
27
|
-
# @param aBoolean [true/false]
|
28
|
-
def nullable=(aBoolean)
|
29
|
-
@nullable = aBoolean
|
30
|
-
end
|
31
|
-
|
32
|
-
|
33
26
|
end # class
|
34
27
|
end # module
|
35
28
|
end # module
|
data/lib/rley/syntax/terminal.rb
CHANGED
@@ -2,7 +2,6 @@ require_relative 'grm_symbol' # Load superclass
|
|
2
2
|
|
3
3
|
module Rley # This module is used as a namespace
|
4
4
|
module Syntax # This module is used as a namespace
|
5
|
-
|
6
5
|
# A terminal symbol represents a class of words in the language
|
7
6
|
# defined the grammar.
|
8
7
|
class Terminal < GrmSymbol
|
@@ -16,9 +15,10 @@ module Rley # This module is used as a namespace
|
|
16
15
|
# @return [false] Return true if the symbol derives
|
17
16
|
# the empty string. As terminal symbol corresponds to a input token
|
18
17
|
# it is by definition non-nullable.
|
19
|
-
def nullable?()
|
18
|
+
def nullable?()
|
19
|
+
false
|
20
|
+
end
|
20
21
|
end # class
|
21
|
-
|
22
22
|
end # module
|
23
23
|
end # module
|
24
24
|
|
@@ -96,7 +96,7 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
96
96
|
end
|
97
97
|
|
98
98
|
it 'should give its text representation' do
|
99
|
-
expectation =
|
99
|
+
expectation = 'sentence => A . B C'
|
100
100
|
expect(subject.to_s).to eq(expectation)
|
101
101
|
end
|
102
102
|
end
|
@@ -164,7 +164,7 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
164
164
|
######################
|
165
165
|
# Expectation chart[0]:
|
166
166
|
expected = [
|
167
|
-
|
167
|
+
'S => . A | 0', # start rule
|
168
168
|
"A => . 'a' A 'c' | 0", # predict from 0
|
169
169
|
"A => . 'b' | 0" # predict from 0
|
170
170
|
]
|
@@ -217,7 +217,7 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
217
217
|
# Expectation chart[5]:
|
218
218
|
expected = [
|
219
219
|
"A => 'a' A 'c' . | 0", # scan from S(4) 1
|
220
|
-
|
220
|
+
'S => A . | 0' # complete from 0 and S(0) 0
|
221
221
|
]
|
222
222
|
state_set_5 = parse_result.chart[5]
|
223
223
|
expect(state_set_5.states.size).to eq(2)
|
@@ -232,12 +232,12 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
232
232
|
###################### S(0): . 2 + 3 * 4
|
233
233
|
# Expectation chart[0]:
|
234
234
|
expected = [
|
235
|
-
|
235
|
+
'P => . S | 0', # start rule
|
236
236
|
"S => . S '+' M | 0", # predict from (1)
|
237
|
-
|
237
|
+
'S => . M | 0', # predict from (1)
|
238
238
|
"M => . M '*' T | 0", # predict from (3)
|
239
|
-
|
240
|
-
|
239
|
+
'M => . T | 0', # predict from (3)
|
240
|
+
'T => . integer | 0' # predict from (3)
|
241
241
|
]
|
242
242
|
compare_state_texts(parse_result.chart[0], expected)
|
243
243
|
|
@@ -245,11 +245,11 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
245
245
|
###################### S(1): 2 . + 3 * 4
|
246
246
|
# Expectation chart[1]:
|
247
247
|
expected = [
|
248
|
-
|
249
|
-
|
250
|
-
|
248
|
+
'T => integer . | 0', # scan from S(0) 6
|
249
|
+
'M => T . | 0', # complete from (1) and S(0) 5
|
250
|
+
'S => M . | 0', # complete from (2) and S(0) 3
|
251
251
|
"M => M . '*' T | 0", # complete from (2) and S(0) 4
|
252
|
-
|
252
|
+
'P => S . | 0', # complete from (4) and S(0) 1
|
253
253
|
"S => S . '+' M | 0" # complete from (4) and S(0) 2
|
254
254
|
]
|
255
255
|
compare_state_texts(parse_result.chart[1], expected)
|
@@ -260,8 +260,8 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
260
260
|
expected = [
|
261
261
|
"S => S '+' . M | 0", # scan from S(1) 6
|
262
262
|
"M => . M '*' T | 2", # predict from (1)
|
263
|
-
|
264
|
-
|
263
|
+
'M => . T | 2', # predict from (1)
|
264
|
+
'T => . integer | 2' # predict from (3)
|
265
265
|
]
|
266
266
|
compare_state_texts(parse_result.chart[2], expected)
|
267
267
|
|
@@ -269,34 +269,68 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
269
269
|
###################### S(3): 2 + 3 . * 4
|
270
270
|
# Expectation chart[3]:
|
271
271
|
expected = [
|
272
|
-
|
273
|
-
|
272
|
+
'T => integer . | 2', # scan from S(2) 4
|
273
|
+
'M => T . | 2', # complete from (1) and S(2) 3
|
274
274
|
"S => S '+' M . | 0", # complete from (1) and S(2) 1
|
275
275
|
"M => M . '*' T | 2", # complete from (2) and S(2) 2
|
276
|
-
|
276
|
+
'P => S . | 0' # complete from (4) and S(0) 1
|
277
277
|
]
|
278
278
|
compare_state_texts(parse_result.chart[3], expected)
|
279
279
|
|
280
280
|
###################### S(4): 2 + 3 * . 4
|
281
281
|
# Expectation chart[4]:
|
282
282
|
expected = [
|
283
|
-
|
284
|
-
|
283
|
+
"M => M '*' . T | 2", # scan from S(3) 4
|
284
|
+
'T => . integer | 4' # predict from (1)
|
285
285
|
]
|
286
286
|
compare_state_texts(parse_result.chart[4], expected)
|
287
287
|
|
288
288
|
###################### S(5): 2 + 3 * 4 .
|
289
289
|
# Expectation chart[5]:
|
290
290
|
expected = [
|
291
|
-
|
291
|
+
'T => integer . | 4', # scan from S(4) 2
|
292
292
|
"M => M '*' T . | 2", # complete from (1) and S(4) 1
|
293
293
|
"S => S '+' M . | 0", # complete from (2) and S(2) 1
|
294
294
|
"M => M . '*' T | 2", # complete from (2) and S(2) 2
|
295
|
-
|
295
|
+
'P => S . | 0' # complete from (3) and S(2) 2
|
296
296
|
]
|
297
297
|
compare_state_texts(parse_result.chart[5], expected)
|
298
298
|
end
|
299
299
|
|
300
|
+
it 'should parse a nullable grammar' do
|
301
|
+
# Simple but problematic grammar for the original Earley parser
|
302
|
+
# (based on example in D. Grune, C. Jacobs "Parsing Techniques" book)
|
303
|
+
# Ss => A A 'x';
|
304
|
+
# A => ;
|
305
|
+
t_x = Syntax::VerbatimSymbol.new('x')
|
306
|
+
|
307
|
+
builder = Syntax::GrammarBuilder.new
|
308
|
+
builder.add_terminals(t_x)
|
309
|
+
builder.add_production('Ss' => %w(A A x))
|
310
|
+
builder.add_production('A' => [])
|
311
|
+
tokens = [ Token.new('x', t_x) ]
|
312
|
+
|
313
|
+
instance = EarleyParser.new(builder.grammar)
|
314
|
+
expect { instance.parse(tokens) }.not_to raise_error
|
315
|
+
parse_result = instance.parse(tokens)
|
316
|
+
expect(parse_result.success?).to eq(true)
|
317
|
+
###################### S(0): . x
|
318
|
+
# Expectation chart[0]:
|
319
|
+
expected = [
|
320
|
+
"Ss => . A A 'x' | 0", # Start rule
|
321
|
+
'A => . | 0', # predict from (1)
|
322
|
+
"Ss => A . A 'x' | 0", # modified predict from (1)
|
323
|
+
"Ss => A A . 'x' | 0", # modified predict from (1)
|
324
|
+
]
|
325
|
+
compare_state_texts(parse_result.chart[0], expected)
|
326
|
+
|
327
|
+
###################### S(1): x .
|
328
|
+
# Expectation chart[1]:
|
329
|
+
expected = [
|
330
|
+
"Ss => A A 'x' . | 0", # scan from S(0) 4
|
331
|
+
]
|
332
|
+
compare_state_texts(parse_result.chart[1], expected)
|
333
|
+
end
|
300
334
|
|
301
335
|
it 'should parse an ambiguous grammar' do
|
302
336
|
# Grammar 3: A ambiguous arithmetic expression language
|
@@ -332,22 +366,22 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
332
366
|
###################### S(0): . 2 + 3 * 4
|
333
367
|
# Expectation chart[0]:
|
334
368
|
expected = [
|
335
|
-
|
369
|
+
'P => . S | 0', # Start rule
|
336
370
|
"S => . S '+' S | 0", # predict from (1)
|
337
371
|
"S => . S '*' S | 0", # predict from (1)
|
338
|
-
|
339
|
-
|
372
|
+
'S => . L | 0', # predict from (1)
|
373
|
+
'L => . integer | 0' # predict from (4)
|
340
374
|
]
|
341
375
|
compare_state_texts(parse_result.chart[0], expected)
|
342
376
|
|
343
377
|
###################### S(1): 2 . + 3 * 4
|
344
378
|
# Expectation chart[1]:
|
345
379
|
expected = [
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
"S => S . '+' S | 0", #complete from (2) and S(0) 2
|
350
|
-
"S => S . '*' S | 0", #complete from (2) and S(0) 3
|
380
|
+
'L => integer . | 0', # scan from S(0) 4
|
381
|
+
'S => L . | 0', # complete from (1) and S(0) 4
|
382
|
+
'P => S . | 0', # complete from (2) and S(0) 1
|
383
|
+
"S => S . '+' S | 0", # complete from (2) and S(0) 2
|
384
|
+
"S => S . '*' S | 0", # complete from (2) and S(0) 3
|
351
385
|
]
|
352
386
|
compare_state_texts(parse_result.chart[1], expected)
|
353
387
|
|
@@ -357,25 +391,25 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
357
391
|
"S => S '+' . S | 0", # scan from S(1) 4
|
358
392
|
"S => . S '+' S | 2", # predict from (1)
|
359
393
|
"S => . S '*' S | 2", # predict from (1)
|
360
|
-
|
361
|
-
|
394
|
+
'S => . L | 2', # predict from (1)
|
395
|
+
'L => . integer | 2' # predict from (4)
|
362
396
|
]
|
363
397
|
compare_state_texts(parse_result.chart[2], expected)
|
364
|
-
|
398
|
+
|
365
399
|
###################### S(3): 2 + 3 . * 4
|
366
400
|
# Expectation chart[3]:
|
367
401
|
expected = [
|
368
|
-
|
369
|
-
|
402
|
+
'L => integer . | 2', # scan from S(2) 5
|
403
|
+
'S => L . | 2', # complete from (1) and S(2) 4
|
370
404
|
"S => S '+' S . | 0", # complete from (2) and S(2) 1
|
371
405
|
"S => S . '+' S | 2", # complete from (2) and S(2) 2
|
372
406
|
"S => S . '*' S | 2", # complete from (2) and S(2) 3
|
373
|
-
|
374
|
-
"S => S . '+' S | 0", #complete from (2) and S(0) 2
|
375
|
-
"S => S . '*' S | 0", #complete from (2) and S(0) 3
|
407
|
+
'P => S . | 0', # complete from (2) and S(0) 1
|
408
|
+
"S => S . '+' S | 0", # complete from (2) and S(0) 2
|
409
|
+
"S => S . '*' S | 0", # complete from (2) and S(0) 3
|
376
410
|
]
|
377
411
|
compare_state_texts(parse_result.chart[3], expected)
|
378
|
-
|
412
|
+
|
379
413
|
###################### S(4): 2 + 3 * . 4
|
380
414
|
# Expectation chart[4]:
|
381
415
|
expected = [
|
@@ -383,16 +417,16 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
383
417
|
"S => S '*' . S | 0", # scan from S(3) 8
|
384
418
|
"S => . S '+' S | 4", # predict from (1)
|
385
419
|
"S => . S '*' S | 4", # predict from (1)
|
386
|
-
|
387
|
-
|
420
|
+
'S => . L | 4', # predict from (1)
|
421
|
+
'L => . integer | 4' # predict from (4)
|
388
422
|
]
|
389
423
|
compare_state_texts(parse_result.chart[4], expected)
|
390
|
-
|
424
|
+
|
391
425
|
###################### S(5): 2 + 3 * 4 .
|
392
426
|
# Expectation chart[5]:
|
393
427
|
expected = [
|
394
|
-
|
395
|
-
|
428
|
+
'L => integer . | 4', # scan from S(4) 6
|
429
|
+
'S => L . | 4', # complete from (1) and S(4) 5
|
396
430
|
"S => S '*' S . | 2", # complete from (2) and S(4) 1
|
397
431
|
"S => S '*' S . | 0", # complete from (2) and S(4) 2
|
398
432
|
"S => S . '+' S | 4", # complete from (2) and S(4) 3
|
@@ -400,9 +434,9 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
400
434
|
"S => S '+' S . | 0", # complete from (2) and S(2) 1
|
401
435
|
"S => S . '+' S | 2", # complete from (2) and S(2) 2
|
402
436
|
"S => S . '*' S | 2", # complete from (2) and S(2) 3
|
403
|
-
|
404
|
-
"S => S . '+' S | 0", #
|
405
|
-
"S => S . '*' S | 0" #
|
437
|
+
'P => S . | 0', # complete from (2) and S(0) 1
|
438
|
+
"S => S . '+' S | 0", # complete from (2) and S(0) 2
|
439
|
+
"S => S . '*' S | 0" # complete from (2) and S(0) 3
|
406
440
|
]
|
407
441
|
compare_state_texts(parse_result.chart[5], expected)
|
408
442
|
end
|
@@ -422,7 +456,7 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
422
456
|
###################### S(0) == . a a c c
|
423
457
|
# Expectation chart[0]:
|
424
458
|
expected = [
|
425
|
-
|
459
|
+
'S => . A | 0', # start rule
|
426
460
|
"A => . 'a' A 'c' | 0", # predict from 0
|
427
461
|
"A => . 'b' | 0" # predict from 0
|
428
462
|
]
|
@@ -479,13 +513,6 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
479
513
|
Token.new('/', t_slash),
|
480
514
|
Token.new('a', t_a)
|
481
515
|
]
|
482
|
-
prod_Z = builder.productions[0]
|
483
|
-
prod_E1 = builder.productions[1]
|
484
|
-
prod_E2 = builder.productions[2]
|
485
|
-
prod_F = builder.productions[3]
|
486
|
-
prod_Q1 = builder.productions[4]
|
487
|
-
prod_Q2 = builder.productions[5]
|
488
|
-
prod_Q3 = builder.productions[6]
|
489
516
|
|
490
517
|
instance = EarleyParser.new(builder.grammar)
|
491
518
|
expect { instance.parse(tokens) }.not_to raise_error
|
@@ -495,9 +522,9 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
495
522
|
###################### S(0) == . a a / a
|
496
523
|
# Expectation chart[0]:
|
497
524
|
expected = [
|
498
|
-
|
499
|
-
|
500
|
-
|
525
|
+
'Z => . E | 0', # start rule
|
526
|
+
'E => . E Q F | 0', # predict from (1)
|
527
|
+
'E => . F | 0', # predict from (1)
|
501
528
|
"F => . 'a' | 0" # predict from (3)
|
502
529
|
]
|
503
530
|
compare_state_texts(parse_result.chart[0], expected)
|
@@ -505,15 +532,15 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
505
532
|
###################### S(1) == a . a / a
|
506
533
|
# Expectation chart[1]:
|
507
534
|
expected = [
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
535
|
+
"F => 'a' . | 0", # scan from S(0) 4
|
536
|
+
'E => F . | 0', # complete from (1) and S(0) 3
|
537
|
+
'Z => E . | 0', # complete from (2) and S(0) 1
|
538
|
+
'E => E . Q F | 0', # complete from (2) and S(0) 2
|
539
|
+
"Q => . '*' | 1", # Predict from (4)
|
540
|
+
"Q => . '/' | 1", # Predict from (4)
|
541
|
+
'Q => . | 1', # Predict from (4)
|
542
|
+
'E => E Q . F | 0', # Modified predict from (4)
|
543
|
+
"F => . 'a' | 1" # Predict from (8)
|
517
544
|
]
|
518
545
|
compare_state_texts(parse_result.chart[1], expected)
|
519
546
|
|
@@ -521,13 +548,13 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
521
548
|
# Expectation chart[2]:
|
522
549
|
expected = [
|
523
550
|
"F => 'a' . | 1", # scan from S(1) 9
|
524
|
-
|
525
|
-
|
526
|
-
|
551
|
+
'E => E Q F . | 0', # complete from (1) and S(1) 8
|
552
|
+
'Z => E . | 0', # complete from (1) and S(0) 1
|
553
|
+
'E => E . Q F | 0', # complete from (1) and S(0) 2
|
527
554
|
"Q => . '*' | 2", # Predict from (4)
|
528
555
|
"Q => . '/' | 2", # Predict from (4)
|
529
|
-
|
530
|
-
|
556
|
+
'Q => . | 2', # Predict from (4)
|
557
|
+
'E => E Q . F | 0', # Complete from (5) and S(1) 4
|
531
558
|
"F => . 'a' | 2" # Predict from (8)
|
532
559
|
]
|
533
560
|
compare_state_texts(parse_result.chart[2], expected)
|
@@ -536,9 +563,9 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
536
563
|
###################### S(3) == a a / . a
|
537
564
|
# Expectation chart[3]:
|
538
565
|
expected = [
|
539
|
-
|
540
|
-
|
541
|
-
|
566
|
+
"Q => '/' . | 2", # scan from S(2) 6
|
567
|
+
'E => E Q . F | 0', # complete from (1) and S(1) 4
|
568
|
+
"F => . 'a' | 3" # Predict from (2)
|
542
569
|
]
|
543
570
|
compare_state_texts(parse_result.chart[3], expected)
|
544
571
|
|
@@ -547,13 +574,13 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
547
574
|
# Expectation chart[4]:
|
548
575
|
expected = [
|
549
576
|
"F => 'a' . | 3", # scan from S(3) 3
|
550
|
-
|
551
|
-
|
552
|
-
|
577
|
+
'E => E Q F . | 0', # complete from (1) and S(3) 2
|
578
|
+
'Z => E . | 0', # complete from (2) and S(0) 1
|
579
|
+
'E => E . Q F | 0', # complete from (2) and S(0) 2
|
553
580
|
"Q => . '*' | 4", # Predict from (4)
|
554
581
|
"Q => . '/' | 4", # Predict from (4)
|
555
|
-
|
556
|
-
|
582
|
+
'Q => . | 4', # Predict from (4)
|
583
|
+
'E => E Q . F | 0', # Modified predict from (4)
|
557
584
|
"F => . 'a' | 4" # Predict from (8)
|
558
585
|
]
|
559
586
|
compare_state_texts(parse_result.chart[4], expected)
|