【问题标题】:Parsing a variable declaration with FParsec使用 FParsec 解析变量声明
【发布时间】:2018-10-18 08:51:52
【问题描述】:

我正在尝试使用 FParsec 解析变量声明。我阅读了教程的一部分,以及Phillip Trelford's example of parsing C#。 以下是可以扫描的内容:

let [identifier] = [value];
let [identifier] [: type] = [value];
let [identifier] = [new [type(constructor)]];

例如:

let foo = 9;
let foo: Integer = 9;
let foo = new Integer(9);

foo也可以带参数,例如:

let foo(a, b) = a + b;
let foo(a: Integer, b: Integer = 0) -> Integer = a + b;

基本上,let 指令与 F# 的指令相同,只是参数在括号中,并且没有块,只有一个表达式。

在教程中,它实现了一个 C# 变量,例如:

let pdefine = pipe2 (pidentifier .>> ws1) (pidentifier)
                (fun ty name -> Define(ty,name))

let pdefinition = pdefine |>> fun d -> Definition(d)

但是我不知道如何实现我的版本,这似乎更复杂....如果有人可以给我一个线索,或者一个可以更清楚地解释如何做的链接,那将对我有很大帮助。

【问题讨论】:

    标签: f# parsec fparsec


    【解决方案1】:

    你可以以此为例:

    open FParsec
    open System
    
    let str = pstring
    let ws = spaces
    
    type VarType = 
        | Implicit
        | Explicit of string
    
    type Value = 
        | IntValue of int
        | TypeConstructor of string * Value
    
    type LetDeclr = LetDeclr of string * VarType * Value
    
    let isValidChar c =
        ['A'..'Z'] @ ['a'..'z']
        |> Seq.exists (fun ch -> ch = c)
    
    let identifierParser = manySatisfy isValidChar
    
    let value, valueRef = createParserForwardedToRef()
    
    do valueRef := choice [
        str "new" >>. ws >>. identifierParser >>= fun typeName ->
            ws >>. between (str "(") (str ")") value |>> fun typeValue ->
                 TypeConstructor(typeName, typeValue)
        pint32 |>> IntValue
    ]
    
    let parser = 
        str "let" >>. ws >>. identifierParser
        >>= fun identifier ->
        attempt (ws >>. str ":" >>. ws >>. identifierParser |>> Explicit) <|> (ws >>% Implicit )
        >>= fun varType ->
        ws >>. str "=" >>. ws >>. value
        |>> fun varValue -> LetDeclr(identifier, varType, varValue)
        .>> ws .>> str ";"
    
    let parse = FParsec.CharParsers.run parser
    
    parse "let foo = 9;"
    parse "let foo: Integer = 9;"
    parse "let foo = new Integer(new String(344));"
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多