Проблема в том, что ваш парсер pstmt_list
создает некоторые значения некоторого типа, но когда вы используете его в определении, вы оборачиваете значения этого типа дополнительным типом option
(используя комбинатор opt
).
Компилятор F # считает, что тип значений, возвращаемых синтаксическим анализатором, например, 'a
должен быть таким же, как и обернутый тип option 'a
(что, конечно, невозможно).
В любом случае, я не думаю, что это именно то, что вам нужно сделать - комбинатор .>>
создает парсер, который возвращает результат второго аргумента, что означает, что вы будете игнорировать все результаты pstmt
разобрано до сих пор.
Я думаю, вам, вероятно, нужно что-то вроде этого:
let rec pstmt_list : Parser<int list, unit> =
parse.Delay(fun () ->
opt(pstmt .>> pchar ';') .>>. opt pstmt_list
|>> (function Some(prev), Some(rest) -> prev::rest
| Some(prev), _ -> [prev]
| _, Some(rest) -> rest
| _ -> [] ))
Дополнительное использование Delay
состоит в том, чтобы не объявлять значение, которое относится непосредственно к себе.