rley 0.7.06 → 0.8.01

Sign up to get free protection for your applications and to get access to all the features.
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