Есть очень простой способ считывать числа, намного проще чем твой.
Code
let parse_num i sign =
let rec pn acc pos =
if (pos < len) then
match s.[pos] with
x when is_num x -> pn (10 * acc + (int_of_ascii x)) (pos + 1)
|_ -> (Pnum (if sign then acc else -acc), pos)
else (Pnum (if sign then acc else -acc), pos) in pn 0 i;;
Здесь i - позиция, где начинается число, а sign - булёвское значение, указывающее на его знак. Обрати особое внимание на match - там всё самое интересное и происходит.