Search code examples
f#fparsec

Parsing into a complex type


I'm so new at F# and FParsec, I don't even want to embarrass myself by showing what I've got so far.

In the FParsec examples, every type in the ASTs (that I see) are type abbreviations for single values, lists, or tuples.

What if I have a complex type which is supposed to hold, say, a parsed function name and its parameters?

So, f(a, b, c) would be parsed to an object of type PFunction which has a string member Name and a PParameter list member Parameters. How can I go from a parser which can match f(a, b, c) and |>> it into a PFunction?

All I seem to be able to do so far is create the composite parser, but not turn it into anything. The Calculator example would be similar if it made an AST including a type like Term but instead it seems to me to be an interpreter rather than a parser, so there is no AST. Besides, Term would probably just be a tuple of other type abbreviated components.

Thanks!


Solution

  • I think this is what you're looking for:

    let pIdentifier o =
        let isIdentifierFirstChar c = isLetter c || c = '_'
        let isIdentifierChar c = isLetter c || isDigit c || c = '_'
        many1Satisfy2L isIdentifierFirstChar isIdentifierChar "identifier" <| o
    
    let pParameterList p = 
        spaces >>. 
            pchar '(' >>. spaces >>. sepBy (spaces >>. p .>> spaces) (pchar ',') 
                .>> spaces .>> pchar ')'
    
    type FunctionCall(Name: string, Parameters: string list) =
        member this.Name = Name
        member this.Parameters = Parameters
    
    let pFunctionCall o= 
        pipe2 (pIdentifier) (pParameterList pIdentifier) (fun name parameters -> FunctionCall(name, parameters)) <|o