rley 0.7.06 → 0.8.01
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 -6
- data/CHANGELOG.md +20 -4
- data/LICENSE.txt +1 -1
- data/README.md +7 -7
- data/examples/NLP/engtagger.rb +193 -190
- data/examples/NLP/nano_eng/nano_en_demo.rb +7 -11
- data/examples/NLP/nano_eng/nano_grammar.rb +21 -21
- data/examples/NLP/pico_en_demo.rb +2 -2
- data/examples/data_formats/JSON/cli_options.rb +1 -1
- data/examples/data_formats/JSON/json_ast_builder.rb +21 -27
- data/examples/data_formats/JSON/json_ast_nodes.rb +12 -21
- data/examples/data_formats/JSON/json_demo.rb +1 -2
- data/examples/data_formats/JSON/json_grammar.rb +13 -13
- data/examples/data_formats/JSON/json_lexer.rb +8 -8
- data/examples/data_formats/JSON/json_minifier.rb +1 -1
- data/examples/general/calc_iter1/calc_ast_builder.rb +13 -10
- data/examples/general/calc_iter1/calc_ast_nodes.rb +23 -37
- data/examples/general/calc_iter1/calc_grammar.rb +7 -6
- data/examples/general/calc_iter1/calc_lexer.rb +6 -4
- data/examples/general/calc_iter1/spec/calculator_spec.rb +5 -5
- data/examples/general/calc_iter2/calc_ast_builder.rb +5 -3
- data/examples/general/calc_iter2/calc_ast_nodes.rb +27 -43
- data/examples/general/calc_iter2/calc_grammar.rb +12 -12
- data/examples/general/calc_iter2/calc_lexer.rb +11 -10
- data/examples/general/calc_iter2/spec/calculator_spec.rb +26 -26
- data/examples/general/left.rb +2 -2
- data/examples/general/right.rb +2 -2
- data/lib/rley.rb +1 -1
- data/lib/rley/base/dotted_item.rb +28 -31
- data/lib/rley/base/grm_items_builder.rb +6 -0
- data/lib/rley/constants.rb +2 -2
- data/lib/rley/engine.rb +22 -25
- data/lib/rley/formatter/asciitree.rb +3 -3
- data/lib/rley/formatter/bracket_notation.rb +1 -8
- data/lib/rley/formatter/debug.rb +6 -6
- data/lib/rley/formatter/json.rb +2 -2
- data/lib/rley/gfg/call_edge.rb +1 -1
- data/lib/rley/gfg/edge.rb +5 -5
- data/lib/rley/gfg/end_vertex.rb +2 -6
- data/lib/rley/gfg/epsilon_edge.rb +1 -5
- data/lib/rley/gfg/grm_flow_graph.rb +27 -23
- data/lib/rley/gfg/item_vertex.rb +10 -10
- data/lib/rley/gfg/non_terminal_vertex.rb +4 -4
- data/lib/rley/gfg/scan_edge.rb +1 -1
- data/lib/rley/gfg/shortcut_edge.rb +2 -2
- data/lib/rley/gfg/start_vertex.rb +4 -8
- data/lib/rley/gfg/vertex.rb +43 -39
- data/lib/rley/interface.rb +16 -0
- data/lib/rley/lexical/token_range.rb +6 -6
- data/lib/rley/notation/all_notation_nodes.rb +2 -0
- data/lib/rley/notation/ast_builder.rb +191 -0
- data/lib/rley/notation/ast_node.rb +44 -0
- data/lib/rley/notation/ast_visitor.rb +113 -0
- data/lib/rley/notation/grammar.rb +49 -0
- data/lib/rley/notation/grammar_builder.rb +504 -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 +192 -0
- data/lib/rley/parse_forest_visitor.rb +5 -5
- data/lib/rley/parse_rep/ast_base_builder.rb +48 -11
- data/lib/rley/parse_rep/cst_builder.rb +5 -6
- data/lib/rley/parse_rep/parse_forest_builder.rb +22 -18
- data/lib/rley/parse_rep/parse_forest_factory.rb +3 -3
- data/lib/rley/parse_rep/parse_rep_creator.rb +14 -16
- data/lib/rley/parse_rep/parse_tree_builder.rb +4 -4
- data/lib/rley/parse_rep/parse_tree_factory.rb +27 -27
- data/lib/rley/parse_tree_visitor.rb +1 -1
- data/lib/rley/parser/error_reason.rb +4 -5
- data/lib/rley/parser/gfg_chart.rb +118 -26
- data/lib/rley/parser/gfg_parsing.rb +22 -33
- data/lib/rley/parser/parse_entry.rb +25 -31
- data/lib/rley/parser/parse_entry_set.rb +19 -16
- data/lib/rley/parser/parse_entry_tracker.rb +4 -4
- data/lib/rley/parser/parse_tracer.rb +13 -13
- data/lib/rley/parser/parse_walker_factory.rb +23 -28
- data/lib/rley/ptree/non_terminal_node.rb +7 -5
- data/lib/rley/ptree/parse_tree.rb +3 -3
- data/lib/rley/ptree/parse_tree_node.rb +5 -5
- data/lib/rley/ptree/terminal_node.rb +7 -7
- data/lib/rley/rley_error.rb +12 -12
- data/lib/rley/sppf/alternative_node.rb +6 -6
- data/lib/rley/sppf/composite_node.rb +7 -7
- data/lib/rley/sppf/epsilon_node.rb +3 -3
- data/lib/rley/sppf/leaf_node.rb +3 -3
- data/lib/rley/sppf/parse_forest.rb +16 -16
- data/lib/rley/sppf/sppf_node.rb +7 -8
- data/lib/rley/sppf/token_node.rb +3 -3
- data/lib/rley/syntax/{grammar_builder.rb → base_grammar_builder.rb} +61 -23
- data/lib/rley/syntax/grammar.rb +5 -5
- data/lib/rley/syntax/grm_symbol.rb +7 -7
- data/lib/rley/syntax/match_closest.rb +43 -0
- data/lib/rley/syntax/non_terminal.rb +9 -15
- data/lib/rley/syntax/production.rb +16 -10
- data/lib/rley/syntax/symbol_seq.rb +7 -9
- data/lib/rley/syntax/terminal.rb +4 -5
- data/lib/rley/syntax/verbatim_symbol.rb +3 -3
- data/lib/support/base_tokenizer.rb +19 -18
- data/spec/rley/base/dotted_item_spec.rb +2 -2
- data/spec/rley/engine_spec.rb +23 -21
- data/spec/rley/formatter/asciitree_spec.rb +7 -7
- data/spec/rley/formatter/bracket_notation_spec.rb +13 -13
- data/spec/rley/formatter/json_spec.rb +1 -1
- data/spec/rley/gfg/end_vertex_spec.rb +5 -5
- data/spec/rley/gfg/grm_flow_graph_spec.rb +2 -2
- data/spec/rley/gfg/item_vertex_spec.rb +10 -10
- data/spec/rley/gfg/non_terminal_vertex_spec.rb +3 -3
- data/spec/rley/gfg/shortcut_edge_spec.rb +1 -1
- data/spec/rley/gfg/start_vertex_spec.rb +5 -5
- data/spec/rley/gfg/vertex_spec.rb +3 -3
- data/spec/rley/lexical/token_range_spec.rb +16 -16
- data/spec/rley/lexical/token_spec.rb +2 -2
- data/spec/rley/notation/grammar_builder_spec.rb +302 -0
- data/spec/rley/notation/parser_spec.rb +184 -0
- data/spec/rley/notation/tokenizer_spec.rb +370 -0
- data/spec/rley/parse_forest_visitor_spec.rb +165 -163
- data/spec/rley/parse_rep/ambiguous_parse_spec.rb +44 -44
- data/spec/rley/parse_rep/ast_builder_spec.rb +6 -7
- data/spec/rley/parse_rep/cst_builder_spec.rb +5 -5
- data/spec/rley/parse_rep/groucho_spec.rb +24 -26
- data/spec/rley/parse_rep/parse_forest_builder_spec.rb +27 -27
- data/spec/rley/parse_rep/parse_forest_factory_spec.rb +8 -8
- data/spec/rley/parse_rep/parse_tree_factory_spec.rb +3 -3
- data/spec/rley/parse_tree_visitor_spec.rb +10 -8
- data/spec/rley/parser/dangling_else_spec.rb +445 -0
- data/spec/rley/parser/error_reason_spec.rb +6 -6
- data/spec/rley/parser/gfg_earley_parser_spec.rb +120 -12
- data/spec/rley/parser/gfg_parsing_spec.rb +6 -13
- data/spec/rley/parser/parse_entry_spec.rb +19 -19
- data/spec/rley/parser/parse_walker_factory_spec.rb +10 -10
- data/spec/rley/ptree/non_terminal_node_spec.rb +5 -3
- data/spec/rley/ptree/parse_tree_node_spec.rb +4 -4
- data/spec/rley/ptree/terminal_node_spec.rb +6 -6
- data/spec/rley/sppf/alternative_node_spec.rb +6 -6
- data/spec/rley/sppf/non_terminal_node_spec.rb +3 -3
- data/spec/rley/sppf/token_node_spec.rb +4 -4
- data/spec/rley/support/ambiguous_grammar_helper.rb +4 -5
- data/spec/rley/support/grammar_abc_helper.rb +3 -5
- data/spec/rley/support/grammar_ambig01_helper.rb +5 -6
- data/spec/rley/support/grammar_arr_int_helper.rb +5 -6
- data/spec/rley/support/grammar_b_expr_helper.rb +5 -6
- data/spec/rley/support/grammar_int_seq_helper.rb +51 -0
- data/spec/rley/support/grammar_l0_helper.rb +14 -17
- data/spec/rley/support/grammar_pb_helper.rb +8 -7
- data/spec/rley/support/grammar_sppf_helper.rb +3 -3
- data/spec/rley/syntax/{grammar_builder_spec.rb → base_grammar_builder_spec.rb} +35 -16
- data/spec/rley/syntax/grammar_spec.rb +6 -6
- data/spec/rley/syntax/grm_symbol_spec.rb +1 -1
- data/spec/rley/syntax/match_closest_spec.rb +46 -0
- data/spec/rley/syntax/non_terminal_spec.rb +8 -8
- data/spec/rley/syntax/production_spec.rb +17 -13
- data/spec/rley/syntax/symbol_seq_spec.rb +2 -2
- data/spec/rley/syntax/terminal_spec.rb +5 -5
- data/spec/rley/syntax/verbatim_symbol_spec.rb +1 -1
- data/spec/spec_helper.rb +0 -12
- data/spec/support/base_tokenizer_spec.rb +7 -2
- metadata +48 -74
- data/.simplecov +0 -7
- data/lib/rley/parser/parse_state.rb +0 -83
- data/lib/rley/parser/parse_state_tracker.rb +0 -59
- data/lib/rley/parser/state_set.rb +0 -101
- 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
@@ -46,8 +46,8 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
46
46
|
|
47
47
|
context 'Initialization:' do
|
48
48
|
it 'should be created with arguments' do
|
49
|
-
expect do
|
50
|
-
ExpectationNotMet.new(3, err_token, terminals)
|
49
|
+
expect do
|
50
|
+
ExpectationNotMet.new(3, err_token, terminals)
|
51
51
|
end.not_to raise_error
|
52
52
|
end
|
53
53
|
|
@@ -75,8 +75,8 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
75
75
|
|
76
76
|
context 'Initialization:' do
|
77
77
|
it 'should be created with arguments' do
|
78
|
-
expect do
|
79
|
-
UnexpectedToken.new(3, err_token, terminals)
|
78
|
+
expect do
|
79
|
+
UnexpectedToken.new(3, err_token, terminals)
|
80
80
|
end.not_to raise_error
|
81
81
|
end
|
82
82
|
end # context
|
@@ -107,8 +107,8 @@ MESSAGE_END
|
|
107
107
|
|
108
108
|
context 'Initialization:' do
|
109
109
|
it 'should be created with arguments' do
|
110
|
-
expect do
|
111
|
-
PrematureInputEnd.new(3, err_token, terminals)
|
110
|
+
expect do
|
111
|
+
PrematureInputEnd.new(3, err_token, terminals)
|
112
112
|
end.not_to raise_error
|
113
113
|
end
|
114
114
|
end # context
|
@@ -5,7 +5,7 @@ require 'stringio'
|
|
5
5
|
require_relative '../../../lib/rley/syntax/verbatim_symbol'
|
6
6
|
require_relative '../../../lib/rley/syntax/non_terminal'
|
7
7
|
require_relative '../../../lib/rley/syntax/production'
|
8
|
-
require_relative '../../../lib/rley/syntax/
|
8
|
+
require_relative '../../../lib/rley/syntax/base_grammar_builder'
|
9
9
|
require_relative '../../../lib/rley/lexical/token'
|
10
10
|
require_relative '../../../lib/rley/base/dotted_item'
|
11
11
|
require_relative '../../../lib/rley/parser/gfg_parsing'
|
@@ -13,6 +13,7 @@ require_relative '../../../lib/rley/parser/gfg_parsing'
|
|
13
13
|
# Load builders and lexers for sample grammars
|
14
14
|
require_relative '../support/grammar_abc_helper'
|
15
15
|
require_relative '../support/ambiguous_grammar_helper'
|
16
|
+
require_relative '../support/grammar_int_seq_helper'
|
16
17
|
require_relative '../support/grammar_pb_helper'
|
17
18
|
require_relative '../support/grammar_helper'
|
18
19
|
require_relative '../support/expectation_helper'
|
@@ -71,7 +72,7 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
71
72
|
|
72
73
|
# Helper method that mimicks the output of a tokenizer
|
73
74
|
# for the language specified by grammar_expr
|
74
|
-
def grm2_tokens
|
75
|
+
def grm2_tokens
|
75
76
|
input_sequence = [
|
76
77
|
{ '2' => 'integer' },
|
77
78
|
'+',
|
@@ -79,7 +80,7 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
79
80
|
'*',
|
80
81
|
{ '4' => 'integer' }
|
81
82
|
]
|
82
|
-
|
83
|
+
build_token_sequence(input_sequence, grammar_expr)
|
83
84
|
end
|
84
85
|
|
85
86
|
# Default instantiation rule
|
@@ -104,6 +105,7 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
104
105
|
end # context
|
105
106
|
|
106
107
|
context 'Parsing: ' do
|
108
|
+
# rubocop: disable Naming/VariableNumber
|
107
109
|
it 'should parse a valid simple input' do
|
108
110
|
parse_result = subject.parse(grm1_tokens)
|
109
111
|
expect(parse_result.success?).to eq(true)
|
@@ -183,6 +185,7 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
183
185
|
expect(entry_set_5.entries.size).to eq(4)
|
184
186
|
compare_entry_texts(entry_set_5, expected)
|
185
187
|
end
|
188
|
+
# rubocop: enable Naming/VariableNumber
|
186
189
|
|
187
190
|
it 'should parse a valid simple expression' do
|
188
191
|
instance = GFGEarleyParser.new(grammar_expr)
|
@@ -279,6 +282,91 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
279
282
|
compare_entry_texts(parse_result.chart[5], expected)
|
280
283
|
end
|
281
284
|
|
285
|
+
it 'should support Kleene plus ' do
|
286
|
+
extend(GrammarIntSeqHelper)
|
287
|
+
grammar = grammar_int_seq_builder.grammar
|
288
|
+
instance = GFGEarleyParser.new(grammar)
|
289
|
+
tokens = int_seq_tokenizer('6, 36, 216')
|
290
|
+
parse_result = nil
|
291
|
+
expect { parse_result = instance.parse(tokens) }.not_to raise_error
|
292
|
+
expect(parse_result.success?).to eq(true)
|
293
|
+
|
294
|
+
###################### S(0): . 6, 36, 216
|
295
|
+
# Expectation chart[0]:
|
296
|
+
expected = [
|
297
|
+
'.S | 0', # Initialization
|
298
|
+
'S => . sequence | 0', # start rule
|
299
|
+
'S => . | 0', # start rule
|
300
|
+
'.sequence | 0', # call rule
|
301
|
+
'S. | 0', # exit rule
|
302
|
+
'sequence => . sequence comma integer | 0', # start rule
|
303
|
+
'sequence => . integer | 0', # start rule
|
304
|
+
'.integer | 0', # call rule
|
305
|
+
'integer => . digit_plus | 0' , # start rule
|
306
|
+
'.digit_plus | 0', # call rule
|
307
|
+
'digit_plus => . digit_plus digit | 0', # start rule (generated)
|
308
|
+
'digit_plus => . digit | 0' # start rule (generated)
|
309
|
+
]
|
310
|
+
compare_entry_texts(parse_result.chart[0], expected)
|
311
|
+
|
312
|
+
###################### S(1): 6 ., 36, 216
|
313
|
+
# Expectation chart[1]:
|
314
|
+
expected = [
|
315
|
+
'digit_plus => digit . | 0', # Scan
|
316
|
+
'digit_plus. | 0', # exit rule
|
317
|
+
'integer => digit_plus . | 0' , # end rule
|
318
|
+
'digit_plus => digit_plus . digit | 0', # rule (generated)
|
319
|
+
'integer. | 0', # exit rule
|
320
|
+
'sequence => integer . | 0', # end rule
|
321
|
+
'sequence. | 0', # exit rule
|
322
|
+
'S => sequence . | 0', # end rule
|
323
|
+
'sequence => sequence . comma integer | 0', # rule
|
324
|
+
'S. | 0' # exit rule
|
325
|
+
]
|
326
|
+
compare_entry_texts(parse_result.chart[1], expected)
|
327
|
+
|
328
|
+
###################### S(2): 6 , . 36, 216
|
329
|
+
# Expectation chart[2]:
|
330
|
+
expected = [
|
331
|
+
'sequence => sequence comma . integer | 0', # Scan
|
332
|
+
'.integer | 2', # call rule
|
333
|
+
'integer => . digit_plus | 2' , # start rule
|
334
|
+
'.digit_plus | 2', # call rule
|
335
|
+
'digit_plus => . digit_plus digit | 2', # start rule (generated)
|
336
|
+
'digit_plus => . digit | 2' # start rule (generated)
|
337
|
+
]
|
338
|
+
compare_entry_texts(parse_result.chart[2], expected)
|
339
|
+
|
340
|
+
###################### S(3): 6 , 3 . 6. , 216
|
341
|
+
# Expectation chart[3]:
|
342
|
+
expected = [
|
343
|
+
'digit_plus => digit . | 2', # Scan
|
344
|
+
'digit_plus. | 2', # exit rule
|
345
|
+
'integer => digit_plus . | 2' , # end rule
|
346
|
+
'digit_plus => digit_plus . digit | 2', # rule (generated)
|
347
|
+
'integer. | 2', # exit rule
|
348
|
+
'sequence => sequence comma integer . | 0', # rule
|
349
|
+
'sequence. | 0', # exit rule
|
350
|
+
'S => sequence . | 0', # end rule
|
351
|
+
'sequence => sequence . comma integer | 0', # rule
|
352
|
+
]
|
353
|
+
compare_entry_texts(parse_result.chart[3], expected)
|
354
|
+
|
355
|
+
###################### S(4): 6 , 36 . . , 216
|
356
|
+
# Expectation chart[4]:
|
357
|
+
expected = [
|
358
|
+
'digit_plus => digit_plus digit . | 2', # Scan
|
359
|
+
'digit_plus. | 2', # exit rule
|
360
|
+
'integer => digit_plus . | 2' , # end rule
|
361
|
+
'digit_plus => digit_plus . digit | 2', #
|
362
|
+
'integer. | 2', # exit rule
|
363
|
+
'sequence => sequence comma integer . | 0', # rule
|
364
|
+
'sequence. | 0', # exit rule
|
365
|
+
'S => sequence . | 0', # end rule
|
366
|
+
]
|
367
|
+
compare_entry_texts(parse_result.chart[4], expected)
|
368
|
+
end
|
369
|
+
|
282
370
|
it 'should parse a nullable grammar' do
|
283
371
|
# Simple but problematic grammar for the original Earley parser
|
284
372
|
# (based on example in D. Grune, C. Jacobs "Parsing Techniques" book)
|
@@ -286,7 +374,7 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
286
374
|
# A => ;
|
287
375
|
t_x = Syntax::VerbatimSymbol.new('x')
|
288
376
|
|
289
|
-
builder =
|
377
|
+
builder = Notation::GrammarBuilder.new do
|
290
378
|
add_terminals(t_x)
|
291
379
|
rule 'Ss' => 'A A x'
|
292
380
|
rule 'A' => []
|
@@ -332,11 +420,11 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
332
420
|
t_plus = Syntax::VerbatimSymbol.new('+')
|
333
421
|
t_star = Syntax::VerbatimSymbol.new('*')
|
334
422
|
|
335
|
-
builder = Syntax::
|
423
|
+
builder = Syntax::BaseGrammarBuilder.new do
|
336
424
|
add_terminals(t_int, t_plus, t_star)
|
337
425
|
rule 'P' => 'S'
|
338
|
-
rule 'S' =>
|
339
|
-
rule 'S' =>
|
426
|
+
rule 'S' => 'S + S'
|
427
|
+
rule 'S' => 'S * S'
|
340
428
|
rule 'S' => 'L'
|
341
429
|
rule 'L' => 'integer'
|
342
430
|
end
|
@@ -731,7 +819,7 @@ MSG
|
|
731
819
|
t_star = Syntax::VerbatimSymbol.new('*')
|
732
820
|
t_slash = Syntax::VerbatimSymbol.new('/')
|
733
821
|
|
734
|
-
builder = Syntax::
|
822
|
+
builder = Syntax::BaseGrammarBuilder.new do
|
735
823
|
add_terminals(t_a, t_star, t_slash)
|
736
824
|
rule 'Z' => 'E'
|
737
825
|
rule 'E' => %w[E Q F]
|
@@ -846,10 +934,11 @@ MSG
|
|
846
934
|
# S => ;
|
847
935
|
# This grammar requires a time that is quadratic in the number of
|
848
936
|
# input tokens
|
849
|
-
builder =
|
850
|
-
|
851
|
-
|
852
|
-
|
937
|
+
builder = Notation::GrammarBuilder.new do
|
938
|
+
add_terminals('a')
|
939
|
+
rule('S' => 'a S')
|
940
|
+
rule('S' => '')
|
941
|
+
end
|
853
942
|
grammar = builder.grammar
|
854
943
|
tokens = build_token_sequence(%w[a a a a], grammar)
|
855
944
|
|
@@ -929,6 +1018,25 @@ MSG
|
|
929
1018
|
]
|
930
1019
|
compare_entry_texts(parse_result.chart[4], expected)
|
931
1020
|
end
|
1021
|
+
|
1022
|
+
it 'should support modifier(s) in start rule' do
|
1023
|
+
# An implicit EOF marker is a special terminal
|
1024
|
+
# that denotes the end of input string but doesn't
|
1025
|
+
# appear explicitly as some character or text in the input.
|
1026
|
+
builder = Notation::GrammarBuilder.new do
|
1027
|
+
add_terminals('a', 'b', 'EOF')
|
1028
|
+
|
1029
|
+
rule('S' => 'a_or_b* EOF')
|
1030
|
+
rule('a_or_b' => 'a')
|
1031
|
+
rule('a_or_b' => 'b')
|
1032
|
+
end
|
1033
|
+
grammar = builder.grammar
|
1034
|
+
tokens = build_token_sequence(%w[EOF], grammar)
|
1035
|
+
tokens[0].instance_variable_set(:@lexeme, '')
|
1036
|
+
instance = GFGEarleyParser.new(grammar)
|
1037
|
+
parse_result = instance.parse(tokens)
|
1038
|
+
expect(parse_result.success?).to eq(true)
|
1039
|
+
end
|
932
1040
|
end # context
|
933
1041
|
end # describe
|
934
1042
|
end # module
|
@@ -6,7 +6,7 @@ require 'stringio'
|
|
6
6
|
require_relative '../../../lib/rley/syntax/non_terminal'
|
7
7
|
require_relative '../../../lib/rley/syntax/verbatim_symbol'
|
8
8
|
require_relative '../../../lib/rley/syntax/production'
|
9
|
-
require_relative '../../../lib/rley/syntax/
|
9
|
+
require_relative '../../../lib/rley/syntax/base_grammar_builder'
|
10
10
|
require_relative '../../../lib/rley/base/dotted_item'
|
11
11
|
require_relative '../../../lib/rley/lexical/token'
|
12
12
|
require_relative '../../../lib/rley/parser/parse_tracer'
|
@@ -95,14 +95,14 @@ SNIPPET
|
|
95
95
|
|
96
96
|
context 'Parsing:' do
|
97
97
|
# Utility method to fill the first entry set...
|
98
|
-
def fill_first_set
|
98
|
+
def fill_first_set
|
99
99
|
subject.start_rule(subject.initial_entry, 0)
|
100
100
|
subject.call_rule(subject.chart[0].last, 0)
|
101
101
|
subject.start_rule(subject.chart[0].last, 0)
|
102
102
|
end
|
103
103
|
|
104
104
|
# Utility method to initialize the second entry set...
|
105
|
-
def seed_second_set
|
105
|
+
def seed_second_set
|
106
106
|
# Cheating: we change the tokens to scan...
|
107
107
|
# Seeding second entry set...
|
108
108
|
subject.scan_rule(0, grm1_token_b[0])
|
@@ -252,9 +252,6 @@ SNIPPET
|
|
252
252
|
end
|
253
253
|
|
254
254
|
=begin
|
255
|
-
|
256
|
-
|
257
|
-
|
258
255
|
it 'should retrieve the parse states that expect a given terminal' do
|
259
256
|
item1 = DottedItem.new(prod_A1, 2)
|
260
257
|
item2 = DottedItem.new(prod_A1, 1)
|
@@ -303,9 +300,9 @@ SNIPPET
|
|
303
300
|
|
304
301
|
it 'should give a text representation of itself' do
|
305
302
|
repr = subject.to_s
|
306
|
-
expect(repr).to match
|
307
|
-
|
308
|
-
# Let's test the last chart state only
|
303
|
+
expect(repr).to match(/^success\? true/)
|
304
|
+
|
305
|
+
# Let's test the last chart state only
|
309
306
|
expectation = <<REPR
|
310
307
|
State[5]
|
311
308
|
T => integer . | 4
|
@@ -341,10 +338,6 @@ REPR
|
|
341
338
|
it 'should indicate whether a parse succeeded' do
|
342
339
|
expect(subject.success?).to be_truthy
|
343
340
|
end
|
344
|
-
|
345
|
-
it 'should build a parse forest' do
|
346
|
-
expect { subject.parse_forest }.not_to raise_error if subject.success?
|
347
|
-
end
|
348
341
|
end # context
|
349
342
|
end # describe
|
350
343
|
end # module
|
@@ -52,7 +52,7 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
52
52
|
it 'should know the origin value' do
|
53
53
|
expect(subject.origin).to eq(origin_val)
|
54
54
|
end
|
55
|
-
|
55
|
+
|
56
56
|
it 'should have not antecedent at creation' do
|
57
57
|
expect(subject.antecedents).to be_empty
|
58
58
|
expect(subject).to be_orphan
|
@@ -91,13 +91,13 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
91
91
|
instance = ParseEntry.new(GFG::EndVertex.new('NT.'), 3)
|
92
92
|
expect(instance).to be_end_entry
|
93
93
|
end
|
94
|
-
|
94
|
+
|
95
95
|
it 'should know if the entry is a dotted item vertex' do
|
96
96
|
expect(subject).not_to be_dotted_entry
|
97
97
|
|
98
98
|
instance = ParseEntry.new(GFG::ItemVertex.new('P => S.'), 3)
|
99
99
|
expect(instance).to be_dotted_entry
|
100
|
-
end
|
100
|
+
end
|
101
101
|
|
102
102
|
it 'should know if the vertex is at end of production (if any)' do
|
103
103
|
# Case: start vertex
|
@@ -120,7 +120,7 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
120
120
|
instance4 = ParseEntry.new(v2, 3)
|
121
121
|
expect(instance4).to be_exit_entry
|
122
122
|
end
|
123
|
-
|
123
|
+
|
124
124
|
it 'should know if the vertex is at begin of production (if any)' do
|
125
125
|
# Case: start vertex
|
126
126
|
instance1 = ParseEntry.new(GFG::StartVertex.new('.NT'), 3)
|
@@ -131,17 +131,17 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
131
131
|
expect(instance2).not_to be_entry_entry
|
132
132
|
|
133
133
|
# Case: item vertex not at begin of rhs
|
134
|
-
d1 = Base::DottedItem.new(sample_prod, 1)
|
134
|
+
d1 = Base::DottedItem.new(sample_prod, 1)
|
135
135
|
v1 = GFG::ItemVertex.new(d1)
|
136
136
|
instance3 = ParseEntry.new(v1, 3)
|
137
137
|
expect(instance3).not_to be_entry_entry
|
138
138
|
|
139
139
|
# Case: item vertex at end of rhs
|
140
|
-
d2 = Base::DottedItem.new(sample_prod, 0)
|
141
|
-
v2 = GFG::ItemVertex.new(d2)
|
140
|
+
d2 = Base::DottedItem.new(sample_prod, 0)
|
141
|
+
v2 = GFG::ItemVertex.new(d2)
|
142
142
|
instance4 = ParseEntry.new(v2, 3)
|
143
143
|
expect(instance4).to be_entry_entry
|
144
|
-
end
|
144
|
+
end
|
145
145
|
|
146
146
|
it 'should know the symbol before the dot (if any)' do
|
147
147
|
# Case: start vertex
|
@@ -151,20 +151,20 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
151
151
|
# Case: end vertex
|
152
152
|
instance2 = ParseEntry.new(GFG::EndVertex.new('NT.'), 3)
|
153
153
|
expect(instance2.prev_symbol).to be_nil # Really correct?
|
154
|
-
|
154
|
+
|
155
155
|
# Case: item vertex not at start of rhs
|
156
156
|
v1 = double('vertex-not-at-start')
|
157
157
|
expect(v1).to receive(:prev_symbol).and_return('symbol')
|
158
158
|
instance3 = ParseEntry.new(v1, 3)
|
159
|
-
expect(instance3.prev_symbol).to eq('symbol')
|
159
|
+
expect(instance3.prev_symbol).to eq('symbol')
|
160
160
|
|
161
161
|
# Case: item vertex at start of rhs
|
162
162
|
v2 = double('vertex-at-start')
|
163
163
|
expect(v2).to receive(:prev_symbol).and_return(nil)
|
164
164
|
instance4 = ParseEntry.new(v2, 0)
|
165
|
-
expect(instance4.prev_symbol).to be_nil
|
165
|
+
expect(instance4.prev_symbol).to be_nil
|
166
166
|
end
|
167
|
-
|
167
|
+
|
168
168
|
it 'should know the next expected symbol (if any)' do
|
169
169
|
# Case: start vertex
|
170
170
|
instance1 = ParseEntry.new(GFG::StartVertex.new('.NT'), 3)
|
@@ -173,19 +173,19 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
173
173
|
# Case: end vertex
|
174
174
|
instance2 = ParseEntry.new(GFG::EndVertex.new('NT.'), 3)
|
175
175
|
expect(instance2.next_symbol).to be_nil
|
176
|
-
|
176
|
+
|
177
177
|
# Case: item vertex not at end of rhs
|
178
178
|
v1 = double('vertex-not-at-end')
|
179
179
|
expect(v1).to receive(:next_symbol).and_return('symbol')
|
180
180
|
instance3 = ParseEntry.new(v1, 3)
|
181
|
-
expect(instance3.next_symbol).to eq('symbol')
|
181
|
+
expect(instance3.next_symbol).to eq('symbol')
|
182
182
|
|
183
183
|
# Case: item vertex at end of rhs
|
184
184
|
v2 = double('vertex-at-end')
|
185
185
|
expect(v2).to receive(:next_symbol).and_return(nil)
|
186
186
|
instance4 = ParseEntry.new(v2, 3)
|
187
|
-
expect(instance4.next_symbol).to be_nil
|
188
|
-
end
|
187
|
+
expect(instance4.next_symbol).to be_nil
|
188
|
+
end
|
189
189
|
|
190
190
|
it 'should accept antecedents' do
|
191
191
|
antecedent = ParseEntry.new(vertex2, origin_val)
|
@@ -198,7 +198,7 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
198
198
|
expected = '.sentence | 3'
|
199
199
|
expect(subject.to_s).to eq(expected)
|
200
200
|
end
|
201
|
-
|
201
|
+
|
202
202
|
it 'should be inspectable' do
|
203
203
|
subject.add_antecedent(subject) # Cheat for the good cause...
|
204
204
|
# expected = '.sentence | 3'
|
@@ -209,8 +209,8 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
209
209
|
pattern2 = /@origin=3 @antecedents=\[/
|
210
210
|
expect(subject.inspect).to match(pattern2)
|
211
211
|
suffix = /<Rley::GFG::StartVertex:\d+ label=\.sentence> @origin=3\]>$/
|
212
|
-
expect(subject.inspect).to match(suffix)
|
213
|
-
end
|
212
|
+
expect(subject.inspect).to match(suffix)
|
213
|
+
end
|
214
214
|
end # context
|
215
215
|
end # describe
|
216
216
|
end # module
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
require_relative '../../spec_helper'
|
4
4
|
|
5
|
-
require_relative '../../../lib/rley/syntax/
|
5
|
+
require_relative '../../../lib/rley/syntax/base_grammar_builder'
|
6
6
|
require_relative '../support/grammar_helper'
|
7
7
|
require_relative '../support/expectation_helper'
|
8
8
|
|
@@ -45,15 +45,15 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
45
45
|
# "SPPF=Style Parsing From Earley Recognizers" in
|
46
46
|
# Notes in Theoretical Computer Science 203, (2008), pp. 53-67
|
47
47
|
# contains a hidden left recursion and a cycle
|
48
|
-
builder = Syntax::
|
48
|
+
builder = Syntax::BaseGrammarBuilder.new do
|
49
49
|
add_terminals('a', '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]
|
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]
|
57
57
|
end
|
58
58
|
builder.grammar
|
59
59
|
end
|
@@ -303,7 +303,7 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
303
303
|
event18 = walker.next
|
304
304
|
expectations = [:revisit, 'T. | 1', 4]
|
305
305
|
event_expectations(event18, expectations)
|
306
|
-
|
306
|
+
|
307
307
|
# Lazy walk: make start entry .T the current one
|
308
308
|
# Multiple visit occurred: jump to antecedent of start entry
|
309
309
|
event19 = walker.next
|