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
@@ -5,33 +5,33 @@ require 'rley' # Load the gem
5
5
 
6
6
  ########################################
7
7
  # Define a grammar for basic arithmetical expressions
8
- builder = Rley::Syntax::GrammarBuilder.new do
8
+ builder = Rley::grammar_builder do
9
9
  add_terminals('NUMBER')
10
10
  add_terminals('PLUS', 'MINUS') # For '+', '-' operators or sign
11
11
  add_terminals('STAR', 'DIVIDE', 'POWER') # For '*', '/', '**' operators
12
- add_terminals('LPAREN', 'RPAREN') # For '(', ')' delimiters
12
+ add_terminals('LPAREN', 'RPAREN') # For '(', ')' delimiters
13
13
  add_terminals('PI', 'E') # For numeric constants
14
14
  add_terminals('RESERVED') # Reserved identifiers
15
15
 
16
- rule 'expression' => %w[simple_expression]
16
+ rule 'expression' => 'simple_expression'
17
17
  rule 'simple_expression' => 'term'
18
- rule 'simple_expression' => %w[simple_expression add_operator term]
18
+ rule 'simple_expression' => 'simple_expression add_operator term'
19
19
  rule 'term' => 'factor'
20
- rule 'term' => %w[term mul_operator factor]
20
+ rule 'term' => 'term mul_operator factor'
21
21
  rule 'factor' => 'simple_factor'
22
- rule 'factor' => %w[factor POWER simple_factor]
23
- rule 'simple_factor' => %w[sign scalar]
24
- rule 'simple_factor' => %w[unary_function in_parenthesis]
25
- rule 'simple_factor' => %w[MINUS in_parenthesis]
26
- rule 'simple_factor' => 'in_parenthesis'
22
+ rule 'factor' => 'factor POWER simple_factor'
23
+ rule 'simple_factor' => 'sign scalar'
24
+ rule 'simple_factor' => 'unary_function in_parenthesis'
25
+ rule 'simple_factor' => 'MINUS in_parenthesis'
26
+ rule 'simple_factor' => 'in_parenthesis'
27
27
  rule 'sign' => 'PLUS'
28
28
  rule 'sign' => 'MINUS'
29
29
  rule 'sign' => []
30
30
  rule 'scalar' => 'NUMBER'
31
31
  rule 'scalar' => 'PI'
32
- rule 'scalar' => 'E'
32
+ rule 'scalar' => 'E'
33
33
  rule 'unary_function' => 'RESERVED'
34
- rule 'in_parenthesis' => %w[LPAREN expression RPAREN]
34
+ rule 'in_parenthesis' => 'LPAREN expression RPAREN'
35
35
  rule 'add_operator' => 'PLUS'
36
36
  rule 'add_operator' => 'MINUS'
37
37
  rule 'mul_operator' => 'STAR'
@@ -10,7 +10,6 @@ class CalcLexer
10
10
  attr_reader(:lineno)
11
11
  attr_reader(:line_start)
12
12
 
13
-
14
13
  @@lexeme2name = {
15
14
  '(' => 'LPAREN',
16
15
  ')' => 'RPAREN',
@@ -22,7 +21,7 @@ class CalcLexer
22
21
  'PI' => 'PI',
23
22
  'E' => 'E'
24
23
  }.freeze
25
-
24
+
26
25
  @@unary_functions = %w[
27
26
  sin cos tan asin acos atan
28
27
  sqrt cbrt exp ln log
@@ -35,7 +34,7 @@ class CalcLexer
35
34
  @lineno = 1
36
35
  end
37
36
 
38
- def tokens()
37
+ def tokens
39
38
  @unary_f_pattern = Regexp.new(@@unary_functions.join('|'))
40
39
  tok_sequence = []
41
40
  until @scanner.eos?
@@ -48,11 +47,12 @@ class CalcLexer
48
47
 
49
48
  private
50
49
 
51
- def _next_token()
50
+ # rubocop: disable Lint/DuplicateBranch
51
+ def _next_token
52
52
  skip_whitespaces
53
53
  curr_ch = scanner.peek(1)
54
54
  return nil if curr_ch.nil?
55
-
55
+
56
56
  token = nil
57
57
 
58
58
  if '()+-/'.include? curr_ch
@@ -63,25 +63,26 @@ class CalcLexer
63
63
  elsif (lexeme = scanner.scan(/\*|PI|E/))
64
64
  token = build_token(@@lexeme2name[lexeme], lexeme)
65
65
  elsif (lexeme = scanner.scan(@unary_f_pattern))
66
- token = build_token('RESERVED', lexeme)
66
+ token = build_token('RESERVED', lexeme)
67
67
  elsif (lexeme = scanner.scan(/[0-9]+(\.[0-9]+)?([eE][-+]?[0-9])?/))
68
68
  token = build_token('NUMBER', lexeme)
69
69
  else # Unknown token
70
70
  erroneous = curr_ch.nil? ? '' : curr_ch
71
71
  sequel = scanner.scan(/.{1,20}/)
72
72
  erroneous += sequel unless sequel.nil?
73
- raise ScanError.new("Unknown token #{erroneous}")
73
+ raise ScanError, "Unknown token #{erroneous}"
74
74
  end
75
75
 
76
76
  return token
77
77
  end
78
-
78
+ # rubocop: enable Lint/DuplicateBranch
79
+
79
80
  def build_token(aSymbolName, aLexeme)
80
81
  pos = Rley::Lexical::Position.new(1, scanner.pos)
81
- return Rley::Lexical::Token.new(aLexeme, aSymbolName, pos)
82
+ return Rley::Lexical::Token.new(aLexeme, aSymbolName, pos)
82
83
  end
83
84
 
84
- def skip_whitespaces()
85
+ def skip_whitespaces
85
86
  scanner.scan(/[ \t\f\n\r]+/)
86
87
  end
87
88
  end # class
@@ -17,13 +17,13 @@ describe 'Calculator' do
17
17
  engine = Rley::Engine.new do |cfg|
18
18
  cfg.repr_builder = CalcASTBuilder
19
19
  end
20
-
20
+
21
21
  engine.use_grammar(CalcGrammar)
22
22
  raw_result = parse_expression(engine, anExpression)
23
23
  ast = engine.to_ptree(raw_result)
24
24
  return expect(ast.root.interpret)
25
25
  end
26
-
26
+
27
27
  def parse_expression(anEngine, anExpression)
28
28
  lexer = CalcLexer.new(anExpression)
29
29
  result = anEngine.parse(lexer.tokens)
@@ -40,7 +40,7 @@ describe 'Calculator' do
40
40
 
41
41
  context 'Parsing valid expressions' do
42
42
  let(:epsilon) { 0.0000000001 }
43
-
43
+
44
44
  it 'should evaluate simple integer literals' do
45
45
  expect_expr('2').to eq(2)
46
46
  end
@@ -72,18 +72,18 @@ describe 'Calculator' do
72
72
  it 'should evaluate the pi constant' do
73
73
  expect_expr('PI').to eq(3.141592653589793)
74
74
  end
75
-
75
+
76
76
  it 'should evaluate the negated pi constant' do
77
77
  expect_expr('-PI').to eq(-3.141592653589793)
78
- end
78
+ end
79
79
 
80
80
  it "should evaluate Neper's e constant" do
81
81
  expect_expr('E').to eq(2.718281828459045)
82
82
  end
83
-
83
+
84
84
  it "should evaluate negated Neper's e constant" do
85
85
  expect_expr('-E').to eq(-2.718281828459045)
86
- end
86
+ end
87
87
 
88
88
  it 'should evaluate integer addition' do
89
89
  expect_expr('2 + 2').to eq(4)
@@ -156,7 +156,7 @@ describe 'Calculator' do
156
156
  it 'should evaluate multiple levels of parentheses' do
157
157
  expect_expr('2*(1/(1+3))').to eq(0.5)
158
158
  end
159
-
159
+
160
160
  # Some special functions
161
161
  it 'should evaluate square root of expressions' do
162
162
  expect_expr('sqrt(0)').to eq(0)
@@ -170,69 +170,69 @@ describe 'Calculator' do
170
170
  expect_expr('cbrt(1)').to eq(1)
171
171
  expect_expr('cbrt(1 + 1)').to eq(Math.cbrt(2))
172
172
  expect_expr('cbrt(5 * 5 * 5)').to eq(5)
173
- end
173
+ end
174
174
 
175
175
  it 'should evaluate exponential of expressions' do
176
- expect_expr('exp(-1)').to eq(1 / Math::E)
176
+ expect_expr('exp(-1)').to eq(1 / Math::E)
177
177
  expect_expr('exp(0)').to eq(1)
178
178
  expect_expr('exp(1)').to eq(Math::E)
179
179
  expect_expr('exp(2)').to be_within(epsilon).of(Math::E * Math::E)
180
180
  end
181
181
 
182
182
  it 'should evaluate natural logarithm of expressions' do
183
- expect_expr('ln(1/E)').to eq(-1)
184
- expect_expr('ln(1)').to eq(0)
183
+ expect_expr('ln(1/E)').to eq(-1)
184
+ expect_expr('ln(1)').to eq(0)
185
185
  expect_expr('ln(E)').to eq(1)
186
186
  expect_expr('ln(E * E)').to eq(2)
187
- end
187
+ end
188
188
 
189
189
  it 'should evaluate the logarithm base 10 of expressions' do
190
- expect_expr('log(1/10)').to eq(-1)
191
- expect_expr('log(1)').to eq(0)
190
+ expect_expr('log(1/10)').to eq(-1)
191
+ expect_expr('log(1)').to eq(0)
192
192
  expect_expr('log(10)').to eq(1)
193
193
  expect_expr('log(10 * 10 * 10)').to eq(3)
194
- end
195
-
194
+ end
195
+
196
196
  # Trigonometric functions
197
-
197
+
198
198
  it 'should compute the sinus of an expression' do
199
199
  expect_expr('sin(0)').to eq(0)
200
200
  expect_expr('sin(PI/6)').to be_within(epsilon).of(0.5)
201
201
  expect_expr('sin(PI/2)').to eq(1)
202
202
  end
203
-
203
+
204
204
  it 'should compute the cosinus of an expression' do
205
205
  expect_expr('cos(0)').to eq(1)
206
206
  expect_expr('cos(PI/3)').to be_within(epsilon).of(0.5)
207
207
  expect_expr('cos(PI/2)').to be_within(epsilon).of(0)
208
- end
208
+ end
209
209
 
210
210
  it 'should compute the tangent of an expression' do
211
211
  expect_expr('tan(0)').to eq(0)
212
212
  expect_expr('tan(PI/4)').to be_within(epsilon).of(1)
213
213
  expect_expr('tan(5*PI/12)').to be_within(epsilon).of(2 + Math.sqrt(3))
214
- end
215
-
214
+ end
215
+
216
216
  # Inverse trigonometric functions
217
-
217
+
218
218
  it 'should compute the arcsinus of an expression' do
219
219
  expect_expr('asin(0)').to eq(0)
220
220
  expect_expr('asin(0.5)').to be_within(epsilon).of(Math::PI / 6)
221
221
  expect_expr('asin(1)').to eq(Math::PI / 2)
222
222
  end
223
-
223
+
224
224
  it 'should compute the arccosinus of an expression' do
225
225
  expect_expr('acos(1)').to eq(0)
226
226
  expect_expr('acos(0.5)').to be_within(epsilon).of(Math::PI / 3)
227
227
  expect_expr('acos(0)').to be_within(epsilon).of(Math::PI / 2)
228
- end
228
+ end
229
229
 
230
230
  it 'should compute the tangent of an expression' do
231
231
  expect_expr('atan(0)').to eq(0)
232
232
  pi = Math::PI
233
233
  expect_expr('atan(1)').to be_within(epsilon).of(pi / 4)
234
234
  expect_expr('atan(2 + sqrt(3))').to be_within(epsilon).of(5 * pi / 12)
235
- end
235
+ end
236
236
  end # context
237
237
  end # describe
238
238
  # End of file
@@ -8,10 +8,10 @@ builder = Rley::Syntax::GrammarBuilder.new do
8
8
  # The grammar defines a language that consists in a sequence
9
9
  # of 0 or more dots...
10
10
  add_terminals('DOT')
11
-
11
+
12
12
  # Grammar with left recursive rule.
13
13
  rule 'l_dots' => []
14
- rule 'l_dots' => %w[l_dots DOT]
14
+ rule 'l_dots' => 'l_dots DOT'
15
15
  end
16
16
 
17
17
  # And now, let's build the grammar...
@@ -8,10 +8,10 @@ builder = Rley::Syntax::GrammarBuilder.new do
8
8
  # The grammar defines a language that consists in a sequence
9
9
  # of 0 or more dots...
10
10
  add_terminals('DOT')
11
-
11
+
12
12
  # Grammar with right recursive rule.
13
13
  rule 'r_dots' => []
14
- rule 'r_dots' => %w[DOT r_dots]
14
+ rule 'r_dots' => 'DOT r_dots'
15
15
  end
16
16
 
17
17
  # And now, let's build the grammar...
data/lib/rley.rb CHANGED
@@ -5,7 +5,7 @@
5
5
  # for a Rley client.
6
6
 
7
7
  require_relative './rley/constants'
8
- require_relative './rley/syntax/grammar_builder'
8
+ require_relative './rley/interface'
9
9
  require_relative './rley/lexical/token'
10
10
  require_relative './rley/parser/gfg_earley_parser'
11
11
  require_relative './rley/parse_rep/ast_base_builder'
@@ -19,14 +19,19 @@ module Rley # This module is used as a namespace
19
19
  class DottedItem
20
20
  # Production rule
21
21
  # @return [Syntax::Production]
22
- attr_reader(:production)
22
+ attr_reader :production
23
23
 
24
24
  # Index of the next symbol (from the rhs) after the 'dot'.
25
25
  # If the dot is at the end of the rhs (i.e.) there is no next
26
26
  # symbol, then the position takes the value -1.
27
27
  # It the rhs is empty, then the position is -2
28
28
  # @return [Integer]
29
- attr_reader(:position)
29
+ attr_reader :position
30
+
31
+ # A possible constraint between symbol on left of dot and
32
+ # the closest preceding given terminal
33
+ # @return [NilClass, Syntax::MatchClosest]
34
+ attr_accessor :constraint
30
35
 
31
36
  # @param aProduction [Syntax::Production]
32
37
  # @param aPosition [Integer] Position of the dot in rhs of production.
@@ -37,7 +42,7 @@ module Rley # This module is used as a namespace
37
42
 
38
43
  # Return a String representation of the dotted item.
39
44
  # @return [String]
40
- def to_s()
45
+ def to_s
41
46
  prefix = "#{production.lhs} => "
42
47
  text_values = production.rhs.map(&:to_s)
43
48
  if position.negative?
@@ -47,13 +52,13 @@ module Rley # This module is used as a namespace
47
52
  end
48
53
  suffix = text_values.join(' ')
49
54
 
50
- return prefix + suffix
55
+ prefix + suffix
51
56
  end
52
57
 
53
58
  # Return true if the dot position is at the start of the rhs.
54
59
  # @return [Boolean]
55
- def at_start?()
56
- return position.zero? || position == -2
60
+ def at_start?
61
+ position.zero? || position == -2
57
62
  end
58
63
 
59
64
  # An item with the dot at the beginning is called
@@ -62,41 +67,35 @@ module Rley # This module is used as a namespace
62
67
 
63
68
  # A dotted item is called a reduce item if the dot is at the end.
64
69
  # @return [Boolean]
65
- def reduce_item?()
66
- return position.negative? # Either -1 or -2
70
+ def reduce_item?
71
+ position.negative? # Either -1 or -2
67
72
  end
68
73
 
69
74
  # The non-terminal symbol that is on the left-side of the production
70
75
  # @return [Syntax::NonTerminal]
71
- def lhs()
72
- return production.lhs
76
+ def lhs
77
+ production.lhs
73
78
  end
74
79
 
75
80
  # Return the symbol before the dot.
76
81
  # nil is returned if the dot is at the start of the rhs
77
82
  # @return [Syntax::GrmSymbol, NilClass]
78
- def prev_symbol()
83
+ def prev_symbol
79
84
  before_position = prev_position
80
- result = if before_position.nil?
81
- nil
82
- else
83
- production.rhs[before_position]
84
- end
85
-
86
- return result
85
+ before_position.nil? ? nil : production.rhs[before_position]
87
86
  end
88
87
 
89
88
  # Return the symbol after the dot.
90
89
  # nil is returned if the dot is at the end
91
90
  # @return [Syntax::GrmSymbol, NilClass]
92
- def next_symbol()
93
- return position.negative? ? nil : production.rhs[position]
91
+ def next_symbol
92
+ position.negative? ? nil : production.rhs[position]
94
93
  end
95
94
 
96
95
  # Calculate the position of the dot if were moved by
97
96
  # one step on the left.
98
97
  # @return [Integer]
99
- def prev_position()
98
+ def prev_position
100
99
  unless @k_prev_position
101
100
  case position
102
101
  when -2, 0
@@ -122,7 +121,7 @@ module Rley # This module is used as a namespace
122
121
  to_the_left = prev_position
123
122
  return false if to_the_left.nil?
124
123
 
125
- return to_the_left == another.position
124
+ to_the_left == another.position
126
125
  end
127
126
 
128
127
 
@@ -135,15 +134,13 @@ module Rley # This module is used as a namespace
135
134
  raise StandardError, 'Out of bound index'
136
135
  end
137
136
 
138
- index = if rhs_size.zero?
139
- -2 # Minus 2 at start/end of empty production
140
- elsif aPosition == rhs_size
141
- -1 # Minus 1 at end of non-empty production
142
- else
143
- aPosition
144
- end
145
-
146
- return index
137
+ if rhs_size.zero?
138
+ -2 # Minus 2 at start/end of empty production
139
+ elsif aPosition == rhs_size
140
+ -1 # Minus 1 at end of non-empty production
141
+ else
142
+ aPosition
143
+ end
147
144
  end
148
145
  end # class
149
146
  end # module
@@ -12,12 +12,18 @@ module Rley # This module is used as a namespace
12
12
  def build_dotted_items(aGrammar)
13
13
  items = []
14
14
  aGrammar.rules.each do |prod|
15
+ index_prev = items.size
15
16
  rhs_size = prod.rhs.size
16
17
  if rhs_size.zero?
17
18
  items << DottedItem.new(prod, 0)
18
19
  else
19
20
  items += (0..rhs_size).map { |i| DottedItem.new(prod, i) }
20
21
  end
22
+
23
+ prod.constraints.each do |cs|
24
+ # Attach constraint to dotted item n + 1
25
+ items[index_prev + cs.idx_symbol + 1].constraint = cs
26
+ end
21
27
  end
22
28
 
23
29
  return items