Class: Kotoshu::Grammar::PatternMatchers::DoubleNegativeMatcher
- Inherits:
-
BaseMatcher
- Object
- BaseMatcher
- Kotoshu::Grammar::PatternMatchers::DoubleNegativeMatcher
- Defined in:
- lib/kotoshu/grammar/pattern_matchers/double_negative_matcher.rb
Overview
Matcher for double negative rules.
Detects when multiple negative words appear within a certain distance, with support for declared exception phrases. The canonical exception is the "not only...but also" correlative conjunction: both "not" and "also" are flagged as negatives, but the construction is grammatical and must not fire.
Exception phrases use the literal ... separator to indicate
arbitrary text between the prefix and suffix:
"not only...but also"
means "not only" at some position, then any text, then "but also". Every negative inside such a region is suppressed.
Instance Method Summary collapse
-
#match(tokens, rule) ⇒ Array<Hash>
Match tokens against the double negative pattern.
Methods inherited from BaseMatcher
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.
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
# File 'lib/kotoshu/grammar/pattern_matchers/double_negative_matcher.rb', line 27 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 regions = exception_regions(tokens, exception_phrases) negative_indices = tokens.each_with_index.filter_map do |token, idx| word = token[:token]&.downcase next unless negative?(word) next if regions.any? { |range| range.include?(idx) } 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 |