Class: LcpRuby::Search::QueryLanguageParser
- Inherits:
-
Object
- Object
- LcpRuby::Search::QueryLanguageParser
- Defined in:
- lib/lcp_ruby/search/query_language_parser.rb
Defined Under Namespace
Classes: ParseError
Constant Summary collapse
- SYMBOL_OPERATORS =
{ "!=" => :not_eq, ">=" => :gteq, "<=" => :lteq, ">" => :gt, "<" => :lt, "=" => :eq, "~" => :cont, "!~" => :not_cont, "!^" => :not_start, "!$" => :not_end, "^" => :start, "$" => :end }.freeze
- SORTED_SYMBOL_OPS =
Sorted by length desc so multi-char operators match first
SYMBOL_OPERATORS.keys.sort_by { |k| -k.length }.freeze
- KEYWORD_OPERATORS =
{ "in" => :in, "not in" => :not_in }.freeze
- IS_VALUES =
{ "not null" => :not_null, "not true" => :not_true, "not false" => :not_false, "null" => :null, "present" => :present, "blank" => :blank, "true" => :true, "false" => :false, "this_week" => :this_week, "this_month" => :this_month, "this_quarter" => :this_quarter, "this_year" => :this_year }.freeze
- SORTED_IS_VALUES =
Sorted by length desc so “not null” matches before “not”
IS_VALUES.keys.sort_by { |k| -k.length }.freeze
- WHITESPACE_RE =
/\s/- IDENTIFIER_CHAR_RE =
/[a-zA-Z0-9_]/- DIGIT_RE =
/[0-9]/- MAX_INPUT_LENGTH =
2000- MAX_PARSE_DEPTH =
50
Instance Method Summary collapse
-
#initialize(input, max_nesting_depth: 10) ⇒ QueryLanguageParser
constructor
A new instance of QueryLanguageParser.
-
#parse ⇒ Object
Parse the input and return a recursive condition tree.
Constructor Details
#initialize(input, max_nesting_depth: 10) ⇒ QueryLanguageParser
Returns a new instance of QueryLanguageParser.
62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/lcp_ruby/search/query_language_parser.rb', line 62 def initialize(input, max_nesting_depth: 10) @input = input.to_s if @input.length > MAX_INPUT_LENGTH raise ParseError.new( "Query too long (#{@input.length} characters, maximum is #{MAX_INPUT_LENGTH})", position: 0 ) end @pos = 0 @parse_depth = 0 @max_nesting_depth = max_nesting_depth end |
Instance Method Details
#parse ⇒ Object
Parse the input and return a recursive condition tree. Returns: { “combinator” => “and”, “children” => […] } Each child is either a leaf condition { “field”, “operator”, “value” } or a group { “combinator”, “children” => […] }
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/lcp_ruby/search/query_language_parser.rb', line 79 def parse skip_whitespace return empty_tree if eof? tree = parse_or_expression skip_whitespace unless eof? error("Unexpected input at position #{@pos}") end result = normalize_ast(tree, depth: 1) # Ensure root is always a group node, not a bare leaf if result.is_a?(Hash) && result.key?("field") { "combinator" => "and", "children" => [ result ] } else result end end |