如何在重复模式之后解析权利之间的差异?

时间:2014-10-11 18:32:52

标签: f# fparsec

您如何使用现有的FParsec功能在最右边的标签中找到重复的连续模式?

在这种情况下,这是合法的可能性。预解析+转义可能有效,但是有更好的解决方案吗?我们是否需要编写一个新的前向组合器,如果是,它看起来像什么?

#r"""bin\debug\FParsecCS.dll"""
#r"""bin\debug\FParsec.dll"""

open FParsec

let str = pstring
let phraseEscape = pchar '\\' >>. pchar '"'
let phraseChar = phraseEscape <|> (noneOf "|\"\r\n]")    // <- this right square bracket needs to be removed
let phrase = manyChars phraseChar

let wrapped = between (str"[[") (str"]]".>>newline) phrase 

run wrapped "[[some text]]\n"  // <- works fine

// !! problem
run wrapped "[[array[] d]]\n"    // <- that means we can't make ']' invalid in phraseChar

// !! problem
run wrapped "[[array[]]]\n"      // <- and this means that the first ]] gets match leaving a floating one to break the parser

1 个答案:

答案 0 :(得分:1)

很抱歉回答我自己的问题,但是......

请参阅可组合函数 phraseTill ,以及传递给 pend 解析器(notFollowedBy(s&#34;]]]&#34;) &GT;&GT;(S&#34;]]&#34))

#r"""bin\debug\FParsecCS.dll"""
#r"""bin\debug\FParsec.dll"""

open FParsec

let s = pstring
let phraseChar = (noneOf "\r\n")   
let phrase = manyChars phraseChar
/// keep eating characters until the pend parser is successful
let phraseTill pend = manyCharsTill phraseChar pend

/// when not followed by tipple, a double will truly be the end
let repeatedTo repeatedPtrn ptrn = notFollowedBy(s repeatedPtrn)>>.(s ptrn) 
let wrapped = (s"[[")>>.phraseTill (repeatedTo "]]]" "]]")
run wrapped "[[some text]]]"
run wrapped "[[some text]]"

NB。如果您在FSharp Interactive(FSI)中尝试这一点,请确保您至少有一个&#34;运行包装&#34;当您将文本发送到FSI进行评估时(即右键单击“在交互式中执行”#);在此示例中,仅在应用程序上推断/固定类型。我们本可以提供明确的定义,冒着更加冗长的风险。