I have the following subexpression to parse 'quotes' which have the following format
"5.75 @ 5.95"
I therefore have this parsec expression to parse it
let pquote x = (sepBy (pfloat) ((spaces .>> (pchar '/' <|> pchar '@' )>>. spaces))) x
It works fine.. except when there is a trailing space in my input, as the separator expression starts to consume content.So I wrapped it around an attempt, which works and seems, from what I understand, more or less what this was meant to be.
let pquote x = (sepBy (pfloat) (attempt (spaces .>> (pchar '/' <|> pchar '@' )>>. spaces))) x
As I dont know fparsec so well, I wonder if there are any better way to write this. it seems a bit heavy (while still being very manageable of course)
let s1 = "5.75 @ 5.95 "
let s2 = "5.75/5.95 "
let pquote: Parser<_> =
pfloat
.>> spaces .>> skipAnyOf ['@'; '/'] .>> spaces
.>>. pfloat
.>> spaces
Notes:
spaces
optional everywherespaces
skips any sequence of zero or more whitespaces, so there's no need to use opt
- thanks @Daniel;type Parser<'t> = Parser<'t, UserState>
- I define it this way in order to avoid "value restriction" error; you may remove it;System.Threading.Thread.CurrentThread.CurrentCulture <- Globalization.CultureInfo.GetCultureInfo "en-US"
sepBy
unless I have a value list of unknown size.'@'
characters), it is recommended to use skip*
functions instead p*
for performance considerations.UPD added slash as separator