Вариант 1: аналитически. Строишь дерево разбора выражения, интегрируешь. Недостаток: задолбешься расписывать варианты, а без этого будет только очень ограниченный набор функций. Вариант 2:любым численным методом, например трапеций, идешь с экспоненциально увеличевающимся шагом (например, в 2 раза на каждом шагу), пока очередной шаг не даст прирост меньше точности. Недостаток: куча математики в пояснении, почему это работает.