Class: DecisionAgent::Dmn::Feel::Evaluator

Inherits:
Object
  • Object
show all
Defined in:
lib/decision_agent/dmn/feel/evaluator.rb

Overview

FEEL expression evaluator with hybrid parsing strategy Phase 2A: Basic comparisons, ranges, list membership (regex-based) Phase 2B: Arithmetic, logical operators, functions (enhanced parser) Maps FEEL expressions to DecisionAgent ConditionEvaluator

Instance Method Summary collapse

Constructor Details

#initializeEvaluator

Returns a new instance of Evaluator.



19
20
21
22
23
24
25
26
27
# File 'lib/decision_agent/dmn/feel/evaluator.rb', line 19

def initialize
  @simple_parser = SimpleParser.new
  @parslet_parser = Parser.new
  @transformer = Transformer.new
  @cache = {}
  @cache_mutex = Mutex.new
  @ast_cache = {} # Cache for Parslet AST nodes
  @use_parslet = true # Enable full Parslet parser
end

Instance Method Details

#evaluate(expression, field_name, context) ⇒ Boolean

Evaluate a FEEL expression against a context

Parameters:

  • expression (String)

    FEEL expression (e.g., ">= 18", "in [1,2,3]", "age + 5")

  • field_name (String)

    The field name being evaluated

  • context (Hash)

    Evaluation context

Returns:

  • (Boolean)

    Evaluation result



34
35
36
37
38
39
40
41
42
43
# File 'lib/decision_agent/dmn/feel/evaluator.rb', line 34

def evaluate(expression, field_name, context)
  return true if expression == "-" # DMN "don't care" marker

  # Try Parslet parser first (Phase 2B)
  parslet_result = try_parslet_evaluate(expression, context) if @use_parslet
  return parslet_result unless parslet_result == :fallback

  # Phase 2A approach: use condition structures
  evaluate_phase2a(expression, field_name, context)
end

#parse_expression(expr) ⇒ Object

Parse FEEL expression into operator and value (for internal use by Adapter) This maintains backward compatibility with Phase 2A



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/decision_agent/dmn/feel/evaluator.rb', line 47

def parse_expression(expr)
  expr = expr.to_s.strip

  # Handle literal values (quoted strings, numbers, booleans)
  return parse_literal(expr) if literal?(expr)

  # Handle comparison operators
  return parse_comparison(expr) if comparison_expression?(expr)

  # Handle list membership
  return parse_list_membership(expr) if list_expression?(expr)

  # Handle range expressions
  return parse_range(expr) if range_expression?(expr)

  # Check if it's a simple parsable expression (arithmetic/logical)
  if SimpleParser.can_parse?(expr)
    begin
      ast = @simple_parser.parse(expr)
      return translate_ast(ast, nil)
    rescue FeelParseError
      # Fall back to literal equality
    end
  end

  # Default: equality
  { operator: "eq", value: parse_value(expr) }
end