4

BNFで文法の生成を次のように表現すると便利なことがよくあります。

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

ここで、εは空のプロダクションルールを表します。つまり、非終端記号「A」は、終端記号「車」、「自転車」、または何にも拡張できません。ただし、文法をリファクタリングしない限り、FParsecでそのような文法をどのように表現するかはわかりません。私は「選択」コンビネータ<|>を知っていますが、私が知る限り、「空の」コンビネータはありません。つまり、trueを返し、入力を消費しないコンビネータです。

FParsecのドキュメントを高低で検索しましたが、これを行うものは見つかりませんでした。これは一般的なシナリオのように思われるため、驚いています。私はFParsec(および一般的なコンビネータ)にかなり慣れていないので、適切な単語を使用していない可能性があります。ヒントはありますか?

4

2 に答える 2

4

私はジャックの解決策があなたのためにトリックをするべきだと思います。ただし、入力を消費せずに成功するパーサーを表すプリミティブを探している場合は、おそらくfromが必要ですpreturnFParsec.Primitivesドキュメントを参照preturn

文字列の代わりにいくつかの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操作はおそらく直接使用されることはあまりありませんが、基本的なプリミティブの1つです(これは、パーサーのモナディック単位または戻り操作を定義するためです)。

于 2013-02-13T03:18:21.997 に答える
1

私はFParsecにあまり精通していません-私は通常fsyaccを使用します-しかし、choiceコンビネータで空の文字列を使用するとどうなりますか?例:次のようなもの

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