rley 0.7.06 → 0.8.01
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +362 -62
- data/.travis.yml +6 -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
|