【问题标题】:how do I handle an optional trailing comma?如何处理可选的尾随逗号?
【发布时间】:2016-11-03 02:43:31
【问题描述】:

鉴于以下

let maxCount = System.Int32.MaxValue
let pmlcomment = pstring "/*" >>. skipCharsTillString "*/" true (maxCount)
let ws = pspaces >>. many (pspaces >>. pmlcomment .>> pspaces) |>> (function | [] -> () | _ -> ())
let str_ws s = pstring s .>> ws
let exprBraceSeqOpt p =
    let trailingComma = (str_ws "," |>> fun _ -> None )
    between (str_ws "{") (str_ws "}") ((opt (attempt (sepBy p (str_ws ",")))) <|> (attempt trailingComma))
let sampleP = exprBraceSeqOpt (str_ws "x")

它正确匹配除了最后一个之外的所有以下内容:

["{}";"{x}";"{x,x}";"{x,x,}"]

我猜有些东西正在改变状态或其他东西。

如何处理 fparsec 中的可选尾随逗号?

【问题讨论】:

  • 应该是opt (attempt trailingComma)
  • 不,不会编译

标签: f# fparsec


【解决方案1】:

sepBy“吃掉”额外的分隔符(如果存在)。这就是它的工作原理,期间。你不能通过在各个地方应用attempt 来破解它:如果你将attempt 应用到分隔符上,它不会有帮助,因为最后一个分隔符实际上成功了,所以attempt 将不起作用。并且将attempt 应用于整个sepBy 也无济于事,因为这样整个sepBy 将被回滚,而不仅仅是最后一个分隔符。并且将attempt 应用于“x”解析器本身,在实现所需的尾随逗号行为的同时,也会产生使解析器连续接受多个逗号的不利影响。

因为通过巧妙地使用组合子不可能达到预期的结果,实际上有一个特殊的功能可以做你所追求的 - sepEndBy

这将按需要工作:

let exprBraceSeqOpt p =
    between (str_ws "{") (str_ws "}") (sepEndBy p (str_ws ","))

另外,顺便说一句,我应该指出function | [] -&gt; () | _ -&gt; () 是一种非常精细的方式来处理ignore。 :-)

【讨论】:

  • 非常好的信息。至于忽略...我将其修剪得很差以供一般消费,我的实际代码中有一些东西=)
猜你喜欢
  • 2017-01-10
  • 2017-08-25
  • 2019-02-12
  • 1970-01-01
  • 1970-01-01
  • 2021-01-25
  • 2014-01-16
  • 2014-07-05
  • 1970-01-01
相关资源
最近更新 更多