rley 0.8.01 → 0.8.02
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 +29 -5
- data/CHANGELOG.md +7 -0
- data/examples/NLP/pico_en_demo.rb +2 -2
- data/lib/rley/constants.rb +1 -1
- data/lib/rley/notation/all_notation_nodes.rb +3 -1
- data/lib/rley/notation/ast_builder.rb +185 -191
- data/lib/rley/notation/ast_node.rb +5 -5
- data/lib/rley/notation/ast_visitor.rb +3 -1
- data/lib/rley/notation/grammar.rb +1 -1
- data/lib/rley/notation/grammar_builder.rb +16 -15
- data/lib/rley/notation/grouping_node.rb +1 -1
- data/lib/rley/notation/parser.rb +56 -56
- data/lib/rley/notation/sequence_node.rb +3 -3
- data/lib/rley/notation/symbol_node.rb +2 -2
- data/lib/rley/notation/tokenizer.rb +3 -15
- data/lib/rley/parse_rep/ast_base_builder.rb +5 -6
- data/lib/rley/parser/gfg_chart.rb +5 -4
- data/lib/rley/parser/gfg_earley_parser.rb +1 -1
- data/lib/rley/syntax/base_grammar_builder.rb +3 -3
- data/lib/rley/syntax/match_closest.rb +7 -7
- data/spec/rley/notation/grammar_builder_spec.rb +6 -6
- data/spec/rley/notation/parser_spec.rb +183 -184
- data/spec/rley/notation/tokenizer_spec.rb +98 -104
- data/spec/rley/parser/dangling_else_spec.rb +15 -13
- data/spec/rley/parser/gfg_earley_parser_spec.rb +11 -9
- data/spec/rley/parser/gfg_parsing_spec.rb +1 -0
- data/spec/rley/syntax/base_grammar_builder_spec.rb +0 -1
- data/spec/rley/syntax/match_closest_spec.rb +4 -4
- metadata +2 -2
@@ -19,10 +19,10 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
19
19
|
expect(token.lexeme).to eq(lexeme)
|
20
20
|
end
|
21
21
|
end
|
22
|
-
|
22
|
+
|
23
23
|
context 'Initialization:' do
|
24
|
-
|
25
|
-
|
24
|
+
let(:sample_text) { 'begin-object member-list end-object' }
|
25
|
+
subject { Tokenizer.new }
|
26
26
|
|
27
27
|
it 'could be initialized with a text to tokenize or...' do
|
28
28
|
expect { Tokenizer.new(sample_text) }.not_to raise_error
|
@@ -36,7 +36,7 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
36
36
|
expect(subject.scanner).to be_kind_of(StringScanner)
|
37
37
|
end
|
38
38
|
end # context
|
39
|
-
|
39
|
+
|
40
40
|
context 'Input tokenization:' do
|
41
41
|
it 'should recognize single special character token' do
|
42
42
|
input = '(){}?*+,'
|
@@ -47,9 +47,9 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
47
47
|
%w[RIGHT_PAREN )],
|
48
48
|
%w[LEFT_BRACE {],
|
49
49
|
%w[RIGHT_BRACE }],
|
50
|
-
%w[QUESTION_MARK ?],
|
51
|
-
%w[STAR *],
|
52
|
-
%w[PLUS +],
|
50
|
+
%w[QUESTION_MARK ?],
|
51
|
+
%w[STAR *],
|
52
|
+
%w[PLUS +],
|
53
53
|
%w[COMMA ,]
|
54
54
|
]
|
55
55
|
match_expectations(subject, expectations)
|
@@ -64,7 +64,7 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
64
64
|
]
|
65
65
|
match_expectations(subject, expectations)
|
66
66
|
end
|
67
|
-
|
67
|
+
|
68
68
|
it 'should treat ? * + as symbols if they occur as suffix' do
|
69
69
|
input = 'a+ + b* * 3 ?'
|
70
70
|
subject.start_with(input)
|
@@ -80,7 +80,7 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
80
80
|
%w[SYMBOL ?]
|
81
81
|
]
|
82
82
|
match_expectations(subject, expectations)
|
83
|
-
end
|
83
|
+
end
|
84
84
|
|
85
85
|
it 'should recognize annotation keywords' do
|
86
86
|
keywords = 'match_closest: repeat:'
|
@@ -110,7 +110,7 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
110
110
|
subject.tokens[0..-2].each_with_index do |tok, i|
|
111
111
|
expect(tok).to be_kind_of(Rley::Lexical::Token)
|
112
112
|
expect(tok.terminal).to eq('INT_LIT')
|
113
|
-
(lexeme,
|
113
|
+
(lexeme,) = expectations[i]
|
114
114
|
expect(tok.lexeme).to eq(lexeme)
|
115
115
|
end
|
116
116
|
end
|
@@ -135,37 +135,31 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
135
135
|
subject.tokens.each_with_index do |str, i|
|
136
136
|
expect(str).to be_kind_of(Rley::Lexical::Token)
|
137
137
|
expect(str.terminal).to eq('STR_LIT')
|
138
|
-
(lexeme,
|
138
|
+
(lexeme,) = expectations[i]
|
139
139
|
expect(str.lexeme).to eq(lexeme)
|
140
140
|
end
|
141
141
|
end
|
142
142
|
|
143
143
|
it 'should recognize a sequence of symbols' do
|
144
|
-
input =
|
145
|
-
expectations = [
|
146
|
-
'IF',
|
147
|
-
'ifCondition',
|
148
|
-
'statement',
|
149
|
-
'ELSE',
|
150
|
-
'statement'
|
151
|
-
]
|
144
|
+
input = 'IF ifCondition statement ELSE statement'
|
145
|
+
expectations = %w[IF ifCondition statement ELSE statement]
|
152
146
|
|
153
147
|
subject.start_with(input)
|
154
148
|
subject.tokens.each_with_index do |str, i|
|
155
149
|
expect(str).to be_kind_of(Rley::Lexical::Token)
|
156
150
|
expect(str.terminal).to eq('SYMBOL')
|
157
|
-
(lexeme,
|
151
|
+
(lexeme,) = expectations[i]
|
158
152
|
expect(str.lexeme).to eq(lexeme)
|
159
153
|
end
|
160
154
|
end
|
161
155
|
|
162
156
|
it 'should recognize an optional symbol' do
|
163
|
-
input =
|
157
|
+
input = 'RETURN expression? SEMICOLON'
|
164
158
|
expectations = [
|
165
|
-
[
|
166
|
-
[
|
167
|
-
[
|
168
|
-
[
|
159
|
+
%w[RETURN SYMBOL],
|
160
|
+
%w[expression SYMBOL],
|
161
|
+
%w[? QUESTION_MARK],
|
162
|
+
%w[SEMICOLON SYMBOL]
|
169
163
|
]
|
170
164
|
|
171
165
|
subject.start_with(input)
|
@@ -178,11 +172,11 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
178
172
|
end
|
179
173
|
|
180
174
|
it 'should recognize a symbol with a star quantifier' do
|
181
|
-
input =
|
175
|
+
input = 'declaration* EOF'
|
182
176
|
expectations = [
|
183
|
-
[
|
184
|
-
[
|
185
|
-
[
|
177
|
+
%w[declaration SYMBOL],
|
178
|
+
%w[* STAR],
|
179
|
+
%w[EOF SYMBOL]
|
186
180
|
]
|
187
181
|
|
188
182
|
subject.start_with(input)
|
@@ -195,11 +189,11 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
195
189
|
end
|
196
190
|
|
197
191
|
it 'should recognize a symbol with a plus quantifier' do
|
198
|
-
input =
|
192
|
+
input = 'declaration+ EOF'
|
199
193
|
expectations = [
|
200
|
-
[
|
201
|
-
[
|
202
|
-
[
|
194
|
+
%w[declaration SYMBOL],
|
195
|
+
%w[+ PLUS],
|
196
|
+
%w[EOF SYMBOL]
|
203
197
|
]
|
204
198
|
|
205
199
|
subject.start_with(input)
|
@@ -212,16 +206,16 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
212
206
|
end
|
213
207
|
|
214
208
|
it 'should recognize a grouping with a quantifier' do
|
215
|
-
input =
|
209
|
+
input = 'IF ifCondition statement (ELSE statement)?'
|
216
210
|
expectations = [
|
217
|
-
[
|
218
|
-
[
|
219
|
-
[
|
220
|
-
[
|
221
|
-
[
|
222
|
-
[
|
223
|
-
[
|
224
|
-
[
|
211
|
+
%w[IF SYMBOL],
|
212
|
+
%w[ifCondition SYMBOL],
|
213
|
+
%w[statement SYMBOL],
|
214
|
+
%w[( LEFT_PAREN],
|
215
|
+
%w[ELSE SYMBOL],
|
216
|
+
%w[statement SYMBOL],
|
217
|
+
%w[) RIGHT_PAREN],
|
218
|
+
%w[? QUESTION_MARK]
|
225
219
|
]
|
226
220
|
|
227
221
|
subject.start_with(input)
|
@@ -236,15 +230,15 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
236
230
|
it 'should recognize a match closest constraint' do
|
237
231
|
input = "IF ifCondition statement ELSE { match_closest: 'IF' } statement"
|
238
232
|
expectations = [
|
239
|
-
[
|
240
|
-
[
|
241
|
-
[
|
242
|
-
[
|
243
|
-
[
|
244
|
-
[
|
245
|
-
[
|
246
|
-
[
|
247
|
-
[
|
233
|
+
%w[IF SYMBOL],
|
234
|
+
%w[ifCondition SYMBOL],
|
235
|
+
%w[statement SYMBOL],
|
236
|
+
%w[ELSE SYMBOL],
|
237
|
+
%w[{ LEFT_BRACE],
|
238
|
+
%w[match_closest KEY],
|
239
|
+
%w[IF STR_LIT],
|
240
|
+
%w[} RIGHT_BRACE],
|
241
|
+
%w[statement SYMBOL]
|
248
242
|
]
|
249
243
|
|
250
244
|
subject.start_with(input)
|
@@ -257,17 +251,17 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
257
251
|
end
|
258
252
|
|
259
253
|
it 'should recognize a repeat constraint' do
|
260
|
-
input =
|
254
|
+
input = 'IF ifCondition statement { repeat: 1 } ELSE statement'
|
261
255
|
expectations = [
|
262
|
-
[
|
263
|
-
[
|
264
|
-
[
|
265
|
-
[
|
266
|
-
[
|
267
|
-
[
|
268
|
-
[
|
269
|
-
[
|
270
|
-
[
|
256
|
+
%w[IF SYMBOL],
|
257
|
+
%w[ifCondition SYMBOL],
|
258
|
+
%w[statement SYMBOL],
|
259
|
+
%w[{ LEFT_BRACE],
|
260
|
+
%w[repeat KEY],
|
261
|
+
%w[1 INT_LIT],
|
262
|
+
%w[} RIGHT_BRACE],
|
263
|
+
%w[ELSE SYMBOL],
|
264
|
+
%w[statement SYMBOL]
|
271
265
|
]
|
272
266
|
|
273
267
|
subject.start_with(input)
|
@@ -280,21 +274,21 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
280
274
|
end
|
281
275
|
|
282
276
|
it 'should recognize a grouping with a repeat constraint' do
|
283
|
-
input =
|
277
|
+
input = 'IF ifCondition statement ( ELSE statement ){ repeat: 0..1 }'
|
284
278
|
expectations = [
|
285
|
-
[
|
286
|
-
[
|
287
|
-
[
|
288
|
-
[
|
289
|
-
[
|
290
|
-
[
|
291
|
-
[
|
292
|
-
[
|
293
|
-
[
|
294
|
-
[
|
295
|
-
[
|
296
|
-
[
|
297
|
-
[
|
279
|
+
%w[IF SYMBOL],
|
280
|
+
%w[ifCondition SYMBOL],
|
281
|
+
%w[statement SYMBOL],
|
282
|
+
%w[( LEFT_PAREN],
|
283
|
+
%w[ELSE SYMBOL],
|
284
|
+
%w[statement SYMBOL],
|
285
|
+
%w[) RIGHT_PAREN],
|
286
|
+
%w[{ LEFT_BRACE],
|
287
|
+
%w[repeat KEY],
|
288
|
+
%w[0 INT_LIT],
|
289
|
+
%w[.. ELLIPSIS],
|
290
|
+
%w[1 INT_LIT],
|
291
|
+
%w[} RIGHT_BRACE]
|
298
292
|
]
|
299
293
|
|
300
294
|
subject.start_with(input)
|
@@ -309,18 +303,18 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
309
303
|
it 'should recognize a combination of constraints' do
|
310
304
|
input = "IF ifCondition statement ELSE { repeat: 1, match_closest: 'IF' } statement"
|
311
305
|
expectations = [
|
312
|
-
[
|
313
|
-
[
|
314
|
-
[
|
315
|
-
[
|
316
|
-
[
|
317
|
-
[
|
318
|
-
[
|
319
|
-
[
|
320
|
-
[
|
321
|
-
[
|
322
|
-
[
|
323
|
-
[
|
306
|
+
%w[IF SYMBOL],
|
307
|
+
%w[ifCondition SYMBOL],
|
308
|
+
%w[statement SYMBOL],
|
309
|
+
%w[ELSE SYMBOL],
|
310
|
+
%w[{ LEFT_BRACE],
|
311
|
+
%w[repeat KEY],
|
312
|
+
%w[1 INT_LIT],
|
313
|
+
%w[, COMMA],
|
314
|
+
%w[match_closest KEY],
|
315
|
+
%w[IF STR_LIT],
|
316
|
+
%w[} RIGHT_BRACE],
|
317
|
+
%w[statement SYMBOL]
|
324
318
|
]
|
325
319
|
|
326
320
|
subject.start_with(input)
|
@@ -335,23 +329,23 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
335
329
|
it 'should recognize a grouping with a nested constraint' do
|
336
330
|
input = "IF ifCondition statement ( ELSE { match_closest: 'IF' } statement ){ repeat: 0..1 }"
|
337
331
|
expectations = [
|
338
|
-
[
|
339
|
-
[
|
340
|
-
[
|
341
|
-
[
|
342
|
-
[
|
343
|
-
[
|
344
|
-
[
|
345
|
-
[
|
346
|
-
[
|
347
|
-
[
|
348
|
-
[
|
349
|
-
[
|
350
|
-
[
|
351
|
-
[
|
352
|
-
[
|
353
|
-
[
|
354
|
-
[
|
332
|
+
%w[IF SYMBOL],
|
333
|
+
%w[ifCondition SYMBOL],
|
334
|
+
%w[statement SYMBOL],
|
335
|
+
%w[( LEFT_PAREN],
|
336
|
+
%w[ELSE SYMBOL],
|
337
|
+
%w[{ LEFT_BRACE],
|
338
|
+
%w[match_closest KEY],
|
339
|
+
%w[IF STR_LIT],
|
340
|
+
%w[} RIGHT_BRACE],
|
341
|
+
%w[statement SYMBOL],
|
342
|
+
%w[) RIGHT_PAREN],
|
343
|
+
%w[{ LEFT_BRACE],
|
344
|
+
%w[repeat KEY],
|
345
|
+
%w[0 INT_LIT],
|
346
|
+
%w[.. ELLIPSIS],
|
347
|
+
%w[1 INT_LIT],
|
348
|
+
%w[} RIGHT_BRACE]
|
355
349
|
]
|
356
350
|
|
357
351
|
subject.start_with(input)
|
@@ -19,15 +19,18 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
19
19
|
module Parser # Open this namespace to avoid module qualifier prefixes
|
20
20
|
describe GFGEarleyParser do
|
21
21
|
include ExpectationHelper # Mix-in with expectation on parse entry sets
|
22
|
-
|
22
|
+
|
23
|
+
# rubocop: disable Lint/ConstantDefinitionInBlock
|
24
|
+
|
23
25
|
Keyword = {
|
24
26
|
'else' => 'ELSE',
|
25
27
|
'false' => 'FALSE',
|
26
28
|
'if' => 'IF',
|
27
29
|
'then' => 'THEN',
|
28
30
|
'true' => 'TRUE'
|
29
|
-
}.freeze
|
30
|
-
|
31
|
+
}.freeze
|
32
|
+
# rubocop: enable Lint/ConstantDefinitionInBlock
|
33
|
+
|
31
34
|
def tokenizer(aTextToParse)
|
32
35
|
scanner = StringScanner.new(aTextToParse)
|
33
36
|
tokens = []
|
@@ -35,20 +38,21 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
35
38
|
loop do
|
36
39
|
scanner.skip(/\s+/)
|
37
40
|
break if scanner.eos?
|
38
|
-
|
39
|
-
|
41
|
+
|
42
|
+
curr_pos = scanner.pos
|
43
|
+
lexeme = scanner.scan(/\S+/)
|
40
44
|
|
41
45
|
term_name = Keyword[lexeme]
|
42
46
|
unless term_name
|
43
47
|
if lexeme =~ /\d+/
|
44
48
|
term_name = 'INTEGER'
|
45
|
-
else
|
49
|
+
else
|
46
50
|
err_msg = "Unknown token '#{lexeme}'"
|
47
51
|
raise StandardError, err_msg
|
48
52
|
end
|
49
53
|
end
|
50
54
|
pos = Rley::Lexical::Position.new(1, curr_pos + 1)
|
51
|
-
tokens << Rley::Lexical::Token.new(lexeme, term_name, pos)
|
55
|
+
tokens << Rley::Lexical::Token.new(lexeme, term_name, pos)
|
52
56
|
end
|
53
57
|
|
54
58
|
tokens
|
@@ -57,12 +61,12 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
57
61
|
let(:input) { 'if false then if true then 1 else 2' }
|
58
62
|
|
59
63
|
context 'Ambiguous parse: ' do
|
60
|
-
# Factory method. Creates a grammar builder for a simple grammar.
|
64
|
+
# Factory method. Creates a grammar builder for a simple grammar.
|
61
65
|
def grammar_if_else_amb
|
62
66
|
builder = Rley::Syntax::BaseGrammarBuilder.new do
|
63
67
|
add_terminals('IF', 'THEN', 'ELSE')
|
64
68
|
add_terminals('FALSE', 'TRUE', 'INTEGER')
|
65
|
-
|
69
|
+
|
66
70
|
rule 'program' => 'stmt'
|
67
71
|
rule 'stmt' => 'IF boolean THEN stmt'
|
68
72
|
rule 'stmt' => 'IF boolean THEN stmt ELSE stmt'
|
@@ -72,7 +76,7 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
72
76
|
rule 'boolean' => 'FALSE'
|
73
77
|
rule 'boolean' => 'TRUE'
|
74
78
|
end
|
75
|
-
|
79
|
+
|
76
80
|
builder.grammar
|
77
81
|
end
|
78
82
|
|
@@ -390,7 +394,7 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
390
394
|
'boolean => . TRUE | 8'
|
391
395
|
]
|
392
396
|
result8 = parse_result.chart[8]
|
393
|
-
found = parse_result.chart.search_entries(4, {before: 'IF'})
|
397
|
+
# found = parse_result.chart.search_entries(4, { before: 'IF' })
|
394
398
|
expect(result8.entries.size).to eq(11)
|
395
399
|
compare_entry_texts(result8, expected)
|
396
400
|
expected_terminals(result8, %w[FALSE IF INTEGER TRUE])
|
@@ -441,5 +445,3 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
441
445
|
end # describe
|
442
446
|
end # module
|
443
447
|
end # module
|
444
|
-
|
445
|
-
|
@@ -22,6 +22,7 @@ require_relative '../support/expectation_helper'
|
|
22
22
|
require_relative '../../../lib/rley/parser/gfg_earley_parser'
|
23
23
|
|
24
24
|
module Rley # Open this namespace to avoid module qualifier prefixes
|
25
|
+
# rubocop: disable Metrics/BlockLength
|
25
26
|
module Parser # Open this namespace to avoid module qualifier prefixes
|
26
27
|
describe GFGEarleyParser do
|
27
28
|
include GrammarABCHelper # Mix-in module with builder for grammar abc
|
@@ -302,7 +303,7 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
302
303
|
'sequence => . sequence comma integer | 0', # start rule
|
303
304
|
'sequence => . integer | 0', # start rule
|
304
305
|
'.integer | 0', # call rule
|
305
|
-
'integer => . digit_plus | 0'
|
306
|
+
'integer => . digit_plus | 0', # start rule
|
306
307
|
'.digit_plus | 0', # call rule
|
307
308
|
'digit_plus => . digit_plus digit | 0', # start rule (generated)
|
308
309
|
'digit_plus => . digit | 0' # start rule (generated)
|
@@ -314,7 +315,7 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
314
315
|
expected = [
|
315
316
|
'digit_plus => digit . | 0', # Scan
|
316
317
|
'digit_plus. | 0', # exit rule
|
317
|
-
'integer => digit_plus . | 0'
|
318
|
+
'integer => digit_plus . | 0', # end rule
|
318
319
|
'digit_plus => digit_plus . digit | 0', # rule (generated)
|
319
320
|
'integer. | 0', # exit rule
|
320
321
|
'sequence => integer . | 0', # end rule
|
@@ -329,8 +330,8 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
329
330
|
# Expectation chart[2]:
|
330
331
|
expected = [
|
331
332
|
'sequence => sequence comma . integer | 0', # Scan
|
332
|
-
'.integer | 2',
|
333
|
-
'integer => . digit_plus | 2'
|
333
|
+
'.integer | 2', # call rule
|
334
|
+
'integer => . digit_plus | 2', # start rule
|
334
335
|
'.digit_plus | 2', # call rule
|
335
336
|
'digit_plus => . digit_plus digit | 2', # start rule (generated)
|
336
337
|
'digit_plus => . digit | 2' # start rule (generated)
|
@@ -342,13 +343,13 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
342
343
|
expected = [
|
343
344
|
'digit_plus => digit . | 2', # Scan
|
344
345
|
'digit_plus. | 2', # exit rule
|
345
|
-
'integer => digit_plus . | 2'
|
346
|
+
'integer => digit_plus . | 2', # end rule
|
346
347
|
'digit_plus => digit_plus . digit | 2', # rule (generated)
|
347
348
|
'integer. | 2', # exit rule
|
348
349
|
'sequence => sequence comma integer . | 0', # rule
|
349
|
-
'sequence. | 0',
|
350
|
+
'sequence. | 0', # exit rule
|
350
351
|
'S => sequence . | 0', # end rule
|
351
|
-
'sequence => sequence . comma integer | 0'
|
352
|
+
'sequence => sequence . comma integer | 0' # rule
|
352
353
|
]
|
353
354
|
compare_entry_texts(parse_result.chart[3], expected)
|
354
355
|
|
@@ -357,12 +358,12 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
357
358
|
expected = [
|
358
359
|
'digit_plus => digit_plus digit . | 2', # Scan
|
359
360
|
'digit_plus. | 2', # exit rule
|
360
|
-
'integer => digit_plus . | 2'
|
361
|
+
'integer => digit_plus . | 2', # end rule
|
361
362
|
'digit_plus => digit_plus . digit | 2', #
|
362
363
|
'integer. | 2', # exit rule
|
363
364
|
'sequence => sequence comma integer . | 0', # rule
|
364
365
|
'sequence. | 0', # exit rule
|
365
|
-
'S => sequence . | 0'
|
366
|
+
'S => sequence . | 0' # end rule
|
366
367
|
]
|
367
368
|
compare_entry_texts(parse_result.chart[4], expected)
|
368
369
|
end
|
@@ -1040,5 +1041,6 @@ MSG
|
|
1040
1041
|
end # context
|
1041
1042
|
end # describe
|
1042
1043
|
end # module
|
1044
|
+
# rubocop: enable Metrics/BlockLength
|
1043
1045
|
end # module
|
1044
1046
|
# End of file
|