Class: Kotoshu::Grammar::PatternMatchers::DoubleNegativeMatcher

Inherits:
BaseMatcher
  • Object
show all
Defined in:
lib/kotoshu/grammar/pattern_matchers/double_negative_matcher.rb

Overview

Matcher for double negative rules.

This matcher detects when multiple negative words appear within a certain distance.

Instance Method Summary collapse

Methods inherited from BaseMatcher

#initialize

Constructor Details

This class inherits a constructor from Kotoshu::Grammar::PatternMatchers::BaseMatcher

Instance Method Details

#match(tokens, rule) ⇒ Array<Hash>

Match tokens against the double negative pattern.

Parameters:

  • tokens (Array<Hash>)

    Array of token hashes

  • rule (Rule)

    The rule being checked

Returns:

  • (Array<Hash>)

    Array of error hashes



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/kotoshu/grammar/pattern_matchers/double_negative_matcher.rb', line 18

def match(tokens, rule)
  errors = []
  exceptions = rule.exceptions || {}
  exception_phrases = exceptions['phrases'] || []

  conditions = @pattern['conditions'] || []
  distance_condition = conditions.find { |c| c['type'] == 'distance_check' }
  max_distance = distance_condition&.dig('max_distance') || 15

  negative_indices = []
  tokens.each_with_index do |token, idx|
    word = token[:token]&.downcase
    next unless is_negative?(word)

    # Skip "not only... but also" pattern
    next if in_exception_phrase?(idx, tokens, exception_phrases)

    negative_indices << idx
  end

  negative_indices.each_cons(2) do |idx1, idx2|
    pos1 = tokens[idx1][:position]
    pos2 = tokens[idx2][:position]
    distance = pos2 - pos1
    next if distance > max_distance

    error = build_error(tokens, idx1, idx2, rule)
    errors << error if error
  end
  errors
end