I am trying to parse standard simple types (in the sense of lambda calculus) using FParsec, but I had difficulty moving from the Lex / Yacc style to the one used in FParsec, especially with respect to recursive definitions.
Examples of types that I am trying to parse are as follows:
- about
- o → o
- (o → o → o) → o
And here is my attempt:
type SType =
| Atom
| Arrow of SType * SType
let ws = spaces
let stype, styperef = createParserForwardedToRef()
let atom = pchar 'o' .>> ws |>> (fun _ -> Atom)
let arrow = pipe2 (stype .>> (pstring "->" .>> ws))
stype
(fun t1 t2 -> Arrow (t1,t2))
let arr = parse {
let! t1 = stype
do! ws
let! _ = pstring "->"
let! t2 = stype
do! ws
return Arrow (t1,t2)
}
styperef := choice [ pchar '(' >>. stype .>> pchar ')';
arr;
atom ]
let _ = run stype "o -> o"`
, ( , ). , , , , , ( ) stype. , arr, stype .. ?
, .