Module: ScopedSearch::QueryLanguage::Parser
- Included in:
- Compiler
- Defined in:
- lib/scoped_search/query_language/parser.rb
Constant Summary collapse
- DEFAULT_SEQUENCE_OPERATOR =
:and
- LOGICAL_INFIX_OPERATORS =
[:and, :or]
- LOGICAL_PREFIX_OPERATORS =
[:not]
- NULL_PREFIX_OPERATORS =
[:null, :notnull]
- COMPARISON_OPERATORS =
[:eq, :ne, :gt, :gte, :lt, :lte, :like, :unlike]
- ALL_INFIX_OPERATORS =
LOGICAL_INFIX_OPERATORS + COMPARISON_OPERATORS
- ALL_PREFIX_OPERATORS =
LOGICAL_PREFIX_OPERATORS + COMPARISON_OPERATORS + NULL_PREFIX_OPERATORS
Instance Method Summary collapse
-
#parse ⇒ Object
Start the parsing process by parsing an expression sequence.
-
#parse_comparison ⇒ Object
Parses a comparison.
-
#parse_expression_sequence(initial = false) ⇒ Object
Parses a sequence of expressions.
-
#parse_infix_comparison ⇒ Object
Parses an infix expression, i.e.
-
#parse_logical_expression ⇒ Object
Parses a logical expression.
-
#parse_logical_not_expression ⇒ Object
Parses a NOT expression.
-
#parse_null_expression ⇒ Object
Parses a set? or null? expression.
-
#parse_prefix_comparison ⇒ Object
Parses a prefix comparison, i.e.
-
#parse_value ⇒ Object
Parses a single value.
Instance Method Details
#parse ⇒ Object
Start the parsing process by parsing an expression sequence
13 14 15 16 |
# File 'lib/scoped_search/query_language/parser.rb', line 13 def parse @tokens = tokenize parse_expression_sequence(true).simplify end |
#parse_comparison ⇒ Object
Parses a comparison
64 65 66 67 |
# File 'lib/scoped_search/query_language/parser.rb', line 64 def parse_comparison next_token if peek_token == :comma # skip comma return (String === peek_token) ? parse_infix_comparison : parse_prefix_comparison end |
#parse_expression_sequence(initial = false) ⇒ Object
Parses a sequence of expressions
19 20 21 22 23 24 25 |
# File 'lib/scoped_search/query_language/parser.rb', line 19 def parse_expression_sequence(initial = false) expressions = [] next_token if !initial && peek_token == :lparen # skip staring :lparen expressions << parse_logical_expression until peek_token.nil? || peek_token == :rparen next_token if !initial && peek_token == :rparen # skip final :rparen return ScopedSearch::QueryLanguage::AST::LogicalOperatorNode.new(DEFAULT_SEQUENCE_OPERATOR, expressions) end |
#parse_infix_comparison ⇒ Object
Parses an infix expression, i.e. <field> <operator> <value>
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
# File 'lib/scoped_search/query_language/parser.rb', line 75 def parse_infix_comparison lhs = parse_value return case peek_token when nil lhs when :comma next_token # skip comma lhs else if COMPARISON_OPERATORS.include?(peek_token) comparison_operator = next_token rhs = parse_value ScopedSearch::QueryLanguage::AST::OperatorNode.new(comparison_operator, [lhs, rhs]) else lhs end end end |
#parse_logical_expression ⇒ Object
Parses a logical expression.
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
# File 'lib/scoped_search/query_language/parser.rb', line 29 def parse_logical_expression lhs = case peek_token when nil; nil when :lparen; parse_expression_sequence when :not; parse_logical_not_expression when :null, :notnull; parse_null_expression else; parse_comparison end if LOGICAL_INFIX_OPERATORS.include?(peek_token) operator = next_token rhs = parse_logical_expression ScopedSearch::QueryLanguage::AST::LogicalOperatorNode.new(operator, [lhs, rhs]) else lhs end end |
#parse_logical_not_expression ⇒ Object
Parses a NOT expression
48 49 50 51 52 53 54 55 56 |
# File 'lib/scoped_search/query_language/parser.rb', line 48 def parse_logical_not_expression next_token # = skip NOT operator negated_expression = case peek_token when :not; parse_logical_not_expression when :lparen; parse_expression_sequence else parse_comparison end return ScopedSearch::QueryLanguage::AST::OperatorNode.new(:not, [negated_expression]) end |
#parse_null_expression ⇒ Object
Parses a set? or null? expression
59 60 61 |
# File 'lib/scoped_search/query_language/parser.rb', line 59 def parse_null_expression return ScopedSearch::QueryLanguage::AST::OperatorNode.new(next_token, [parse_value]) end |
#parse_prefix_comparison ⇒ Object
Parses a prefix comparison, i.e. without an explicit field: <operator> <value>
70 71 72 |
# File 'lib/scoped_search/query_language/parser.rb', line 70 def parse_prefix_comparison return ScopedSearch::QueryLanguage::AST::OperatorNode.new(next_token, [parse_value]) end |
#parse_value ⇒ Object
Parses a single value. This can either be a constant value or a field name.
96 97 98 99 |
# File 'lib/scoped_search/query_language/parser.rb', line 96 def parse_value raise ScopedSearch::QueryNotSupported, "Value expected but found #{peek_token.inspect}" unless String === peek_token ScopedSearch::QueryLanguage::AST::LeafNode.new(next_token) end |