5

次の形式を持つ「引用符」を解析するための次の部分式があります

"5.75 @ 5.95"

したがって、私はそれを解析するためにこのパーセク式を持っています

let pquote x = (sepBy (pfloat) ((spaces .>> (pchar '/' <|>  pchar '@' )>>. spaces))) x

セパレーター式がコンテンツを消費し始めるため、入力に末尾のスペースがある場合を除いて、正常に動作します。することが。

let pquote x = (sepBy (pfloat) (attempt (spaces .>> (pchar '/' <|>  pchar '@' )>>. spaces))) x

私は fparsec をよく知らないので、これを書くためのより良い方法があるかどうか疑問に思います。それは少し重いようです(もちろん、それでも非常に扱いやすいですが)

4

3 に答える 3

6
let s1 = "5.75         @             5.95              "
let s2 = "5.75/5.95   "
let pquote: Parser<_> =
    pfloat
    .>> spaces .>> skipAnyOf ['@'; '/'] .>> spaces
    .>>. pfloat
    .>> spaces

ノート:

  1. 私はspaces任意の場所で ゼロ個以上の空白spacesのシーケンスをスキップするようにしたので、使用する必要はありません- @Daniel に感謝します。opt
  2. type Parser<'t> = Parser<'t, UserState>- 「値の制限」エラーを回避するために、このように定義します。あなたはそれを取り除くことができます。
  3. また、小数点以下のコンマがあるデフォルトの言語設定でプログラムがシステム上で実行される可能性がある場合は、次のことを忘れないでください。System.Threading.Thread.CurrentThread.CurrentCulture <- Globalization.CultureInfo.GetCultureInfo "en-US"これは機能しません。@Stephan に感謝します。
  4. sepByサイズが不明な値リストがない限り、使用しません。
  5. '@'返される値 (文字など)が本当に必要ない場合は、パフォーマンスを考慮してskip*代わりに関数を使用することをお勧めします。p*

UPDは区切り記号としてスラッシュを追加しました

于 2012-05-04T18:18:02.587 に答える
3

私はおそらくこのようなことをするでしょう、それは戻りますfloat * float

let ws = spaces
let quantity = pfloat .>> ws
let price = pfloat .>> ws
let quoteSep = pstring "@" .>> ws
let quote = quantity .>> quoteSep .>>. price //`.>> eof` (if final parser)

各パーサーが末尾の空白を消費するのが一般的です。トップレベルのパーサーにが含まれていることを確認してくださいeof

于 2012-05-04T16:12:25.187 に答える
1

入力に​​2 つ以上を含めることができfloat、'/' と '@' が区切り文字であると仮定します。

let ws = spaces
let str_ws s = pstring s .>> ws
let float_ws = pfloat .>> ws
let pquote = sepBy float_ws (str_ws "/" <|> str_ws "@")

空白の処理について言えば、FParsec チュートリアルのこのセクションは非常に役に立ちます。

于 2012-05-04T16:21:21.857 に答える