g | x | w | all
Bytes Lang Time Link
402Java 8171020T140820ZKevin Cr
251Perl 5171020T113447ZDom Hast
279Python 3171020T114256ZTFeld

Java 8, 456 423 419 407 403 402 bytes

n->{int r=R(9);return r>4?(r<8?"FGX!".charAt(r-5):"")+b(n):"("+b(n)+"UWR&|".charAt(r)+b(n)+")";};int R(int i){return i*=Math.random();}String b(int n){int r=R(9);return r>7?"abcd".charAt(r%4)+"":r>6?"True":r>5?"False":n>0?"("+i(n)+"<≤>≥=≠".charAt(r)+i(n)+")":b(n);}String i(int n){int r=R(n>0?256:261)-128;return r>131?"wxyz".charAt(r+2&3)+"":r>127?"("+i(--n)+"+-*/".charAt(r-128)+i(n)+")":r+"";}

-9 bytes thanks to @ceilingcat.

Try it online.

NOTE: Due to the rule "The distribution does not have to be uniformly random", I've been able to golf some parts by using modulo-4 on the input or random integer for the characters "abcd" or "wxyz", and change Math.random()*10 to Math.random()*9 and change the ternary a bit. Personally I prefer to have the randomness equally divided for each method, which is 456 441 404 403 bytes instead (and is explained below):

n->{int r=R(10);return r>4?(r<9?"FGX!".charAt(r-5):"")+b(n):"("+b(n)+"UWR&|".charAt(r)+b(n)+")";};int R(int i){return i*=Math.random();}String b(int n){int r=R(9);return r>7?"abcd".charAt(R(4))+"":r>6?"True":r>5?"False":n>0?"("+i(n)+"<≤>≥=≠".charAt(r)+i(n)+")":b(n);}String i(int n){int r=R(n>0?256:261)-128;return r>131?"wxyz".charAt(R(4))+"":r>127?"("+i(--n)+"+-*/".charAt(r-128)+i(n)+")":r+"";}

Try it online.

Explanation:

n->{                     // Method with integer parameter and String return-type
  int r=R(10);           //  Random integer [0,9]
  return r>4?            //  Is it [5,9]:
    (r<9?                //   Is it [5,8]:
      "FGX!".charAt(r-5) //    Return a leading character
     :                   //   Else (it's 9):
      "")                //    Return nothing
    +b(n)                //   + call to method `b(n)`
   :                     //  Else (it's [0-4]):
    "("                  //   Return opening parenthesis
    +b(n)                //   + call to method `b(n)`
    +"UWR&|".charAt(r)   //   + middle character
    +b(n)                //   + another call to method `b(n)`
    +")";                //   + closing parenthesis
}                        // End of method

int R(int i){            // Method `R(i)` with integer as both parameter and return-type
  return i*=Math.random();
                         //  Return a random integer in the range [0,i)
}                        // Else of method `R(i)`

String b(int n){         // Method `b(n)` with integer parameter and String return-type
  int r=R(9);            //  Random integer [0,8]
  return r>7?            //  Is it 8:
     "abcd".charAt(R(4))+""
                         //   Return random from "abcd"
   :r>6?                 //  Else-if it's 7:
    "True"               //   Return literal "True"
   :r>5?                 //  Else-if it's 6:
    "False"              //   Return literal "False"
   :n>0?                 //  Else-if it's [0-5] AND the input is larger than 0:
    "("                  //   Return opening parenthesis
    +i(n)                //   + call to method `i(n)`
    +"<≤>≥=≠".charAt(r)  //   + middle character
    +i(n)                //   + another call to method `i(n)`
    +")"                 //   + closing parenthesis
   :                     //  Else (it's [0-5] and the input is 0):
    b(n);                //   Call itself again, hoping for random [6-8]
}                        // End of method `b(n)`

String i(int n){         // Method `i(n)` with integer parameter and String return-type
  int r=R(n>0?256:261)-128;
                         //  Random integer in range [-128,128]
                         //  OR [-128,132] if the input is larger than 0
  return r>131?          //  If it is 132:
     "wxyz".charAt(R(4))+""
                         //   Return random from "wxyz"
   :r>127?               //  Else-if it's [128,131]:
    "("                  //   Return opening parenthesis
    +i(--n)              //   + call to `i(n-1)`
    +"+-*/".charAt(r-128)//   + middle character
    +i(n)                //   + another call to `i(n-1)`
    +")"                 //   + closing parenthesis
   :                     //  Else:
    r+"";                //   Return the random integer [-128,127]
}                        // End of method `i(n)`

Perl 5, 251 bytes

249 bytes code + 2 for -pa.

$d=I;sub a{map"($d$_$d)",@_}@I=(w..z,-128..127,a qw{+ - * /});@L=(@B=(a..d,True,False,a qw{< <= > >= = !=}),B,FL,GL,XL,"!".($d=L),a qw{U W R & |});$_=$L[rand@L];0while s/L|B|I/@{$&}[rand@{$&}]/e;$;=$_;s/[^()]//g;0while s/\)\(//g;$_=y/(//>"@F"?redo:$

Try it online!

Python 3, 298 293 283 279 bytes

def f(n,t=1):s,*X=c([[(c(V[t>1]),)],[('%s',0),(c('FGX!')+'%s',1)]][t&1]+[(f"(%s{c('<U+≤W->R*≥&/=|+≠'[t::3])}%s)",*[2-(t&1)]*2)]);return n and s%tuple(f(n-1,x)for x in X)or c(V[t>1])
from random import*
c=choice
V=['True','False',*'abcd'],[*map(str,range(-128,128)),*'wxyz']

Try it online!