How do I test for exactly 2 characters with fparsec?

北城余情 提交于 2020-01-02 05:38:09

问题


I have the following program that runs. It takes a line of text and splits it into two parts, the first is an identifier and the second is the remainder of the line. My parser for the identifier (factID) takes any string of characters as the identifier, which is not (quite) what I want. What I want is a parser that only succeeds when it encounters two consecutive upper case letters. So for example "AA" should succeed while "A", "A1" or "AAA" should not.

What I can't figure out is how construct a parser that looks for a fixed length token. I thought perhaps CharParsers.next2CharsSatisfy might be the function I am looking for, but I can't figure out how to properly use it.

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

回答1:


I think this would do it

let pFactID = manyMinMaxSatisfy 2 2 Char.IsUpper


来源:https://stackoverflow.com/questions/16525975/how-do-i-test-for-exactly-2-characters-with-fparsec

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!