首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >为什么FParsec不使用解析列表分隔符的字符?

为什么FParsec不使用解析列表分隔符的字符?
EN

Stack Overflow用户
提问于 2018-06-02 00:31:37
回答 1查看 120关注 0票数 3

下面的实际场景是虚构的。这个问题的目的是更多地了解FParsec在这里做什么。

我正在解析由一个或多个空格字符' '分隔的字符串(w)(x)的列表。

my list xs的解析器使用带有分隔符解析器isSeparatorsepBy

isSeparator是基于manySatisfy的,似乎可以正确地消耗空间。我相信这可以在下面的测试输出中看到,当它解析两个前导空格字符时,它在位置3结束。

但是,当我在xs中使用它时,它会失败,如下所示。

为什么这会失败,什么是处理可能是一个或多个空格的分隔符的好方法?

代码语言:javascript
复制
open FParsec

let test p str =
    match run p str with
    | Success(result, _, p)   -> printfn "Success: %A position = %A" result p
    | Failure(errorMsg, _, _) -> printfn "Failure: %s" errorMsg

let str s = pstringCI s

let w = str "(w)"
let z = str "(z)"

let woz = w <|> z

let isSeparator = manySatisfy (fun c -> c = ' ')
let xs = sepBy woz isSeparator

test isSeparator "  (w)" // Success: "  " position = (Ln: 1, Col: 3)
test xs "(z) (w)"        // Failure: Error in Ln: 1 Col: 8
                         // (z) (w)
                         //        ^
                         // Note: The error occurred at the end of the input stream.                         
                         // Expecting: '(w)' (case-insensitive) or '(z)' (case-insensitive)
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-06-02 03:13:18

之所以会发生这种情况,是因为manySatisfy匹配满足给定谓词的零个或多个字符,关键字是“零”。这意味着,在输入的最后,isSeparator实际上成功了,即使它不使用任何字符。由于isSeparator成功了,sepBy期望在分隔符之后找到woz的另一个实例。但是没有更多的实例,所以sepBy返回一个错误。

要验证这一点,可以尝试解析wztest xs "(z)(w)"之间没有空格的输入。这应该会打印“成功”,因为空分隔符是可以的。

要使isSeparator始终使用至少一个字符并在找不到空格时失败,请使用many1Satisfy而不是manySatisfy

代码语言:javascript
复制
let isSeparator = many1Satisfy (fun c -> c = ' ')
let xs = sepBy woz isSeparator
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50647674

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档