在BNF中表达语法作品通常很方便
A ::= "car"
| "bike"
| ε
其中ε表示空的生产规则;即,非终端“A”可以扩展到终端“汽车”,“自行车”或什么都没有。但是,除非我重构我的语法,否则我不清楚如何在FParsec中表示这样的语法。我知道'选择'组合子,<|>
,但据我所知,没有'空'组合子。即,组合器返回true并且不消耗任何输入。
我搜索了FParsec文档的高低,但我没有发现任何这样做,这让我感到惊讶,因为这似乎是一个常见的场景。我对FParsec(以及一般的组合器)相当新,所以也许我只是没有使用正确的单词。任何提示?
答案 0 :(得分:4)
我认为杰克的解决方案应该为你做到这一点。但是,如果您正在寻找表示成功的解析器的原语,而不消耗任何输入,那么您可能希望preturn
中的FParsec.Primitives
(请参阅preturn
in the documentation)。
如果您组合使用某些AST而不是字符串构建值的解析器,这可能很有用。例如,如果你有一个有区别的联盟:
type Vehicle = Car | Bike | Other
您可以使用pstring "car" >>% Car
和pstring "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 ""