class Elasticfusion::Search::Query::Lexer

Constants

TOKENS

Public Class Methods

new(string, searchable_fields) click to toggle source
# File lib/elasticfusion/search/query/lexer.rb, line 21
def initialize(string, searchable_fields)
  @scanner = StringScanner.new(string)
  @field_regex = /(#{searchable_fields.join('|')}):/ if searchable_fields.any?
end

Public Instance Methods

left_parentheses() click to toggle source
# File lib/elasticfusion/search/query/lexer.rb, line 42
def left_parentheses
  @scanner.skip /\(/
end
match(token) click to toggle source
# File lib/elasticfusion/search/query/lexer.rb, line 26
def match(token)
  @scanner.scan TOKENS[token]
end
match_field() click to toggle source
# File lib/elasticfusion/search/query/lexer.rb, line 34
def match_field
  return unless @field_regex
  field = @scanner.scan @field_regex
  if field
    field[0..-2] # remove field query delimiter (":")
  end
end
match_until(regex) click to toggle source

StringScanner#scan_until returns everything up to and including the regex. To avoid including the pattern, we use a lookahead.

# File lib/elasticfusion/search/query/lexer.rb, line 84
def match_until(regex)
  @scanner.scan /.+?(?=#{regex.source}|\z)/
end
quoted_string() click to toggle source

May contain any characters except for quotes (the latter are allowed when escaped).

# File lib/elasticfusion/search/query/lexer.rb, line 56
def quoted_string
  string = match(:quoted_string)

  if string
    string[1..-2] # ignore quotes
      .gsub(/\\"/, '"')
      .gsub(/\\\\/, '\\')
  end
end
right_parentheses(expected_count) click to toggle source
# File lib/elasticfusion/search/query/lexer.rb, line 46
def right_parentheses(expected_count)
  @scanner.skip /\){,#{expected_count}}/
end
safe_string() click to toggle source

May contain words, numbers, spaces, dashes, and underscores.

# File lib/elasticfusion/search/query/lexer.rb, line 51
def safe_string
  match_until TOKENS[:safe_string_until]
end
skip(token) click to toggle source
# File lib/elasticfusion/search/query/lexer.rb, line 30
def skip(token)
  @scanner.skip TOKENS[token]
end
string_with_balanced_parentheses() click to toggle source
# File lib/elasticfusion/search/query/lexer.rb, line 66
def string_with_balanced_parentheses
  string = match_until TOKENS[:string_with_balanced_parentheses_until]

  if string
    opening_parens = string.count('(')

    balanced = string.split(')')[0..opening_parens].join(')')
    balanced += ')' if opening_parens > 0 && string.ends_with?(')')

    cutoff = string.length - balanced.length
    @scanner.pos -= cutoff

    balanced.strip
  end
end