4

在 BNF 中表达语法产生式通常很方便,例如

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

其中 ε 表示一个空的产生式规则;即,非终结符“A”可以扩展为终结符“car”、“bike”或什么都没有。但是,除非我重构我的语法,否则我不清楚如何在 FParsec 中表示这样的语法。我知道“选择”组合器,<|>但据我所知,没有“空”组合器。即,返回 true 且不消耗任何输入的组合器。

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

4

2 回答 2

4

我认为杰克的解决方案应该为您解决问题。但是,如果您正在寻找一个表示解析器成功且不消耗任何输入的原语,那么您可能需要preturnfrom FParsec.Primitives(参见preturn文档)。

如果您正在组合构建某些 AST 值而不是字符串的解析器,这可能会很有用。例如,如果您有一个受歧视的工会:

type Vehicle = Car | Bike | Other

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

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

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

于 2013-02-13T03:18:21.997 回答
1

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

let parseA = pstring "car" <|> pstring "bike" <|> pstring ""
于 2013-02-12T01:18:11.360 回答