parsanol 1.3.31 → 1.3.32

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: a0f92de331fd22d7ee25390a26c2afc2c7a2a5e691e026b26c64d581883ac15c
4
- data.tar.gz: ba5ed64012b20eae02d04a1479510b64e37a0207514516d108ca7b07864e505f
3
+ metadata.gz: 41651c6d4901c45b1b2d8973eb221d28ea31412a832a88a6c24e6e765bd7617e
4
+ data.tar.gz: 92260b260487280d55c561e49ef9342ce2a752bd12ead9dd3cedca190f260946
5
5
  SHA512:
6
- metadata.gz: dda812680de7dcaab74a4a83042d337f4be96a921c5981e73430092d6d5dc658c9caa899baf8caee3214e0ce072f98daca8873a9f0b77b8db2cffc3c6888149c
7
- data.tar.gz: 867a6b04c745d2d573986e6081deb7f4ae12ad3b922203ad7d8cb7cab06962380b332fc1af68ec7582053e372b114577bb674d9da3f3b11df212091c472ddf02
6
+ metadata.gz: d47ce37751cc457c2e0f878fed50c3b0d337cf663843f821b1aeb792325371862f951f4b3b324983408def926959bd7487ff0c3879b3603a93f8c5fc8a806d94
7
+ data.tar.gz: bd256709d110df1092d60ef05939c9d8a2d3fe6db6714987eb60ad67ce47407c1f9b37701245f5745e940d712cdbff766ae3f7dfe11bc72764f0e1f08fdcf3c4
@@ -1,6 +1,18 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "mkmf"
4
+
5
+ # The Rust extension only builds against MRI's C API. Other engines
6
+ # (TruffleRuby, JRuby) resolve the ruby-platform gem and must install
7
+ # cleanly on the pure-Ruby backend instead of failing the whole install
8
+ # (parsanol-ruby#23). An explicit opt-out works on MRI too.
9
+ if RUBY_ENGINE != "ruby" || ENV["PARSANOL_NATIVE"] == "0"
10
+ File.write("Makefile", dummy_makefile("").to_s)
11
+ warn "parsanol: skipping the Rust extension on #{RUBY_ENGINE} " \
12
+ "(pure-Ruby backend will be used)"
13
+ exit 0
14
+ end
15
+
4
16
  require "rb_sys/mkmf"
5
17
 
6
18
  create_rust_makefile("parsanol/parsanol_native") do |r|
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Parsanol
4
- VERSION = "1.3.31"
4
+ VERSION = "1.3.32"
5
5
  end
data/lib/parsanol.rb CHANGED
@@ -129,10 +129,60 @@ module Parsanol
129
129
  def match(pattern = nil)
130
130
  return CharacterClassBuilder.new unless pattern
131
131
 
132
+ match_quantifier_warning(pattern)
132
133
  Atoms::Re.new(pattern)
133
134
  end
134
135
  module_function :match
135
136
 
137
+ # `match` consumes exactly one character (Parslet parity), so a regex
138
+ # quantifier is silently truncated: match(/[0-9]+/) matches a single
139
+ # digit. Warn once per offending pattern — the intended spelling is
140
+ # `match("[0-9]").repeat(1)`.
141
+ # Deliberately mutable: it accumulates warned patterns per process.
142
+ QUANTIFIER_WARNED = {} # rubocop:disable Style/MutableConstant
143
+ private_constant :QUANTIFIER_WARNED
144
+
145
+ def match_quantifier_warning(pattern)
146
+ return if QUANTIFIER_WARNED.key?(pattern)
147
+ return unless pattern.is_a?(String)
148
+ return unless quantified_pattern?(pattern)
149
+
150
+ QUANTIFIER_WARNED[pattern] = true
151
+ warn "Parsanol: match(#{pattern.inspect}) matches exactly one character " \
152
+ "(Parslet parity); the quantifier is ignored. " \
153
+ "Use match(...).repeat(1) to match repeatedly."
154
+ end
155
+ module_function :match_quantifier_warning
156
+
157
+ # True when the pattern carries a top-level quantifier (+, *, ?, or
158
+ # {n,m}) outside a character class.
159
+ def quantified_pattern?(pattern)
160
+ in_class = false
161
+ escaped = false
162
+ previous = nil
163
+
164
+ pattern.each_char.with_index do |ch, idx|
165
+ if escaped
166
+ escaped = false
167
+ elsif ch == "\\"
168
+ escaped = true
169
+ elsif in_class
170
+ in_class = false if ch == "]"
171
+ elsif ch == "["
172
+ in_class = true
173
+ elsif %w[+ * ?].include?(ch) || (ch == "{" && idx + 1 < pattern.length && pattern[idx + 1] =~ /\d/)
174
+ # A leading quantifier applies to nothing and cannot truncate a
175
+ # character match; any other quantifier does.
176
+ return true if idx.positive? && !previous.nil? && previous != "("
177
+ end
178
+
179
+ previous = ch
180
+ end
181
+
182
+ false
183
+ end
184
+ module_function :quantified_pattern?
185
+
136
186
  # Creates a literal string matcher.
137
187
  #
138
188
  # @param literal [String] the string to match
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: parsanol
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.31
4
+ version: 1.3.32
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.