Class: StringToNumber::Parser

Inherits:
Object
  • Object
show all
Defined in:
lib/string_to_number/parser.rb

Overview

High-performance French text to number parser

This class provides a clean, optimized implementation that maintains compatibility with the original algorithm while adding significant performance improvements through caching and memoization.

Examples:

Basic usage

parser = StringToNumber::Parser.new
parser.parse('vingt et un')  #=> 21
parser.parse('trois millions') #=> 3_000_000

Class method usage

StringToNumber::Parser.convert('mille deux cent') #=> 1200

Constant Summary collapse

WORD_VALUES =

Import the proven data structures from the original implementation

StringToNumber::ToNumber::EXCEPTIONS.freeze
MULTIPLIERS =
StringToNumber::ToNumber::POWERS_OF_TEN.freeze
MULTIPLIER_KEYS =

Pre-compiled regex patterns for optimal performance

MULTIPLIERS.keys
.reject { |k| %w[un dix].include?(k) }
.sort_by(&:length).reverse.freeze
MULTIPLIER_PATTERN =
/(?<f>.*?)\s?(?<m>#{MULTIPLIER_KEYS.join('|')})/.freeze
QUATRE_VINGT_PATTERN =
/(?<base>quatre[-\s]vingt(?:s?)(?:[-\s]dix)?)(?:[-\s]?)(?<suffix>\w*)/.freeze

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(text = '') ⇒ Parser

Initialize parser with normalized text



106
107
108
# File 'lib/string_to_number/parser.rb', line 106

def initialize(text = '')
  @normalized_text = self.class.send(:normalize_text, text)
end

Class Method Details

.cache_statsObject

Get cache statistics



84
85
86
87
88
89
90
91
92
# File 'lib/string_to_number/parser.rb', line 84

def cache_stats
  @cache_mutex.synchronize do
    {
      conversion_cache_size: @cache.size,
      conversion_cache_limit: MAX_CACHE_SIZE,
      cache_hit_ratio: @cache_lookups.zero? ? 0.0 : @cache_hits.to_f / @cache_lookups
    }
  end
end

.clear_caches!Object

Clear all caches



75
76
77
78
79
80
81
# File 'lib/string_to_number/parser.rb', line 75

def clear_caches!
  @cache_mutex.synchronize do
    @cache.clear
    @cache_hits = 0
    @cache_lookups = 0
  end
end

.convert(text) ⇒ Integer

Convert French text to number using cached parser instance

Parameters:

  • text (String)

    French number text to convert

Returns:

  • (Integer)

    The numeric value

Raises:

  • (ArgumentError)

    if text is not a string



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/string_to_number/parser.rb', line 46

def convert(text)
  validate_input!(text)

  normalized = normalize_text(text)
  return 0 if normalized.empty?

  @cache_mutex.synchronize do
    @cache_lookups += 1

    if @cache.key?(normalized)
      @cache_hits += 1
      # Delete and reinsert to move to end (most recently used)
      value = @cache.delete(normalized)
      @cache[normalized] = value
      return value
    end
  end

  result = new(normalized).parse_optimized(normalized)

  @cache_mutex.synchronize do
    @cache.delete(@cache.first[0]) if @cache.size >= MAX_CACHE_SIZE
    @cache[normalized] = result
  end

  result
end

Instance Method Details

#parseObject

Parse the text to numeric value



111
112
113
# File 'lib/string_to_number/parser.rb', line 111

def parse
  self.class.convert(@normalized_text)
end

#parse_optimized(text) ⇒ Object

Internal optimized parsing method using the original proven algorithm but with performance optimizations



117
118
119
120
121
122
123
124
125
# File 'lib/string_to_number/parser.rb', line 117

def parse_optimized(text)
  return 0 if text.nil? || text.empty?

  # Direct lookup (fastest path)
  return WORD_VALUES[text] if WORD_VALUES.key?(text)

  # Use the proven extraction algorithm from the original implementation
  extract_optimized(text)
end