docs: def evaluate_expression(self, expression, context, strategy=EvaluationStrategy.COMPLETE):
          """
          Evaluates a single expression, e.g. "contact.reports * 2"
          :param expression: the expression string
          :param context: the evaluation context
          :param strategy: the evaluation strategy
          :return: the evaluated expression value
          """
          from .gen.ExcellentLexer import ExcellentLexer
          from .gen.ExcellentParser import ExcellentParser
  
          stream = InputStream(expression)
          lexer = ExcellentLexer(stream)
          tokens = CommonTokenStream(lexer)
  
          parser = ExcellentParser(tokens)
          parser._errHandler = BailErrorStrategy()
  
          try:
              tree = parser.parse()
  
              if logger.isEnabledFor(logging.DEBUG):
                  logger.debug("Expression '%s' parsed as %s" % (expression, tree.toStringTree()))
          except ParseCancellationException as ex:
              message = None
              if ex.args and isinstance(ex.args[0], NoViableAltException):
                  token = ex.args[0].offendingToken
                  if token is not None and token.type != ExcellentParser.EOF:
                      message = "Expression error at: %s" % token.text
  
              if message is None:
                  message = "Expression is invalid"
  
              raise EvaluationError(message, ex)
  
          if strategy == EvaluationStrategy.RESOLVE_AVAILABLE:
              resolved = self._resolve_available(tokens, context)
              if resolved is not None:
                  return resolved
  
          visitor = ExcellentVisitor(self._function_manager, context)
          return visitor.visit(tree)