4

我有以下运行的程序。它需要一行文本并将其分成两部分,第一部分是标识符,第二部分是该行的其余部分。我的标识符(factID)解析器将任何字符串作为标识符,这不是(完全)我想要的。我想要的是一个解析器,它只有在遇到两个连续的大写字母时才会成功。因此,例如“AA”应该成功,而“A”、“A1”或“AAA”不应该。

我想不通的是如何构造一个寻找固定长度令牌的解析器。我想也许 CharParsers.next2CharsSatisfy 可能是我正在寻找的功能,但我不知道如何正确使用它。

open FParsec

let test p str =
    match run p str with
    | Success(result, _, _)   -> printfn "Success: %A" result
    | Failure(errorMsg, _, _) -> printfn "Failure: %s" errorMsg

let ws = spaces
let str_ws s = pstring s .>> ws

type StringConstant = StringConstant of string * string

let factID =
    let isIdentifierFirstChar c = isLetter c 
    let isIdentifierChar c = isLetter c 

    many1Satisfy2L isIdentifierFirstChar isIdentifierChar "factID"

let factText =
    let isG c = isLetter c || isDigit c || c = ' ' || c = '.'
    manySatisfy isG 


let factParse = pipe3 factID (str_ws " ") factText
                        (fun id _ str -> StringConstant(id, str))


[<EntryPoint>]
let main argv = 
    test factParse "AA This is some text."      // This should pass
    test factParse "A1 This is some text."      // This should fail
    test factParse "AAA This is some text."     // This passes but I want it to fail
    0 // return an integer exit code
4

1 回答 1

4

我认为这会做到

let pFactID = manyMinMaxSatisfy 2 2 Char.IsUpper
于 2013-05-13T16:20:20.533 回答