【问题标题】:failwith causes an error when used in a calculation expression - FParsecfailwith 在计算表达式中使用时会导致错误 - FParsec
【发布时间】:2019-01-02 16:17:23
【问题描述】:

我使用一个函数:

let identifier kind =
    (many1Satisfy2L isLetter
        (fun c -> isLetter c || isDigit c) "identifier"
     >>= fun s -> preturn s) >>= fun s -> identifierKind s kind

kind 参数属于这种类型:

type KindOfIdentifier =
    | Data
    | Type
    | Module

这是我分析 kind 参数的函数:

let private identifierKind (id: string) kind =
    match kind with
    | KindOfIdentifier.Data ->
        if id.ToUpper() = id && id.Length > 1 then preturn id
        elif System.Char.IsUpper id.[0] = false then preturn id
        else failwith "Error 1"
    | KindOfIdentifier.Module ->
        if System.Char.IsUpper id.[0] then preturn id
        else failwith "Error 2"
    | KindOfIdentifier.Type ->
        preturn id

因此,我想分析一个标识符以验证它是否符合标识符类型的标准。如果识别它不符合标准,我返回一个错误failwith。 但是,当我在要分析的文本中使用此解析器(识别)时故意出现错误,以检查一切是否正常时,我得到一个很长的错误:

(对不起,我是法国人,所以错误信息中有一点法语^^。)

如何防止这一切,只用 FParsec 的经典方式显示错误信息?

【问题讨论】:

    标签: exception f# fparsec


    【解决方案1】:

    failwith 函数引发 .NET 异常 - 一个灾难性的故障,应该表明程序以意外方式中断。或者,换句话说,以一种异常的方式——因此得名“异常”。这不是你想要做的。

    您在这里尝试做的是向 FParsec 表明当前的解析尝试失败,并可能提供对究竟发生了什么的解释。

    为此,您需要创建一个产生错误的Parser 实例——与preturn 返回的类型相同。

    虽然preturn 创建了Parser 的成功实例,但还有另一个函数创建了一个产生错误的实例。此函数称为fail。就用它吧:

        | KindOfIdentifier.Data ->
            if id.ToUpper() = id && id.Length > 1 then preturn id
            elif System.Char.IsUpper id.[0] = false then preturn id
            else fail "Error 1"
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-22
      • 2022-09-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多