【问题标题】:Parsing the arrow type with FParsec使用 FParsec 解析箭头类型
【发布时间】:2018-12-06 16:23:07
【问题描述】:

我正在尝试使用 FParsec 解析箭头类型。 也就是这个:

Int -> Int -> Int -> Float -> Char

例如。

我尝试使用此代码,但它仅适用于一种类型的箭头 (Int -> Int),不再适用。我也想避免使用括号,因为我已经有一个使用它们的元组类型,而且我也不希望它在语法方面太重。

let ws = pspaces >>. many pspaces |>> (fun _ -> ())

let str_ws s = pstring s .>> ws

type Type = ArrowType of Type * Type

let arrowtype' =
    pipe2
        (ws >>. ty')
        (ws >>. str_ws "->" >>. ws >>. ty')
        (fun t1 t2 -> ArrowType(t1, t2))

let arrowtype =
    pipe2
        (ws >>. ty' <|> arrowtype')
        (ws >>. str_ws "->" >>. ws >>. ty' <|> arrowtype')
        (fun t1 t2 -> ArrowType(t1, t2)) <?> "arrow type"

ty' 只是另一种类型,例如元组或标识符。

你有解决办法吗?

【问题讨论】:

    标签: f# parsec fparsec


    【解决方案1】:

    在进入箭头语法之前,我想评论一下您的ws 解析器。使用|&gt;&gt; (fun _ -&gt; ()) 效率有点低,因为 FParsec 必须构造一个结果对象然后立即将其丢弃。内置的 spacesspaces1 解析器可能更适合您的需求,因为它们不需要构造结果对象。

    现在,至于您正在努力解决的问题,在我看来,您想考虑箭头解析器的方式略有不同。将其视为由-&gt; 分隔的一系列类型并使用sepBy 解析器组合器系列怎么样?像这样的:

    let arrow = spaces1 >>. pstring "->" .>> spaces1
    let arrowlist = sepBy1 ty' arrow
    let arrowtype = arrowlist |>> (fun types ->
        types |> List.reduce (fun ty1 ty2 -> ArrowType(ty1, ty2))
    

    注意arrowlist 解析器只匹配普通的Int,因为sepBy1 的定义不是“必须至少有一个列表分隔符”,而是“列表中必须至少有一项”。因此,要区分 Int 类型和箭头类型,您需要执行以下操作:

    let typeAlone = ty' .>> notFollowedBy arrow
    let typeOrArrow = attempt typeAlone <|> arrowtype
    

    这里必须使用attempt,这样如果出现箭头,ty' 使用的字符将被回溯。

    自从您提到不需要括号以来,我根本没有解决一个复杂的因素。但是,如果您决定希望能够拥有箭头类型的箭头类型(即,将函数作为输入的函数),则需要解析像(Int -&gt; Int) -&gt; (Int -&gt; Float) -&gt; Char 这样的类型。这会使sepBy 的使用变得复杂,我根本没有解决它。如果您最终需要更复杂的解析,包括括号,那么您可能想要使用OperatorPrecedenceParser。但是对于不涉及括号的简单需求,sepBy1 看起来是您的最佳选择。

    最后,我应该给出一个警告:我根本没有测试过这个,只是在 Stack Overflow 框中输入了这个。我给您的代码示例并不是要按原样工作,而是要让您了解如何进行。如果您需要一个按原样工作的示例,我很乐意为您提供一个,但我现在没有时间这样做。

    【讨论】:

    • 感谢您的帮助,我现在可以更好地了解如何进行,使用列表类型对我来说似乎更容易解析,以后再分析。我想我可以处理这个:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多