我使用一个函数:
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以经典方式显示错误消息?
答案 0 :(得分:2)
failwith
函数会引发.NET异常-属巨灾失败,应表明程序以意外方式中断。或者,换句话说,以 exception 的方式命名-因此命名为“ exception”。这不是您要执行的操作。
您要在此处执行的操作是向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"