parsanol 1.3.8-aarch64-linux → 1.3.10-aarch64-linux

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 11fa862698ade99f509fc95b23031680cbe951a0a16cde95d0e1766108741479
4
- data.tar.gz: 0e32431822dc551ea6ed7b6f4642c64481ffb9b61c011e870007d5212fc52d47
3
+ metadata.gz: 69ee119824b358519e2833e4d77b3c58a8921e4dede01700148c95024e17b5a2
4
+ data.tar.gz: 46fd8493a20d6277510345bb5c692bfcc7e9227ad8ce3b934d788d9bb120db3a
5
5
  SHA512:
6
- metadata.gz: 3a2ceb99dc545d14fa8d84aad4913aa72354365a81af405b446af665c5a3d6605f52916b902bfd2b68f201a6089816a022e826c5226cd313c4b387913c89bb31
7
- data.tar.gz: bc39f6141c521d4212224306f5bca82adaf83a78123890a99d20f1830b7ce47179622a90d29ab7b7982b94990f22d62bb79c6ff1bff240f5b82761d3584f4911
6
+ metadata.gz: 253408a7fc6923ff834c46c6dcd80466b1b1bc6a354d1b0d5cf895250d0b84552687b14d0405c95ea1501d5aca88aa6a1ac4d5e7cded56118e352875050566a9
7
+ data.tar.gz: 41938dced4ae4395a1cdb71aed258c7c209eb8173b912e84869887ffce83e37950e01a576eaebef21caf62f920d2139240a129cb31b1fa39f84315b12f7a190a
Binary file
Binary file
Binary file
@@ -115,7 +115,7 @@ module Parsanol
115
115
  # Convert to JSON for native parser
116
116
  #
117
117
  # @return [String] JSON representation
118
- def to_json(*_args)
118
+ def to_json(*)
119
119
  build.to_json
120
120
  end
121
121
 
@@ -57,9 +57,8 @@ module Parsanol
57
57
  # pre-decoded Ruby value from _parse_raw
58
58
  # @param input [String] Original input string (for Slice references)
59
59
  # @param slice_class [Class] The Slice class to use
60
- # @param grammar_atom [Parsanol::Atoms::Base] The grammar atom (unused, kept for API compat)
61
60
  # @return [Object] Transformed Ruby AST
62
- def decode_and_flatten(data, input, slice_class, _grammar_atom)
61
+ def decode_and_flatten(data, input, slice_class)
63
62
  # Check if data is batch data (flat u64 array) or already a Ruby value
64
63
  if data.is_a?(Integer) || (data.is_a?(Array) && data.first.is_a?(Integer))
65
64
  # Batch data (flat u64 array) - decode first, then transform
@@ -323,9 +323,26 @@ module Parsanol
323
323
  all_items_are_hashes = non_hash_items.empty?
324
324
 
325
325
  if all_items_are_hashes
326
- # Merge all inner hashes into merged_hash
327
- item.each do |sub_item|
328
- merged_hash.merge!(sub_item) if sub_item.is_a?(Hash)
326
+ # Check if merging would overwrite existing keys in merged_hash.
327
+ # If so, this is a repetition pattern (item >> (sep >> item).repeat)
328
+ # and should be kept as array, not merged.
329
+ # Example: merged_hash={namedTypeOrRename: A}, array=[{namedTypeOrRename: B}]
330
+ # → should produce [{namedTypeOrRename: A}, {namedTypeOrRename: B}]
331
+ existing_keys = merged_hash.keys
332
+ shares_keys = item.any? do |sub_item|
333
+ sub_item.is_a?(Hash) && sub_item.keys.intersect?(existing_keys)
334
+ end
335
+
336
+ if shares_keys
337
+ has_non_empty_array = true
338
+ item.each do |sub_item|
339
+ hash_count += 1 if sub_item.is_a?(Hash)
340
+ end
341
+ total_items += 1
342
+ else
343
+ item.each do |sub_item|
344
+ merged_hash.merge!(sub_item) if sub_item.is_a?(Hash)
345
+ end
329
346
  end
330
347
  else
331
348
  # Non-empty repetition with non-hash items - mark that we should keep as array
@@ -25,18 +25,5 @@ module Parsanol
25
25
  EMPTY_ARRAY = [].freeze
26
26
  EMPTY_HASH = {}.freeze
27
27
  end
28
-
29
- # Symbol cache to avoid repeated string-to-symbol conversions
30
- # This is a class variable to share across all transformations
31
- @@symbol_cache = {}
32
-
33
- # Convert string key to symbol with caching
34
- # @param key [String, Symbol] The key to convert
35
- # @return [Symbol] The symbol version of the key
36
- def self.cached_symbol(key)
37
- return key if key.is_a?(Symbol)
38
-
39
- @@symbol_cache[key] ||= key.to_sym
40
- end
41
28
  end
42
29
  end
@@ -10,8 +10,6 @@ require "parsanol/native/batch_decoder"
10
10
 
11
11
  module Parsanol
12
12
  module Native
13
- VERSION = "0.1.0"
14
-
15
13
  class << self
16
14
  # Check if native extension is available
17
15
  def available?
@@ -41,20 +39,38 @@ module Parsanol
41
39
  raise LoadError, "Native parser not available" unless available?
42
40
 
43
41
  # Handle both grammar atoms and pre-serialized JSON strings
44
- if grammar.is_a?(String)
45
- grammar_json = grammar
46
- grammar_atom = nil
47
- else
48
- grammar_json = Parser.serialize_grammar(grammar)
49
- grammar_atom = grammar
50
- end
42
+ grammar_json = if grammar.is_a?(String)
43
+ grammar
44
+ else
45
+ Parser.serialize_grammar(grammar)
46
+ end
51
47
 
52
48
  # Use _parse_raw which returns properly tagged Ruby arrays via transform_ast.
53
49
  # The batch format doesn't preserve :repetition/:sequence tags, so we use
54
50
  # the direct FFI path. Apply the Ruby transformer to handle tags correctly.
55
51
  raw_ast = _parse_raw(grammar_json, input)
56
- BatchDecoder.decode_and_flatten(raw_ast, input, Parsanol::Slice,
57
- grammar_atom)
52
+ BatchDecoder.decode_and_flatten(raw_ast, input, Parsanol::Slice)
53
+ end
54
+
55
+ # Memory-bounded parsing without packrat cache.
56
+ #
57
+ # This creates a fresh arena and empty cache per call, bounding memory
58
+ # to AST size rather than input × atoms. Use for large files.
59
+ #
60
+ # @param grammar [Parsanol::Atoms::Base] Ruby grammar definition
61
+ # @param input [String] Input string to parse
62
+ # @return [Hash, Array, Parsanol::Slice] Transformed AST
63
+ def parse_fresh(grammar, input)
64
+ raise LoadError, "Native parser not available" unless available?
65
+
66
+ grammar_json = if grammar.is_a?(String)
67
+ grammar
68
+ else
69
+ Parser.serialize_grammar(grammar)
70
+ end
71
+
72
+ raw_ast = _parse_fresh_raw(grammar_json, input)
73
+ BatchDecoder.decode_and_flatten(raw_ast, input, Parsanol::Slice)
58
74
  end
59
75
 
60
76
  # Parse and return RAW AST without transformation.
@@ -166,13 +182,6 @@ module Parsanol
166
182
  end
167
183
  stats
168
184
  end
169
-
170
- private
171
-
172
- # Get the Slice class
173
- def get_slice_class
174
- Parsanol::Slice
175
- end
176
185
  end
177
186
  end
178
187
  end
@@ -89,11 +89,10 @@ module Parsanol
89
89
  # Parse input and return direct Ruby objects (no serialization)
90
90
  #
91
91
  # @param input [String] The input string to parse
92
- # @param options [Hash] Parse options (ignored for zero-copy)
93
92
  # @return [Object] Direct Ruby object (type depends on grammar)
94
93
  # @raise [LoadError] If native extension not available
95
94
  # @raise [Parsanol::ParseFailed] If parsing fails
96
- def parse(input, _options = {})
95
+ def parse(input)
97
96
  unless Parsanol::Native.available?
98
97
  raise LoadError,
99
98
  "ZeroCopy mode requires native extension for direct FFI object construction. " \
@@ -67,6 +67,10 @@ module Parsanol
67
67
 
68
68
  alias length size
69
69
 
70
+ def empty?
71
+ content.empty?
72
+ end
73
+
70
74
  def +(other)
71
75
  self.class.new(@byte_position, content + other.to_s, @input)
72
76
  end
@@ -110,7 +114,7 @@ module Parsanol
110
114
  as_json.to_json(*)
111
115
  end
112
116
 
113
- def as_json(_options = {})
117
+ def as_json
114
118
  result = { "value" => content, "offset" => offset, "length" => length }
115
119
  if @input
116
120
  line, column = line_and_column
@@ -97,13 +97,6 @@ module Parsanol
97
97
  return hi if hi <= lo
98
98
  end
99
99
  end
100
-
101
- # Legacy method name for backward compatibility
102
- alias find_mid midpoint_index
103
- alias lbound lower_bound_index
104
100
  end
105
-
106
- # Legacy constant name for backward compatibility
107
- RangeSearch = IntervalLookup
108
101
  end
109
102
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Parsanol
4
- VERSION = "1.3.8"
4
+ VERSION = "1.3.10"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: parsanol
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.8
4
+ version: 1.3.10
5
5
  platform: aarch64-linux
6
6
  authors:
7
7
  - Ribose Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-03-26 00:00:00.000000000 Z
11
+ date: 2026-04-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -151,7 +151,6 @@ files:
151
151
  - README.adoc
152
152
  - Rakefile
153
153
  - lib/parsanol.rb
154
- - lib/parsanol/3.2/parsanol_native.so
155
154
  - lib/parsanol/3.3/parsanol_native.so
156
155
  - lib/parsanol/3.4/parsanol_native.so
157
156
  - lib/parsanol/4.0/parsanol_native.so
@@ -262,7 +261,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
262
261
  requirements:
263
262
  - - ">="
264
263
  - !ruby/object:Gem::Version
265
- version: '3.2'
264
+ version: '3.3'
266
265
  - - "<"
267
266
  - !ruby/object:Gem::Version
268
267
  version: 4.1.dev
Binary file