代码之家  ›  专栏  ›  技术社区  ›  Simon P

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

  •  2
  • Simon P  · 技术社区  · 6 年前

    给定输入:

    alpha beta gamma  one two three
    

    我怎么能把它分解成下面的呢?

    [["alpha"; "beta"; "gamma"]; ["one"; "two"; "three"]]
    

    sepBy (sepBy word (pchar ' ')) (pstring "__")
    

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

    2 回复  |  直到 6 年前
        1
  •  2
  •   Be Brave Be Like Ukraine    6 年前

    says 那在哪 sepBy p sep sep 成功与后续 p sepBy 也失败了。因此,您的目标是:

    1. 制造分离器 如果遇到多个空格字符;
    2. 所以“内在的” 循环愉快地关闭并将控制权传递给“外部” 塞比 循环。

    以下是如何做到这两者:

    // 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"]]
    
        2
  •  2
  •   rmunn    6 年前

    我建议更换 sepBy word (pchar ' ') 像这样:

    let pOneSpace = pchar ' ' .>> notFollowedBy (pchar ' ')
    let pTwoSpaces = pstring "  "
    // Or if two spaces are allowed as separators but *not* three spaces...
    let pTwoSpaces = pstring "  " .>> notFollowedBy (pchar ' ')
    sepBy (sepBy word pOneSpace) pTwoSpaces
    

    注意:没有测试(因为我现在没有时间),只是在答案框中输入。所以测试一下,以防我在什么地方出错。