code: def _expression_to_string(expression):
      
      if isinstance(expression, BinaryExp):
          left = _expression_to_string(expression.op1)
          if isinstance(expression.op1, BinaryExp) and not (
                  expression.op1.precedence > expression.precedence
                  or expression.op1.precedence == expression.precedence
                  and expression.associates in ('left', 'both')):
              left = '(' + left + ')'
  
          right = _expression_to_string(expression.op2)
          if isinstance(expression.op2, BinaryExp) and not (
                  expression.precedence < expression.op2.precedence
                  or expression.precedence == expression.op2.precedence
                  and expression.associates in ('right', 'both')):
              right = '(' + right + ')'
  
          return left + expression.operator + right
      elif isinstance(expression, Function):
          return expression.name + '(' + _expression_to_string(expression.expression) + ')'
      elif isinstance(expression, Parameter):
          return str(expression)
      else:
          return format_parameter(expression)
docs: Recursively converts an expression to a string taking into account precedence and associativity for placing
      parenthesis
  
      :param Expression expression: expression involving parameters
      :return: string such as '%x*(%y-4)'
      :rtype: str