F# 解析器标识符和自由格式文本。这可以用FParsec完成吗?

F# 解析器标识符和自由格式文本。这可以用FParsec完成吗?,f#,fparsec,F#,Fparsec,作为后续行动: 我需要解析一个字符串,该字符串由标识符对和自由格式文本组成。我可以很容易地构造一个解析器来查找标识符,其形式为换行符,后跟两个大写字符,后跟一个空格。与前一个标识符关联的自由格式文本是该标识符之后直到下一个标识符的所有内容,但不包括下一个标识符 例如: AB Now is the time for all good men. CD Four score and seven years ago EF our. 包含两个标识符AB和CD以及两段自由格式文本 现在是所有好人的时刻。

作为后续行动:

我需要解析一个字符串,该字符串由标识符对和自由格式文本组成。我可以很容易地构造一个解析器来查找标识符,其形式为换行符,后跟两个大写字符,后跟一个空格。与前一个标识符关联的自由格式文本是该标识符之后直到下一个标识符的所有内容,但不包括下一个标识符

例如:

AB Now is the
time for all good
men.
CD Four score and seven years ago EF our.
包含两个标识符
AB
CD
以及两段自由格式文本

现在是所有好人的时刻。

47年前我们的EF。

我的问题是我不知道如何构造一个匹配自由格式文本但不匹配标识符的解析器。这是我需要回溯的情况吗


这可以做到吗?如果可以,怎么做?

我想你要找的是
不遵循
。这应该可以做到:

// adapted from the other question
let identifier = skipNewline >>. manyMinMaxSatisfy 2 2 CharParsers.isUpper

let freeform = manyChars (notFollowedBy identifier >>. anyChar)

塔米尔提出了简单的解决方案

下面是另一个变体,它在开头不需要换行,只在行尾检查以下标识符:

let id = manyMinMaxSatisfyL 2 2 isUpper "ID" .>> pchar ' '

let text = 
    stringsSepBy (restOfLine true) 
                 ((notFollowedBy ((id >>% ()) <|> skipNewline <|> eof)) >>% "\n")

let parser = many (id .>>. text)

您好,请您对这个问题发表意见:
let notFollowedByIdOrEmptyLineOrEof : Parser<string,_> =
    fun stream ->
        let cs = stream.Peek2()
        let c0, c1 = cs.Char0, cs.Char1
        if c0 = '\r' || c0 = '\n' || c0 = EOS
           || (isUpper c0 && isUpper c1 && stream.Peek(2) = ' ')
        then Reply(Error, NoErrorMessages)
        else Reply("\n")

let text2 = stringsSepBy (restOfLine true) 
                         notFollowedByIdOrEmptyLineOrEof