用FParsec解析器组合代表epsilon产品

时间:2013-02-12 01:10:59

标签: parsing f# fparsec

在BNF中表达语法作品通常很方便

A ::= "car"
   |  "bike"
   |  ε

其中ε表示空的生产规则;即,非终端“A”可以扩展到终端“汽车”,“自行车”或什么都没有。但是,除非我重构我的语法,否则我不清楚如何在FParsec中表示这样的语法。我知道'选择'组合子,<|>,但据我所知,没有'空'组合子。即,组合器返回true并且不消耗任何输入。

我搜索了FParsec文档的高低,但我没有发现任何这样做,这让我感到惊讶,因为这似乎是一个常见的场景。我对FParsec(以及一般的组合器)相当新,所以也许我只是没有使用正确的单词。任何提示?

2 个答案:

答案 0 :(得分:4)

我认为杰克的解决方案应该为你做到这一点。但是,如果您正在寻找表示成功的解析器的原语,而不消耗任何输入,那么您可能希望preturn中的FParsec.Primitives(请参阅preturn in the documentation)。

如果您组合使用某些AST而不是字符串构建值的解析器,这可能很有用。例如,如果你有一个有区别的联盟:

type Vehicle = Car | Bike | Other

您可以使用pstring "car" >>% Carpstring "bike" >>% Bike来构建返回Vehicle值的解析器。然后,您可以使用<|>合并它们,并使用preturn添加特殊(空)案例:

let parseA = 
  pstring "car" >>% Car <|> 
  pstring "bike" >>% Bike <|>
  preturn Other

preturn操作可能不经常直接使用,但它是基本原语之一(因为它定义了monadic unit return 操作解析器)。

答案 1 :(得分:1)

我对FParsec不太熟悉 - 我通常使用fsyacc - 但是如果你使用带有选择组合器的空字符串会发生什么?例如:

let parseA = pstring "car" <|> pstring "bike" <|> pstring ""