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.
Files changed (167) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +362 -62
  3. data/.travis.yml +6 -6
  4. data/CHANGELOG.md +20 -4
  5. data/LICENSE.txt +1 -1
  6. data/README.md +7 -7
  7. data/examples/NLP/engtagger.rb +193 -190
  8. data/examples/NLP/nano_eng/nano_en_demo.rb +7 -11
  9. data/examples/NLP/nano_eng/nano_grammar.rb +21 -21
  10. data/examples/NLP/pico_en_demo.rb +2 -2
  11. data/examples/data_formats/JSON/cli_options.rb +1 -1
  12. data/examples/data_formats/JSON/json_ast_builder.rb +21 -27
  13. data/examples/data_formats/JSON/json_ast_nodes.rb +12 -21
  14. data/examples/data_formats/JSON/json_demo.rb +1 -2
  15. data/examples/data_formats/JSON/json_grammar.rb +13 -13
  16. data/examples/data_formats/JSON/json_lexer.rb +8 -8
  17. data/examples/data_formats/JSON/json_minifier.rb +1 -1
  18. data/examples/general/calc_iter1/calc_ast_builder.rb +13 -10
  19. data/examples/general/calc_iter1/calc_ast_nodes.rb +23 -37
  20. data/examples/general/calc_iter1/calc_grammar.rb +7 -6
  21. data/examples/general/calc_iter1/calc_lexer.rb +6 -4
  22. data/examples/general/calc_iter1/spec/calculator_spec.rb +5 -5
  23. data/examples/general/calc_iter2/calc_ast_builder.rb +5 -3
  24. data/examples/general/calc_iter2/calc_ast_nodes.rb +27 -43
  25. data/examples/general/calc_iter2/calc_grammar.rb +12 -12
  26. data/examples/general/calc_iter2/calc_lexer.rb +11 -10
  27. data/examples/general/calc_iter2/spec/calculator_spec.rb +26 -26
  28. data/examples/general/left.rb +2 -2
  29. data/examples/general/right.rb +2 -2
  30. data/lib/rley.rb +1 -1
  31. data/lib/rley/base/dotted_item.rb +28 -31
  32. data/lib/rley/base/grm_items_builder.rb +6 -0
  33. data/lib/rley/constants.rb +2 -2
  34. data/lib/rley/engine.rb +22 -25
  35. data/lib/rley/formatter/asciitree.rb +3 -3
  36. data/lib/rley/formatter/bracket_notation.rb +1 -8
  37. data/lib/rley/formatter/debug.rb +6 -6
  38. data/lib/rley/formatter/json.rb +2 -2
  39. data/lib/rley/gfg/call_edge.rb +1 -1
  40. data/lib/rley/gfg/edge.rb +5 -5
  41. data/lib/rley/gfg/end_vertex.rb +2 -6
  42. data/lib/rley/gfg/epsilon_edge.rb +1 -5
  43. data/lib/rley/gfg/grm_flow_graph.rb +27 -23
  44. data/lib/rley/gfg/item_vertex.rb +10 -10
  45. data/lib/rley/gfg/non_terminal_vertex.rb +4 -4
  46. data/lib/rley/gfg/scan_edge.rb +1 -1
  47. data/lib/rley/gfg/shortcut_edge.rb +2 -2
  48. data/lib/rley/gfg/start_vertex.rb +4 -8
  49. data/lib/rley/gfg/vertex.rb +43 -39
  50. data/lib/rley/interface.rb +16 -0
  51. data/lib/rley/lexical/token_range.rb +6 -6
  52. data/lib/rley/notation/all_notation_nodes.rb +2 -0
  53. data/lib/rley/notation/ast_builder.rb +191 -0
  54. data/lib/rley/notation/ast_node.rb +44 -0
  55. data/lib/rley/notation/ast_visitor.rb +113 -0
  56. data/lib/rley/notation/grammar.rb +49 -0
  57. data/lib/rley/notation/grammar_builder.rb +504 -0
  58. data/lib/rley/notation/grouping_node.rb +23 -0
  59. data/lib/rley/notation/parser.rb +56 -0
  60. data/lib/rley/notation/sequence_node.rb +35 -0
  61. data/lib/rley/notation/symbol_node.rb +29 -0
  62. data/lib/rley/notation/tokenizer.rb +192 -0
  63. data/lib/rley/parse_forest_visitor.rb +5 -5
  64. data/lib/rley/parse_rep/ast_base_builder.rb +48 -11
  65. data/lib/rley/parse_rep/cst_builder.rb +5 -6
  66. data/lib/rley/parse_rep/parse_forest_builder.rb +22 -18
  67. data/lib/rley/parse_rep/parse_forest_factory.rb +3 -3
  68. data/lib/rley/parse_rep/parse_rep_creator.rb +14 -16
  69. data/lib/rley/parse_rep/parse_tree_builder.rb +4 -4
  70. data/lib/rley/parse_rep/parse_tree_factory.rb +27 -27
  71. data/lib/rley/parse_tree_visitor.rb +1 -1
  72. data/lib/rley/parser/error_reason.rb +4 -5
  73. data/lib/rley/parser/gfg_chart.rb +118 -26
  74. data/lib/rley/parser/gfg_parsing.rb +22 -33
  75. data/lib/rley/parser/parse_entry.rb +25 -31
  76. data/lib/rley/parser/parse_entry_set.rb +19 -16
  77. data/lib/rley/parser/parse_entry_tracker.rb +4 -4
  78. data/lib/rley/parser/parse_tracer.rb +13 -13
  79. data/lib/rley/parser/parse_walker_factory.rb +23 -28
  80. data/lib/rley/ptree/non_terminal_node.rb +7 -5
  81. data/lib/rley/ptree/parse_tree.rb +3 -3
  82. data/lib/rley/ptree/parse_tree_node.rb +5 -5
  83. data/lib/rley/ptree/terminal_node.rb +7 -7
  84. data/lib/rley/rley_error.rb +12 -12
  85. data/lib/rley/sppf/alternative_node.rb +6 -6
  86. data/lib/rley/sppf/composite_node.rb +7 -7
  87. data/lib/rley/sppf/epsilon_node.rb +3 -3
  88. data/lib/rley/sppf/leaf_node.rb +3 -3
  89. data/lib/rley/sppf/parse_forest.rb +16 -16
  90. data/lib/rley/sppf/sppf_node.rb +7 -8
  91. data/lib/rley/sppf/token_node.rb +3 -3
  92. data/lib/rley/syntax/{grammar_builder.rb → base_grammar_builder.rb} +61 -23
  93. data/lib/rley/syntax/grammar.rb +5 -5
  94. data/lib/rley/syntax/grm_symbol.rb +7 -7
  95. data/lib/rley/syntax/match_closest.rb +43 -0
  96. data/lib/rley/syntax/non_terminal.rb +9 -15
  97. data/lib/rley/syntax/production.rb +16 -10
  98. data/lib/rley/syntax/symbol_seq.rb +7 -9
  99. data/lib/rley/syntax/terminal.rb +4 -5
  100. data/lib/rley/syntax/verbatim_symbol.rb +3 -3
  101. data/lib/support/base_tokenizer.rb +19 -18
  102. data/spec/rley/base/dotted_item_spec.rb +2 -2
  103. data/spec/rley/engine_spec.rb +23 -21
  104. data/spec/rley/formatter/asciitree_spec.rb +7 -7
  105. data/spec/rley/formatter/bracket_notation_spec.rb +13 -13
  106. data/spec/rley/formatter/json_spec.rb +1 -1
  107. data/spec/rley/gfg/end_vertex_spec.rb +5 -5
  108. data/spec/rley/gfg/grm_flow_graph_spec.rb +2 -2
  109. data/spec/rley/gfg/item_vertex_spec.rb +10 -10
  110. data/spec/rley/gfg/non_terminal_vertex_spec.rb +3 -3
  111. data/spec/rley/gfg/shortcut_edge_spec.rb +1 -1
  112. data/spec/rley/gfg/start_vertex_spec.rb +5 -5
  113. data/spec/rley/gfg/vertex_spec.rb +3 -3
  114. data/spec/rley/lexical/token_range_spec.rb +16 -16
  115. data/spec/rley/lexical/token_spec.rb +2 -2
  116. data/spec/rley/notation/grammar_builder_spec.rb +302 -0
  117. data/spec/rley/notation/parser_spec.rb +184 -0
  118. data/spec/rley/notation/tokenizer_spec.rb +370 -0
  119. data/spec/rley/parse_forest_visitor_spec.rb +165 -163
  120. data/spec/rley/parse_rep/ambiguous_parse_spec.rb +44 -44
  121. data/spec/rley/parse_rep/ast_builder_spec.rb +6 -7
  122. data/spec/rley/parse_rep/cst_builder_spec.rb +5 -5
  123. data/spec/rley/parse_rep/groucho_spec.rb +24 -26
  124. data/spec/rley/parse_rep/parse_forest_builder_spec.rb +27 -27
  125. data/spec/rley/parse_rep/parse_forest_factory_spec.rb +8 -8
  126. data/spec/rley/parse_rep/parse_tree_factory_spec.rb +3 -3
  127. data/spec/rley/parse_tree_visitor_spec.rb +10 -8
  128. data/spec/rley/parser/dangling_else_spec.rb +445 -0
  129. data/spec/rley/parser/error_reason_spec.rb +6 -6
  130. data/spec/rley/parser/gfg_earley_parser_spec.rb +120 -12
  131. data/spec/rley/parser/gfg_parsing_spec.rb +6 -13
  132. data/spec/rley/parser/parse_entry_spec.rb +19 -19
  133. data/spec/rley/parser/parse_walker_factory_spec.rb +10 -10
  134. data/spec/rley/ptree/non_terminal_node_spec.rb +5 -3
  135. data/spec/rley/ptree/parse_tree_node_spec.rb +4 -4
  136. data/spec/rley/ptree/terminal_node_spec.rb +6 -6
  137. data/spec/rley/sppf/alternative_node_spec.rb +6 -6
  138. data/spec/rley/sppf/non_terminal_node_spec.rb +3 -3
  139. data/spec/rley/sppf/token_node_spec.rb +4 -4
  140. data/spec/rley/support/ambiguous_grammar_helper.rb +4 -5
  141. data/spec/rley/support/grammar_abc_helper.rb +3 -5
  142. data/spec/rley/support/grammar_ambig01_helper.rb +5 -6
  143. data/spec/rley/support/grammar_arr_int_helper.rb +5 -6
  144. data/spec/rley/support/grammar_b_expr_helper.rb +5 -6
  145. data/spec/rley/support/grammar_int_seq_helper.rb +51 -0
  146. data/spec/rley/support/grammar_l0_helper.rb +14 -17
  147. data/spec/rley/support/grammar_pb_helper.rb +8 -7
  148. data/spec/rley/support/grammar_sppf_helper.rb +3 -3
  149. data/spec/rley/syntax/{grammar_builder_spec.rb → base_grammar_builder_spec.rb} +35 -16
  150. data/spec/rley/syntax/grammar_spec.rb +6 -6
  151. data/spec/rley/syntax/grm_symbol_spec.rb +1 -1
  152. data/spec/rley/syntax/match_closest_spec.rb +46 -0
  153. data/spec/rley/syntax/non_terminal_spec.rb +8 -8
  154. data/spec/rley/syntax/production_spec.rb +17 -13
  155. data/spec/rley/syntax/symbol_seq_spec.rb +2 -2
  156. data/spec/rley/syntax/terminal_spec.rb +5 -5
  157. data/spec/rley/syntax/verbatim_symbol_spec.rb +1 -1
  158. data/spec/spec_helper.rb +0 -12
  159. data/spec/support/base_tokenizer_spec.rb +7 -2
  160. metadata +48 -74
  161. data/.simplecov +0 -7
  162. data/lib/rley/parser/parse_state.rb +0 -83
  163. data/lib/rley/parser/parse_state_tracker.rb +0 -59
  164. data/lib/rley/parser/state_set.rb +0 -101
  165. data/spec/rley/parser/parse_state_spec.rb +0 -125
  166. data/spec/rley/parser/parse_tracer_spec.rb +0 -200
  167. data/spec/rley/parser/state_set_spec.rb +0 -130
@@ -33,7 +33,7 @@ module Rley # Open this namespace to avoid module qualifier prefixes
33
33
  terminal = OpenStruct.new(name: aSymbolName)
34
34
  return OpenStruct.new(lexeme: aLexeme, terminal: terminal)
35
35
  end
36
-
36
+
37
37
  it 'should accept the addition of subnodes' do
38
38
  child1 = double('first_child')
39
39
  child2 = double('second_child')
@@ -44,6 +44,7 @@ module Rley # Open this namespace to avoid module qualifier prefixes
44
44
  expect(subject.subnodes).to eq([child3, child2, child1])
45
45
  end
46
46
 
47
+ # rubocop: disable Naming/VariableNumber
47
48
  it 'should provide a text representation of itself' do
48
49
  # Case 1: no child
49
50
  expected_text = 'VP[0, 3]'
@@ -61,9 +62,9 @@ module Rley # Open this namespace to avoid module qualifier prefixes
61
62
  noun = build_token('bus', 'Noun')
62
63
  child_3_1 = TerminalNode.new(noun, range(2, 3))
63
64
  # We reverse the sequence of subnode addition
64
- subject.add_subnode(child_1_2)
65
+ subject.add_subnode(child_1_2)
65
66
  subject.add_subnode(child_1_1)
66
- child_1_2.add_subnode(child_2_2)
67
+ child_1_2.add_subnode(child_2_2)
67
68
  child_1_2.add_subnode(child_2_1)
68
69
  child_2_2.add_subnode(child_3_1)
69
70
  expected_text = <<-SNIPPET
@@ -76,6 +77,7 @@ VP[0, 3]
76
77
  SNIPPET
77
78
  expect(subject.to_string(0)).to eq(expected_text.chomp)
78
79
  end
80
+ # rubocop: enable Naming/VariableNumber
79
81
  end # context
80
82
  end # describe
81
83
  end # module
@@ -27,17 +27,17 @@ module Rley # Open this namespace to avoid module qualifier prefixes
27
27
  expect(subject.range).to eq(sample_range)
28
28
  end
29
29
  end # context
30
-
30
+
31
31
  context 'Initialization:' do
32
32
  it 'should assign undefined range bounds' do
33
33
  partial_range = { low: 0 } # High bound left undefined
34
34
  instance = ParseTreeNode.new(sample_symbol, partial_range)
35
-
35
+
36
36
  another = { low: 1, high: 4 } # High bound is specified
37
37
  instance.range = another
38
38
  expect(instance.range).to eq(low: 0, high: 4)
39
- end
40
- end # context
39
+ end
40
+ end # context
41
41
  end # describe
42
42
  end # module
43
43
  end # module
@@ -10,23 +10,23 @@ module Rley # Open this namespace to avoid module qualifier prefixes
10
10
  module PTree # Open this namespace to avoid module qualifier prefixes
11
11
  describe TerminalNode do
12
12
  let(:sample_symbol) { OpenStruct.new(name: 'Noun') }
13
- let(:sample_token) do
14
- OpenStruct.new(lexeme: 'world', terminal: sample_symbol)
13
+ let(:sample_token) do
14
+ OpenStruct.new(lexeme: 'world', terminal: sample_symbol)
15
15
  end
16
16
  let(:sample_range) { double('fake-range') }
17
-
17
+
18
18
  subject { TerminalNode.new(sample_token, sample_range) }
19
-
19
+
20
20
  context 'Initialization:' do
21
21
  it 'should be bound to a token' do
22
22
  expect(subject.token).to eq(sample_token)
23
23
  end
24
24
  end # context
25
-
25
+
26
26
  context 'Provided services:' do
27
27
  it 'should provide a text representation of itself' do
28
28
  expected_text = "Noun[?, ?]: 'world'"
29
- expect(subject.to_string(0)).to eq(expected_text)
29
+ expect(subject.to_string(0)).to eq(expected_text)
30
30
  end
31
31
  end # context
32
32
  end # describe
@@ -19,7 +19,7 @@ module Rley # Open this namespace to avoid module qualifier prefixes
19
19
  def range(low, high)
20
20
  return Lexical::TokenRange.new(low: low, high: high)
21
21
  end
22
-
22
+
23
23
  let(:t_a) { Syntax::Terminal.new('A') }
24
24
  let(:t_b) { Syntax::Terminal.new('B') }
25
25
  let(:t_c) { Syntax::Terminal.new('C') }
@@ -29,7 +29,7 @@ module Rley # Open this namespace to avoid module qualifier prefixes
29
29
  end
30
30
  let(:sample_item) { Base::DottedItem.new(sample_prod, 3) }
31
31
  let(:sample_vertex) { GFG::ItemVertex.new(sample_item) }
32
- let(:sample_range) { range(0, 3) }
32
+ let(:sample_range) { range(0, 3) }
33
33
 
34
34
  subject { AlternativeNode.new(sample_vertex, sample_range) }
35
35
 
@@ -37,9 +37,9 @@ module Rley # Open this namespace to avoid module qualifier prefixes
37
37
  it 'should be created with a item vertex and a token range' do
38
38
  expect { AlternativeNode.new(sample_vertex, sample_range) }
39
39
  .not_to raise_error
40
- end
40
+ end
41
41
  end
42
-
42
+
43
43
  context 'Initialization:' do
44
44
  it 'should know its token range' do
45
45
  expect(subject.range).to eq(sample_range)
@@ -50,7 +50,7 @@ module Rley # Open this namespace to avoid module qualifier prefixes
50
50
  expect(subject.subnodes).to be_empty
51
51
  end
52
52
  end # context
53
-
53
+
54
54
  context 'Provided services:' do
55
55
  it 'should accept the addition of subnodes' do
56
56
  subnode1 = double('first_subnode')
@@ -63,7 +63,7 @@ module Rley # Open this namespace to avoid module qualifier prefixes
63
63
  end
64
64
 
65
65
 
66
- it 'should have a string representation' do
66
+ it 'should have a string representation' do
67
67
  expect(subject.to_string(0)).to eq('Alt(sentence => A B C .)[0, 3]')
68
68
  end
69
69
  end # context
@@ -37,12 +37,12 @@ module Rley # Open this namespace to avoid module qualifier prefixes
37
37
  it "shouldn't have children yet" do
38
38
  expect(subject.subnodes).to be_empty
39
39
  end
40
-
40
+
41
41
  it 'should have :and refinement' do
42
42
  expect(subject.refinement).to eq(:and)
43
43
  end
44
44
  end # context
45
-
45
+
46
46
  context 'Provided services:' do
47
47
  it 'should accept the addition of subnodes' do
48
48
  subnode1 = double('first_subnode')
@@ -57,7 +57,7 @@ module Rley # Open this namespace to avoid module qualifier prefixes
57
57
  it 'should have a string representation' do
58
58
  expect(subject.to_string(0)).to eq('VP[0, 3]')
59
59
  end
60
-
60
+
61
61
  it 'should return a key value of itself' do
62
62
  expect(subject.key).to eq('VP[0, 3]')
63
63
  end
@@ -15,8 +15,8 @@ module Rley # Open this namespace to avoid module qualifier prefixes
15
15
  describe TokenNode do
16
16
  let(:sample_symbol) { Syntax::Terminal.new('Noun') }
17
17
  let(:sample_position) { Lexical::Position.new(3, 4) }
18
- let(:sample_token) do
19
- Lexical::Token.new('language', sample_symbol, sample_position)
18
+ let(:sample_token) do
19
+ Lexical::Token.new('language', sample_symbol, sample_position)
20
20
  end
21
21
  let(:sample_rank) { 3 }
22
22
 
@@ -33,13 +33,13 @@ module Rley # Open this namespace to avoid module qualifier prefixes
33
33
  expect(subject.range.high).to eq(sample_rank + 1)
34
34
  end
35
35
  end # context
36
-
36
+
37
37
  context 'Provided services:' do
38
38
  it 'should know its string representation' do
39
39
  expect(subject.to_string(0)).to eq('Noun[3, 4]')
40
40
  expect(subject.inspect).to eq('Noun[3, 4]')
41
41
  end
42
-
42
+
43
43
  it 'should return a key value of itself' do
44
44
  expect(subject.key).to eq('Noun[3, 4]')
45
45
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Load the builder class
4
- require_relative '../../../lib/rley/syntax/grammar_builder'
4
+ require_relative '../../../lib/rley/notation/grammar_builder'
5
5
  require_relative '../../../lib/rley/lexical/token'
6
6
 
7
7
 
@@ -9,14 +9,13 @@ module AmbiguousGrammarHelper
9
9
  # Factory method. Creates a grammar builder for a basic ambiguous
10
10
  # expression grammar.
11
11
  # (based on an example from Fisher and LeBlanc: "Crafting a Compiler")
12
- def grammar_builder()
13
- builder = Rley::Syntax::GrammarBuilder.new do
12
+ def grammar_builder
13
+ Rley::Notation::GrammarBuilder.new do
14
14
  add_terminals('+', 'id')
15
15
  rule 'S' => 'E'
16
- rule 'E' => %w[E + E]
16
+ rule 'E' => 'E + E'
17
17
  rule 'E' => 'id'
18
18
  end
19
- builder
20
19
  end
21
20
 
22
21
  # Basic tokenizing method
@@ -1,20 +1,18 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Load the builder class
4
- require_relative '../../../lib/rley/syntax/grammar_builder'
4
+ require_relative '../../../lib/rley/syntax/base_grammar_builder'
5
5
 
6
6
  module GrammarABCHelper
7
7
  # Factory method. Creates a grammar builder for a simple grammar.
8
8
  # (based on example in N. Wirth "Compiler Construction" book, p. 6)
9
- def grammar_abc_builder()
10
- builder = Rley::Syntax::GrammarBuilder.new do
9
+ def grammar_abc_builder
10
+ Rley::Syntax::BaseGrammarBuilder.new do
11
11
  add_terminals('a', 'b', 'c')
12
12
  rule 'S' => 'A'
13
13
  rule 'A' => 'a A c'
14
14
  rule 'A' => 'b'
15
15
  end
16
-
17
- return builder
18
16
  end
19
17
  end # module
20
18
  # End of file
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Load the builder class
4
- require_relative '../../../lib/rley/syntax/grammar_builder'
4
+ require_relative '../../../lib/rley/syntax/base_grammar_builder'
5
5
  require_relative '../../../lib/rley/lexical/token'
6
6
 
7
7
 
@@ -10,16 +10,15 @@ module GrammarAmbig01Helper
10
10
  # Factory method. Define a grammar for a very simple language
11
11
  # Grammar 3: An ambiguous arithmetic expression language
12
12
  # (based on example in article on Earley's algorithm in Wikipedia)
13
- def grammar_ambig01_builder()
14
- builder = Rley::Syntax::GrammarBuilder.new do
13
+ def grammar_ambig01_builder
14
+ Rley::Syntax::BaseGrammarBuilder.new do
15
15
  add_terminals('integer', '+', '*')
16
16
  rule 'P' => 'S'
17
- rule 'S' => %w[S + S]
18
- rule 'S' => %w[S * S]
17
+ rule 'S' => 'S + S'
18
+ rule 'S' => 'S * S'
19
19
  rule 'S' => 'L'
20
20
  rule 'L' => 'integer'
21
21
  end
22
- builder
23
22
  end
24
23
 
25
24
  # Highly simplified tokenizer implementation.
@@ -3,7 +3,7 @@
3
3
  require 'strscan'
4
4
 
5
5
  # Load the builder class
6
- require_relative '../../../lib/rley/syntax/grammar_builder'
6
+ require_relative '../../../lib/rley/syntax/base_grammar_builder'
7
7
  require_relative '../../../lib/rley/lexical/token'
8
8
 
9
9
 
@@ -11,17 +11,16 @@ module GrammarArrIntHelper
11
11
  # Factory method. Creates a grammar builder for a grammar of
12
12
  # array of integers.
13
13
  # (based on the article about Earley's algorithm in Wikipedia)
14
- def grammar_arr_int_builder()
15
- builder = Rley::Syntax::GrammarBuilder.new do
14
+ def grammar_arr_int_builder
15
+ Rley::Syntax::BaseGrammarBuilder.new do
16
16
  add_terminals('[', ']', ',', 'integer')
17
17
  rule 'P' => 'arr'
18
- rule 'arr' => %w([ sequence ])
18
+ rule 'arr' => '[ sequence ]'
19
19
  rule 'sequence' => 'list'
20
20
  rule 'sequence' => []
21
- rule 'list' => %w[list , integer] # Left-recursive rule
21
+ rule 'list' => 'list , integer' # Left-recursive rule
22
22
  rule 'list' => 'integer'
23
23
  end
24
- builder
25
24
  end
26
25
 
27
26
  # Basic tokenizer for array of integers
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Load the builder class
4
- require_relative '../../../lib/rley/syntax/grammar_builder'
4
+ require_relative '../../../lib/rley/syntax/base_grammar_builder'
5
5
  require_relative '../../../lib/rley/lexical/token'
6
6
 
7
7
 
@@ -9,17 +9,16 @@ module GrammarBExprHelper
9
9
  # Factory method. Creates a grammar builder for a basic arithmetic
10
10
  # expression grammar.
11
11
  # (based on the article about Earley's algorithm in Wikipedia)
12
- def grammar_expr_builder()
13
- builder = Rley::Syntax::GrammarBuilder.new do
12
+ def grammar_expr_builder
13
+ Rley::Syntax::BaseGrammarBuilder.new do
14
14
  add_terminals('+', '*', 'integer')
15
15
  rule 'P' => 'S'
16
- rule 'S' => %w[S + M]
16
+ rule 'S' => 'S + M'
17
17
  rule 'S' => 'M'
18
- rule 'M' => %w[M * T]
18
+ rule 'M' => 'M * T'
19
19
  rule 'M' => 'T'
20
20
  rule 'T' => 'integer'
21
21
  end
22
- builder
23
22
  end
24
23
 
25
24
  # Basic expression tokenizer
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'strscan'
4
+
5
+ # Load the builder class
6
+ require_relative '../../../lib/rley/notation/grammar_builder'
7
+ require_relative '../../../lib/rley/lexical/token'
8
+
9
+
10
+ module GrammarIntSeqHelper
11
+ # Factory method. Creates a builder for a grammar of sequence
12
+ # of positive integers.
13
+ def grammar_int_seq_builder
14
+ Rley::Notation::GrammarBuilder.new do
15
+ add_terminals('comma', 'digit')
16
+ rule 'S' => 'sequence'
17
+ rule 'S' => ''
18
+ rule 'sequence' => 'sequence comma integer'
19
+ rule 'sequence' => 'integer'
20
+ rule 'integer' => 'digit+'
21
+ end
22
+ end
23
+
24
+ # Basic tokenizer for sequence positive integers
25
+ def int_seq_tokenizer(aText)
26
+ scanner = StringScanner.new(aText)
27
+ tokens = []
28
+
29
+ loop do
30
+ scanner.skip(/\s+/)
31
+ break if scanner.eos?
32
+
33
+ curr_pos = scanner.pos
34
+
35
+ if (lexeme = scanner.scan(/,/))
36
+ terminal = 'comma'
37
+ elsif (lexeme = scanner.scan(/\d/))
38
+ terminal = 'digit'
39
+ else
40
+ msg = "Unknown input text '#{scanner.scan(/.*/)}'"
41
+ raise StandardError, msg
42
+ end
43
+
44
+ pos = Rley::Lexical::Position.new(1, curr_pos + 1)
45
+ tokens << Rley::Lexical::Token.new(lexeme, terminal, pos)
46
+ end
47
+
48
+ return tokens
49
+ end
50
+ end # module
51
+ # End of file
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Load the builder class
4
- require_relative '../../../lib/rley/syntax/grammar_builder'
4
+ require_relative '../../../lib/rley/syntax/base_grammar_builder'
5
5
  require_relative '../../../lib/rley/lexical/token'
6
6
 
7
7
 
@@ -11,29 +11,28 @@ module GrammarL0Helper
11
11
  # based on Jurafky & Martin L0 language (chapter 12 of the book).
12
12
  # It defines the syntax of a sentence in a language with a
13
13
  # very limited syntax and lexicon in the context of airline reservation.
14
- def grammar_l0_builder()
15
- builder = Rley::Syntax::GrammarBuilder.new do
14
+ def grammar_l0_builder
15
+ Rley::Syntax::BaseGrammarBuilder.new do
16
16
  add_terminals('Noun', 'Verb', 'Pronoun', 'Proper-Noun')
17
17
  add_terminals('Determiner', 'Preposition')
18
- rule 'S' => %w[NP VP]
18
+ rule 'S' => 'NP VP'
19
19
  rule 'NP' => 'Pronoun'
20
20
  rule 'NP' => 'Proper-Noun'
21
- rule 'NP' => %w[Determiner Nominal]
22
- rule 'Nominal' => %w[Nominal Noun]
21
+ rule 'NP' => 'Determiner Nominal'
22
+ rule 'Nominal' => 'Nominal Noun'
23
23
  rule 'Nominal' => 'Noun'
24
24
  rule 'VP' => 'Verb'
25
- rule 'VP' => %w[Verb NP]
26
- rule 'VP' => %w[Verb NP PP]
27
- rule 'VP' => %w[Verb PP]
28
- rule 'PP' => %w[Preposition PP]
25
+ rule 'VP' => 'Verb NP'
26
+ rule 'VP' => 'Verb NP PP'
27
+ rule 'VP' => 'Verb PP'
28
+ rule 'PP' => 'Preposition PP'
29
29
  end
30
- builder
31
30
  end
32
31
 
33
32
  # Return the language lexicon.
34
33
  # A lexicon is just a Hash with pairs of the form:
35
34
  # word => terminal symbol name
36
- def lexicon_l0()
35
+ def lexicon_l0
37
36
  return {
38
37
  'flight' => 'Noun',
39
38
  'breeze' => 'Noun',
@@ -78,13 +77,11 @@ module GrammarL0Helper
78
77
  word = scanner.scan(/\S+/)
79
78
  break unless word
80
79
 
81
- term_name = lexicon_l0[word]
82
- if term_name.nil?
83
- raise StandardError, "Word '#{word}' not found in lexicon"
84
- end
80
+ term = lexicon_l0[word]
81
+ raise StandardError, "Word '#{word}' not found in lexicon" if term.nil?
85
82
 
86
83
  pos = Rley::Lexical::Position.new(1, curr_pos + 1)
87
- tokens << Rley::Lexical::Token.new(word, term_name, pos)
84
+ tokens << Rley::Lexical::Token.new(word, term, pos)
88
85
  end
89
86
 
90
87
  return tokens