failwith вызывает ошибку при использовании в выражении вычисления - FParsec - PullRequest
0 голосов
/ 02 января 2019

Я использую функцию:

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.Но когда я использую этот синтаксический анализатор (идентифицировать) с преднамеренной ошибкой в ​​моем тексте для анализа, чтобы проверить, все ли работает, я получаю длинную ошибку:

enter image description here

(Извините, я француз, поэтому в сообщении об ошибке есть немного французского ^^.)

Как предотвратить все это и отображать сообщение об ошибке только классическим способом с помощью FParsec?

1 Ответ

0 голосов
/ 02 января 2019

Функция 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"
...