parsing - 如何使用 fparsec 解析由双空格分隔的单词序列?

标签 parsing f# fparsec

鉴于输入:

alpha beta gamma  one two three

我怎么能把它解析成下面的?
[["alpha"; "beta"; "gamma"]; ["one"; "two"; "three"]]

当有更好的分隔符(例如__)时,我可以写这个,然后
sepBy (sepBy word (pchar ' ')) (pstring "__")

工作,但在双空间的情况下,第一个 sepBy 中的 pchar 消耗第一个空间,然后解析器失败。

最佳答案

FParsec 手册 sayssepBy p sep , 如果 sep成功和后续 p失败(不改变状态),整个sepBy也失败了因此,您的目标是:

  • 制作分隔符 失败 如果遇到多个空格字符;
  • 回溯使“内在”sepBy循环愉快地关闭并将控制权传递给“外部”sepBy环形。

  • 以下是两者的方法:
    // this is your word parser; it can be different of course,
    // I just made it as simple as possible;
    let pWord = many1Satisfy isAsciiLetter
    
    // this is the Inner separator to separate individual words
    let pSepInner =
        pchar ' '
        .>> notFollowedBy (pchar ' ') // guard rule to prevent 2nd space
        |> attempt                    // a wrapper that would fail NON-fatally
    
    // this is the Outer separator
    let pSepOuter =
        pchar ' '
        |> many1  // loop
    
    // this is the parser that would return String list list
    let pMain =
        pWord
        |> sepBy <| pSepInner         // the Inner loop
        |> sepBy <| pSepOuter         // the Outer loop
    

    用:
    run pMain "alpha beta gamma  one two three"
    Success: [["alpha"; "beta"; "gamma"]; ["one"; "two"; "three"]]
    

    关于parsing - 如何使用 fparsec 解析由双空格分隔的单词序列?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52411478/

    相关文章:

    reflection - 我可以禁止 F# 编译器在 IL 代码中复制函数吗?

    f# - 将 .NET 4.5 异步适配到 F#

    Java数学表达式解析器可以将复数作为变量?

    java - 解析覆盖失败 - Aapt2 - Android Studio

    f# - List 中所有项目的特定属性的总和

    f# - 如果 "till"解析器以空格开头,为什么 manyCharsTill 组合器不起作用?

    f# - 如何使用 FParsec 解析评论

    c# - 使用或不使用程序集重定向都找不到 F# Core 方法。我还可以做些什么?

    c++ - 在 while 循环和段错误 C++ 中使用 erase()

    ruby - 从 Ruby 中的字符串解析十进制值