enolib 0.7.0 → 0.7.2

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 (3) hide show
  1. checksums.yaml +4 -4
  2. data/lib/enolib/parser.rb +69 -76
  3. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 89fe9af4b84d3d1ee96f31944f7033f6bcb1662f89b649922e09cb469131575e
4
- data.tar.gz: 80ae58d7bc69a97f80245ba0f29e24590fbe2d578bd4a1b673b60f8598f29eb8
3
+ metadata.gz: 88751440ddeb55fc6358a9ad2cafa998f3395787b475f3c42e1701c0ef17293c
4
+ data.tar.gz: e61d935cf566395b4787f424930fb84fcfdd5b879254c35c6dc452f15963c187
5
5
  SHA512:
6
- metadata.gz: 225c429cb9734ad04b34c73ff523bf07cb94c9af9a153fb729349ca3b2aead904a93d17f48c8e23ee71e375b21beae9df7188ff5256f4ea06fbe621899395b97
7
- data.tar.gz: f7381ea648ed461ee0dc263cfb4dacfe3117464f74d9064b0485b3b0f13da918126699749e4a501f20c55634d6b6d926cdb685f1334f685cb6a9a62fd00b19a1
6
+ metadata.gz: a23ff5f077a95e19a302c24658f9f0324a4f7a335fffb53018a4f1a1f9f4fa849ce0ae046c279e49445d85175f7ea82b7d118380a0b1ff98d9aaa646510785b1
7
+ data.tar.gz: 228ff010c1724b9db258c8989fa47678b78ad34af528d0ee42c788a3d302e0f6e390abc6723c0bf2cc890775114df0d04a4530cddd6c81521f83208a6f10dbfc
@@ -26,7 +26,7 @@ module Enolib
26
26
  match = Grammar::REGEX.match(@context.input, @index)
27
27
 
28
28
  unless match && match.begin(0) == @index
29
- instruction = tokenize_error_context
29
+ instruction = parse_after_error
30
30
  raise Errors::Parsing.invalid_line(@context, instruction)
31
31
  end
32
32
 
@@ -40,10 +40,11 @@ module Enolib
40
40
 
41
41
  multiline_field = false
42
42
 
43
+ # TODO: In all implementations we could optimize the often occurring
44
+ # empty line case - we need not allocate the instruction object
45
+ # because it is discarded anyway
43
46
  if match[Grammar::EMPTY_LINE_INDEX]
44
47
 
45
- instruction[:type] = :empty_line
46
-
47
48
  if comments
48
49
  @context.meta.concat(comments)
49
50
  comments = nil
@@ -102,7 +103,7 @@ module Enolib
102
103
  end
103
104
 
104
105
  if !last_non_section_element
105
- instruction = tokenize_error_context
106
+ parse_after_error(instruction)
106
107
  raise Errors::Parsing.missing_list_for_list_item(@context, instruction)
107
108
  elsif last_non_section_element[:type] == :list
108
109
  last_non_section_element[:items].push(instruction)
@@ -110,7 +111,7 @@ module Enolib
110
111
  last_non_section_element[:items] = [instruction]
111
112
  last_non_section_element[:type] = :list
112
113
  else
113
- instruction = tokenize_error_context
114
+ parse_after_error(instruction)
114
115
  raise Errors::Parsing.missing_list_for_list_item(@context, instruction)
115
116
  end
116
117
 
@@ -147,7 +148,7 @@ module Enolib
147
148
  end
148
149
 
149
150
  if !last_non_section_element
150
- instruction = tokenize_error_context
151
+ parse_after_error(instruction)
151
152
  raise Errors::Parsing.missing_fieldset_for_fieldset_entry(@context, instruction)
152
153
  elsif last_non_section_element[:type] == :fieldset
153
154
  last_non_section_element[:entries].push(instruction)
@@ -155,7 +156,7 @@ module Enolib
155
156
  last_non_section_element[:entries] = [instruction]
156
157
  last_non_section_element[:type] = :fieldset
157
158
  else
158
- instruction = tokenize_error_context
159
+ parse_after_error(instruction)
159
160
  raise Errors::Parsing.missing_fieldset_for_fieldset_entry(@context, instruction)
160
161
  end
161
162
 
@@ -164,11 +165,6 @@ module Enolib
164
165
 
165
166
  elsif match[Grammar::SPACED_LINE_CONTINUATION_OPERATOR_INDEX]
166
167
 
167
- unless last_continuable_element
168
- instruction = tokenize_error_context
169
- raise Errors::Parsing.missing_element_for_continuation(@context, instruction)
170
- end
171
-
172
168
  instruction[:spaced] = true
173
169
  instruction[:ranges][:spaced_line_continuation_operator] = match.offset(Grammar::SPACED_LINE_CONTINUATION_OPERATOR_INDEX)
174
170
  instruction[:type] = :continuation
@@ -180,6 +176,11 @@ module Enolib
180
176
  instruction[:value] = value
181
177
  end
182
178
 
179
+ unless last_continuable_element
180
+ parse_after_error(instruction)
181
+ raise Errors::Parsing.missing_element_for_continuation(@context, instruction)
182
+ end
183
+
183
184
  if last_continuable_element.has_key?(:continuations)
184
185
  last_continuable_element[:continuations].push(instruction)
185
186
  else
@@ -197,11 +198,6 @@ module Enolib
197
198
 
198
199
  elsif match[Grammar::DIRECT_LINE_CONTINUATION_OPERATOR_INDEX]
199
200
 
200
- unless last_continuable_element
201
- instruction = tokenize_error_context
202
- raise Errors::Parsing.missing_element_for_continuation(@context, instruction)
203
- end
204
-
205
201
  instruction[:ranges][:direct_line_continuation_operator] = match.offset(Grammar::DIRECT_LINE_CONTINUATION_OPERATOR_INDEX)
206
202
  instruction[:type] = :continuation
207
203
 
@@ -212,6 +208,11 @@ module Enolib
212
208
  instruction[:value] = value
213
209
  end
214
210
 
211
+ unless last_continuable_element
212
+ parse_after_error(instruction)
213
+ raise Errors::Parsing.missing_element_for_continuation(@context, instruction)
214
+ end
215
+
215
216
  if last_continuable_element.has_key?(:continuations)
216
217
  last_continuable_element[:continuations].push(instruction)
217
218
  else
@@ -238,28 +239,6 @@ module Enolib
238
239
  instruction[:ranges][:section_operator] = match.offset(Grammar::SECTION_OPERATOR_INDEX)
239
240
  instruction[:type] = :section
240
241
 
241
- new_depth = instruction[:ranges][:section_operator][1] - instruction[:ranges][:section_operator][0]
242
-
243
- if new_depth == @depth + 1
244
- instruction[:parent] = last_section
245
- @depth = new_depth
246
- elsif new_depth == @depth
247
- instruction[:parent] = last_section[:parent]
248
- elsif new_depth < @depth
249
- while new_depth < @depth
250
- last_section = last_section[:parent]
251
- @depth -= 1
252
- end
253
-
254
- instruction[:parent] = last_section[:parent]
255
- else
256
- instruction = tokenize_error_context
257
- raise Errors::Parsing.section_hierarchy_layer_skip(@context, instruction, last_section)
258
- end
259
-
260
- instruction[:parent][:elements].push(instruction)
261
- last_section = instruction
262
-
263
242
  instruction[:key] = match[Grammar::SECTION_KEY_UNESCAPED_INDEX]
264
243
 
265
244
  if instruction[:key]
@@ -277,12 +256,6 @@ module Enolib
277
256
  instruction[:ranges][:template] = match.offset(Grammar::SECTION_TEMPLATE_INDEX)
278
257
  instruction[:template] = template
279
258
 
280
- parent = instruction[:parent]
281
- while parent[:type] != :document
282
- parent[:deep_resolve] = true
283
- parent = parent[:parent]
284
- end
285
-
286
259
  copy_operator_offset = match.offset(Grammar::SECTION_COPY_OPERATOR_INDEX)
287
260
 
288
261
  if copy_operator_offset[1] - copy_operator_offset[0] == 2
@@ -301,6 +274,36 @@ module Enolib
301
274
  instruction[:copy] = @unresolved_sections[template]
302
275
  end
303
276
 
277
+ new_depth = instruction[:ranges][:section_operator][1] - instruction[:ranges][:section_operator][0]
278
+
279
+ if new_depth == @depth + 1
280
+ instruction[:parent] = last_section
281
+ @depth = new_depth
282
+ elsif new_depth == @depth
283
+ instruction[:parent] = last_section[:parent]
284
+ elsif new_depth < @depth
285
+ while new_depth < @depth
286
+ last_section = last_section[:parent]
287
+ @depth -= 1
288
+ end
289
+
290
+ instruction[:parent] = last_section[:parent]
291
+ else
292
+ parse_after_error(instruction)
293
+ raise Errors::Parsing.section_hierarchy_layer_skip(@context, instruction, last_section)
294
+ end
295
+
296
+ instruction[:parent][:elements].push(instruction)
297
+
298
+ if template
299
+ parent = instruction[:parent]
300
+ while parent[:type] != :document
301
+ parent[:deep_resolve] = true
302
+ parent = parent[:parent]
303
+ end
304
+ end
305
+
306
+ last_section = instruction
304
307
  last_continuable_element = nil
305
308
  last_non_section_element = nil
306
309
 
@@ -333,7 +336,7 @@ module Enolib
333
336
  @line += 1
334
337
 
335
338
  unless terminator_match
336
- tokenize_error_context
339
+ parse_after_error
337
340
  raise Errors::Parsing.unterminated_multiline_field(@context, instruction)
338
341
  end
339
342
 
@@ -659,42 +662,32 @@ module Enolib
659
662
  end
660
663
  end
661
664
 
662
- def tokenize_error_context
663
- first_instruction = nil
664
-
665
- loop do
666
- end_of_line_index = @context.input.index("\n", @index)
667
-
668
- if end_of_line_index
669
- instruction = {
670
- line: @line,
671
- ranges: { line: [@index, end_of_line_index] }
672
- }
665
+ def parse_after_error(error_instruction = nil)
666
+ if error_instruction
667
+ @context.meta.push(error_instruction)
668
+ @index = error_instruction[:ranges][:line][RANGE_END]
669
+ @line += 1
670
+ end
673
671
 
674
- @context.meta.push(instruction)
672
+ while @index < @context.input.length
673
+ end_of_line_index = @context.input.index("\n", @index) || @context.input.length
675
674
 
676
- if first_instruction
677
- instruction[:type] = :unparsed
678
- else
679
- first_instruction = instruction
680
- end
675
+ instruction = {
676
+ line: @line,
677
+ ranges: { line: [@index, end_of_line_index] },
678
+ type: :unparsed
679
+ }
681
680
 
682
- @index = end_of_line_index + 1
683
- @line += 1
684
- else
685
- instruction = {
686
- line: @line,
687
- ranges: { line: [@index, @context.input.length] }
688
- }
681
+ error_instruction ||= instruction
689
682
 
690
- instruction[:type] = :unparsed if first_instruction
683
+ @context.meta.push(instruction)
684
+ @index = end_of_line_index + 1
685
+ @line += 1
686
+ end
691
687
 
692
- @context.line_count = @line + 1
693
- @context.meta.push(instruction)
688
+ @context.line_count = @context.input[-1] == "\n" ? @line + 1 : @line
694
689
 
695
- return first_instruction || instruction
696
- end
697
- end
690
+ error_instruction
698
691
  end
699
692
  end
700
693
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: enolib
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0
4
+ version: 0.7.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Simon Repp
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-06-11 00:00:00.000000000 Z
11
+ date: 2019-06-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: deep-cover