/FParsec/CharParsers.fs
F# | 1309 lines | 1078 code | 187 blank | 44 comment | 351 complexity | 4b6e4ccea3f15f27074ae7f96d70c16a MD5 | raw file
Large files files are truncated, but you can click here to view the full file
1// Copyright (c) Stephan Tolksdorf 2007-2009 2// License: Simplified BSD License. See accompanying documentation. 3 4namespace FParsec 5 6module CharParsers 7 8open System.Diagnostics 9open System.Text 10open System.Text.RegularExpressions 11 12open Microsoft.FSharp.NativeInterop 13 14open FParsec.Internals 15open FParsec.Error 16open FParsec.Primitives 17 18#nowarn "9" // "Uses of this construct may result in the generation of unverifiable .NET IL code." 19#nowarn "51" // "The address-of operator may result in non-verifiable code." 20 21// ================ 22// Helper functions 23// ================ 24 25[<Literal>] 26let EOS = CharStream.Iterator.EndOfStreamChar 27 28let foldCase = CharStream.FoldCase 29let normalizeNewlines = CharStream.NormalizeNewlines 30 31let floatToHexString d = Helper.DoubleToHexString(d) 32let floatOfHexString s = Helper.DoubleFromHexString(s) 33 34let float32ToHexString d = Helper.SingleToHexString(d) 35let float32OfHexString s = Helper.SingleFromHexString(s) 36 37// ======================== 38// Running parsers on input 39// ======================== 40 41[<StructuredFormatDisplay("{StructuredFormatDisplay}")>] 42type ParserResult<'Result,'UserState> = 43 | Success of 'Result * 'UserState * Pos 44 | Failure of string * ParserError * 'UserState 45 with 46 member private t.StructuredFormatDisplay = 47 match t with 48 | Success(r,_,_) -> 49 if typeof<'Result> = typeof<unit> then "Success: ()" 50 else sprintf "Success: %A" r 51 | Failure(msg,_,_) -> 52 sprintf "Failure:\n%s" msg 53 54let internal applyParser (parser: Parser<'Result,'UserState>) (state: State<'UserState>) = 55 let reply = parser state 56 if reply.Status = Ok then 57 Success(reply.Result, reply.State.UserState, reply.State.Pos) 58 else 59 let error = ParserError(reply.State.Pos, reply.Error) 60 Failure(error.ToString(reply.State.Stream), error, reply.State.UserState) 61 62let runParser (parser: Parser<'Result,'UserState>) (ustate: 'UserState) (name: string) (stream: CharStream) = 63 let state0 = new State<'UserState>(stream, ustate, name) 64 applyParser parser state0 65 66let runParserOnString (parser: Parser<'Result,'UserState>) (ustate: 'UserState) (streamName: string) (chars: string) = 67 use stream = new CharStream(chars, 0, chars.Length) 68 let state0 = new State<'UserState>(stream, ustate, streamName) 69 applyParser parser state0 70 71let runParserOnSubstring (parser: Parser<'Result,'UserState>) (ustate: 'UserState) (streamName: string) (chars: string) (index: int) length = 72 use stream = new CharStream(chars, index, length) 73 let state0 = new State<'UserState>(stream, ustate, streamName) 74 applyParser parser state0 75 76let runParserOnStream (parser: Parser<'Result,'UserState>) (ustate: 'UserState) (streamName: string) (byteStream: System.IO.Stream) (encoding: System.Text.Encoding) = 77 use stream = new CharStream(byteStream, encoding) 78 let state0 = new State<'UserState>(stream, ustate, streamName) 79 applyParser parser state0 80 81let runParserOnFile (parser: Parser<'Result,'UserState>) (ustate: 'UserState) (path: string) (encoding: System.Text.Encoding) = 82 use stream = new CharStream(path, encoding) 83 let state0 = new State<'UserState>(stream, ustate, path) 84 applyParser parser state0 85 86let runParserOnSubstream (parser: Parser<'Result,'SubstreamUserState>) ustate (stateBeforeSubstream: State<'UserState>) stateAfterSubStream = 87 Helper.RunParserOnSubstream(applyParser parser, ustate, stateBeforeSubstream, stateAfterSubStream) 88 89let run parser (string: string) = 90 runParserOnString parser () "" string 91 92// some predefined error messages 93 94let internal expectedEndOfFile = expectedError "end of file" 95let internal expectedAnyChar = expectedError "any char" 96let internal expectedWhitespace = expectedError "whitespace" 97let internal expectedAsciiUppercaseLetter = expectedError "Ascii uppercase letter" 98let internal expectedAsciiLowercaseLetter = expectedError "Ascii lowercase letter" 99let internal expectedAsciiLetter = expectedError "Ascii letter" 100let internal expectedUppercaseLetter = expectedError "uppercase letter" 101let internal expectedLowercaseLetter = expectedError "lowercase letter" 102let internal expectedLetter = expectedError "letter" 103let internal expectedBinaryDigit = expectedError "binary digit" 104let internal expectedOctalDigit = expectedError "octal digit" 105let internal expectedDecimalDigit = expectedError "digit" 106let internal expectedHexadecimalDigit = expectedError "hexadecimal digit" 107let internal expectedNewline = expectedError "newline" 108let internal expectedTab = expectedError "tab" 109let internal expectedFloatingPointNumber = expectedError "floating-point number" 110let internal expectedInt64 = expectedError "integer number (64-bit, signed)" 111let internal expectedInt32 = expectedError "integer number (32-bit, signed)" 112let internal expectedInt16 = expectedError "integer number (16-bit, signed)" 113let internal expectedInt8 = expectedError "integer number (8-bit, signed)" 114let internal expectedUInt64 = expectedError "integer number (64-bit, unsigned)" 115let internal expectedUInt32 = expectedError "integer number (32-bit, unsigned)" 116let internal expectedUInt16 = expectedError "integer number (16-bit, unsigned)" 117let internal expectedUInt8 = expectedError "integer number (8-bit, unsigned)" 118 119let internal unexpectedNewline = unexpectedError "newline" 120let internal unexpectedEndOfFile = unexpectedError "end of file" 121 122// ======= 123// Parsers 124// ======= 125 126// ------------------------------------------------ 127// Reading the position and handling the user state 128// ------------------------------------------------ 129 130let getPos : Parser<Pos,'u> = 131 fun state -> Reply<_,_>(state.Pos, state) 132 133let getUserState : Parser<'u,'u> = 134 fun state -> Reply<_,_>(state.UserState, state) 135 136let setUserState (newUserState: 'u) : Parser<unit,'u> = 137 fun state -> Reply<_,_>((), state.WithUserState(newUserState)) 138 139let updateUserState (f: 'u -> 'u) : Parser<unit,'u> = 140 fun state -> Reply<_,_>((), state.WithUserState(f state.UserState)) 141 142let userStateSatisfies f : Parser<unit,'u> = 143 fun state -> 144 Reply<unit,_>((if f state.UserState then Ok else Error), NoErrorMessages, state) 145 146// -------------------- 147// Parsing single chars 148// -------------------- 149 150// needs to be inline because of the value restriction 151let inline internal inlineNewlineReturn result : Parser<_,'u> = 152 fun state -> 153 let newState = state.SkipNewline() 154 if not (referenceEquals state newState) then 155 Reply<_,_>(result, newState) 156 else 157 Reply<_,_>(Error, expectedNewline, newState) 158 159let newlineReturn result = fun state -> inlineNewlineReturn result state 160let newline = fun state -> inlineNewlineReturn '\n' state 161let skipNewline = fun state -> inlineNewlineReturn () state 162 163let charReturn c result : Parser<'a,'u> = 164 if c <> '\r' && c <> '\n' then 165 let error = expectedError (quoteChar c) 166 fun state -> 167 if state.Iter.Match(c) then Reply<_,_>(result, state.Next) 168 else Reply<_,_>(Error, error, state) 169 else newlineReturn result 170 171let pchar c = charReturn c c 172let skipChar c = charReturn c () 173 174 175/// returns true for chars '\u000E' - '\ufffe' 176let inline internal isCertainlyNoNLOrEOS (c: char) = 177 // '\n' = '\u000A', '\r' = '\u000D' 178 unativeint c - 0xEun < unativeint EOS - 0xEun 179 180let anyChar : Parser<char,'u> = 181 fun state -> 182 let c = state.Iter.Read() 183 if isCertainlyNoNLOrEOS c then 184 Reply<_,_>(c, state.Next) 185 elif c = '\r' || c = '\n' then 186 Reply<_,_>('\n', state.SkipNewline()) 187 elif c <> EOS then 188 Reply<_,_>(c, state.Next) 189 else 190 Reply<_,_>(Error, expectedAnyChar, state) 191 192let skipAnyChar : Parser<unit,'u> = 193 fun state -> 194 let newState = state.SkipCharOrNewline() 195 if not (referenceEquals state newState) then 196 Reply<_,_>((), newState) 197 else 198 Reply<_,_>(Error, expectedAnyChar, newState) 199 200 201// doesn't check for newlines or EOS 202let inline internal fastInlineSatisfyE f error : Parser<char,'u> = 203 fun state -> 204 let c = state.Iter.Read() 205 if f c then Reply<_,_>(c, state.Next) 206 else Reply<_,_>(Error, error, state) 207 208let inline internal fastInlineSkipSatisfyE f error : Parser<unit,'u> = 209 fun state -> 210 let c = state.Iter.Read() 211 if f c then Reply<_,_>((), state.Next) 212 else Reply<_,_>(Error, error, state) 213 214let inline internal inlineSatisfyE f error : Parser<char,'u> = 215 fun state -> 216 let c = state.Iter.Read() 217 if isCertainlyNoNLOrEOS c then 218 if f c then Reply<_,_>(c, state.Next) 219 else Reply<_,_>(Error, error, state) 220 elif c = '\r' || c = '\n' then 221 if f '\n' then Reply<_,_>('\n', state.SkipNewline()) 222 else Reply<_,_>(Error, error, state) 223 elif c <> EOS && f c then Reply<_,_>(c, state.Next) 224 else Reply<_,_>(Error, error, state) 225 226let inline internal inlineSkipSatisfyE f error : Parser<unit,'u> = 227 fun state -> 228 let c = state.Iter.Read() 229 if isCertainlyNoNLOrEOS c then 230 if f c then Reply<_,_>((), state.Next) 231 else Reply<_,_>(Error, error, state) 232 elif c = '\r' || c = '\n' then 233 if f '\n' then Reply<_,_>((), state.SkipNewline()) 234 else Reply<_,_>(Error, error, state) 235 elif c <> EOS && f c then Reply<_,_>((), state.Next) 236 else Reply<_,_>(Error, error, state) 237 238let internal satisfyE f error = inlineSatisfyE f error 239let internal skipSatisfyE f error = inlineSkipSatisfyE f error 240 241let satisfy f = satisfyE f NoErrorMessages 242let satisfyL f label = satisfyE f (expectedError label) 243 244let skipSatisfy f = skipSatisfyE f NoErrorMessages 245let skipSatisfyL f label = skipSatisfyE f (expectedError label) 246 247 248let isAnyOf (chars: string) = 249 let cs = new FParsec.Helper.CharSet(chars) 250 fun c -> cs.Contains(c) 251 252let isNoneOf (chars: string) = 253 let cs = new FParsec.Helper.CharSet(chars) 254 fun c -> not (cs.Contains(c)) 255 256let anyOf (chars: string) = 257 let error = expectedError ("any char in " + quoteString chars) 258 let cs = new FParsec.Helper.CharSet(chars) 259 inlineSatisfyE (fun c -> cs.Contains(c)) error 260 261let skipAnyOf (chars: string) = 262 let error = expectedError ("any char in " + quoteString chars) 263 let cs = new FParsec.Helper.CharSet(chars) 264 inlineSkipSatisfyE (fun c -> cs.Contains(c)) error 265 266let noneOf (chars: string) = 267 let error = expectedError ("any char not in " + quoteString chars) 268 let cs = new FParsec.Helper.CharSet(chars) 269 inlineSatisfyE (fun c -> not (cs.Contains(c))) error 270 271let skipNoneOf (chars: string) = 272 let error = expectedError ("any char not in " + quoteString chars) 273 let cs = new FParsec.Helper.CharSet(chars) 274 inlineSkipSatisfyE (fun c -> not (cs.Contains(c))) error 275 276 277let inline isAsciiUpper c = c >= 'A' && c <= 'Z' 278let inline isAsciiLower c = c >= 'a' && c <= 'z' 279let inline isAsciiLetter (c: char) = let c2 = int c ||| int ' ' 280 c2 >= int 'a' && c2 <= int 'z' 281 282let inline isUpper c = 283 if c >= 'A' then 284 c <= 'Z' || (c > '\u007F' && System.Char.IsUpper(c)) 285 else false 286 287let inline isLower c = 288 if c >= 'a' then 289 c <= 'z' || (c > '\u007F' && System.Char.IsLower(c)) 290 else false 291 292let inline isLetter c = 293 if c <= '\u007F' then 294 let c2 = int c ||| int ' ' 295 c2 >= int 'a' && c2 <= int 'z' 296 else System.Char.IsLetter(c) 297 298let inline isDigit c = c <= '9' && c >= '0' 299 300let inline isHex c = 301 if c <= '9' then c >= '0' 302 else c <= 'f' && (c >= 'a' || (c >= 'A' && c <= 'F')) 303 304let inline isOctal c = c <= '7' && c >= '0' 305 306let asciiUpper state = fastInlineSatisfyE isAsciiUpper expectedAsciiUppercaseLetter state 307let asciiLower state = fastInlineSatisfyE isAsciiLower expectedAsciiLowercaseLetter state 308let asciiLetter state = fastInlineSatisfyE isAsciiLetter expectedAsciiLetter state 309 310// unicode is the default for letters and ascii the default for numbers 311let upper state = fastInlineSatisfyE isUpper expectedUppercaseLetter state 312let lower state = fastInlineSatisfyE isLower expectedLowercaseLetter state 313let letter state = fastInlineSatisfyE isLetter expectedLetter state 314 315let digit state = fastInlineSatisfyE isDigit expectedDecimalDigit state 316let hex state = fastInlineSatisfyE isHex expectedHexadecimalDigit state 317let octal state = fastInlineSatisfyE isOctal expectedOctalDigit state 318 319let tab state = fastInlineSatisfyE ((=) '\t') expectedTab state 320 321let unicodeNewline : Parser<_,'u> = 322 fun state -> 323 let c = state.Iter.Read() 324 if c < '\u0085' then 325 if c = '\r' || c = '\n' then 326 Reply<_,_>('\n', state.SkipNewline()) 327 elif c <> '\u000C' then 328 Reply<_,_>(Error, expectedNewline, state) 329 else // c = '\u000C' 330 Reply<_,_>('\n', state.Advance(1, 1, 0)) 331 elif c <= '\u2029' && (c >= '\u2028' || c = '\u0085') then 332 Reply<_,_>('\n', state.Advance(1, 1, 0)) 333 else 334 Reply<_,_>(Error, expectedNewline, state) 335 336let whitespace : Parser<char,'u> = 337 fun state -> 338 let c = state.Iter.Read() 339 if c <= ' ' then 340 match c with 341 | ' ' | '\t' -> Reply<_,_>(c, state.Next) 342 | '\r' | '\n' -> Reply<_,_>('\n', state.SkipNewline()) 343 | _ -> Reply<_,_>(Error, expectedWhitespace, state) 344 else Reply<_,_>(Error, expectedWhitespace, state) 345 346let unicodeWhitespace : Parser<char,'u> = 347 fun state -> 348 let c = state.Iter.Read() 349 if c = ' ' then Reply<_,_>(c, state.Next) 350 elif System.Char.IsWhiteSpace(c) then 351 match c with 352 | '\r' | '\n' -> 353 Reply<_,_>('\n', state.SkipNewline()) 354 | '\u000C' | '\u0085' | '\u2028' | '\u2029' -> 355 Reply<_,_>('\n', state.Advance(1, 1, 0)) 356 | _ -> 357 Reply<_,_>(c, state.Next) 358 else Reply<_,_>(Error, expectedWhitespace, state) 359 360 361let spaces : Parser<unit,'u> = 362 fun state -> 363 Reply<_,_>((), state.SkipWhitespace()) 364 365let spaces1 : Parser<unit,'u> = 366 fun state -> 367 let newState = state.SkipWhitespace() 368 if not (referenceEquals newState state) then Reply<_,_>((), newState) 369 else Reply<_,_>(Error, expectedWhitespace, newState) 370 371let eof : Parser<unit,'u>= 372 fun state -> 373 if state.Iter.IsEndOfStream then Reply<_,_>((), state) 374 else Reply<_,_>(Error, expectedEndOfFile, state) 375 376 377// ------------------------ 378// Parsing strings directly 379// ------------------------ 380 381let internal checkStringContainsNoNewlineChar s name = 382 if containsNewlineChar s then 383 raise (System.ArgumentException(concat3 "The string argument to " name " may not contain newline chars ('\r' or '\n').")) 384 385let stringReturn s result : Parser<'a,'u> = 386 checkStringContainsNoNewlineChar s "pstring/skipString/stringReturn" 387 let error = expectedError (quoteString s) 388 fun state -> 389 if state.Iter.Match(s) then Reply<_,_>(result, state.Advance(s.Length)) 390 else Reply<_,_>(Error, error, state) 391let pstring s = stringReturn s s 392let skipString s = stringReturn s () 393 394 395let pstringCI s : Parser<string,'u> = 396 checkStringContainsNoNewlineChar s "pstringCI" 397 let error = expectedError (quoteString s + " (case-insensitive)") 398 let cfs = foldCase s 399 fun state -> 400 if state.Iter.MatchCaseFolded(cfs) then 401 Reply<_,_>(state.Iter.Read(s.Length), state.Advance(s.Length)) 402 else Reply<_,_>(Error, error, state) 403 404let stringCIReturn s result : Parser<'a,'u> = 405 checkStringContainsNoNewlineChar s "skipStringCI/stringCIReturn" 406 let error = expectedError (quoteString s + " (case-insensitive)") 407 let cfs = foldCase s 408 fun state -> 409 if state.Iter.MatchCaseFolded(cfs) then 410 Reply<_,_>(result, state.Advance(s.Length)) 411 else Reply<_,_>(Error, error, state) 412 413let skipStringCI s = stringCIReturn s () 414 415 416let anyString n : Parser<string,'u> = 417 let error = expectedError (concat3 "any sequence of " (string n) " chars") 418 fun state -> 419 let mutable str = null 420 let newState = state.SkipCharsOrNewlines(n, &str) 421 if str.Length = n then Reply<_,_>(str, newState) 422 else Reply<_,_>(Error, error, state) 423 424let skipAnyString n : Parser<unit,'u> = 425 let error = expectedError (concat3 "any sequence of " (string n) " chars") 426 fun state -> 427 let mutable nSkipped = 0 428 let newState = state.SkipCharsOrNewlines(n, &nSkipped) 429 if n = nSkipped then Reply<_,_>((), newState) 430 else Reply<_,_>(Error, error, state) 431 432let restOfLine : Parser<_,_> = 433 fun state -> 434 let mutable str = null 435 let newState = state.SkipRestOfLine(true, &str) 436 Reply<_,_>(str, newState) 437 438let skipRestOfLine : Parser<_,_> = 439 fun state -> 440 Reply<_,_>((), state.SkipRestOfLine(true)) 441 442let skipToEndOfLine : Parser<_,_> = 443 fun state -> 444 Reply<_,_>((), state.SkipRestOfLine(false)) 445 446 447let skipToString (s: string) maxChars : Parser<unit,'u> = 448 checkStringContainsNoNewlineChar s "skipToString" 449 if maxChars < 0 then raise (System.ArgumentOutOfRangeException("maxChars", "maxChars is negative.")) 450 let error = messageError (concat3 "Could not find the string " (quoteString s) ".") 451 fun state -> 452 let mutable foundString = false 453 let state2 = state.SkipToString(s, maxChars, &foundString) 454 if foundString then Reply<_,_>((), state2) 455 else Reply<_,_>(Error, error, state2) 456 457let skipToStringCI (s: string) maxChars : Parser<unit,'u> = 458 checkStringContainsNoNewlineChar s "skipToStringCI" 459 if maxChars < 0 then raise (System.ArgumentOutOfRangeException("maxChars", "maxChars is negative.")) 460 let cfs = foldCase s 461 let error = messageError (concat3 "Could not find the case-insensitive string " (quoteString s) ".") 462 fun state -> 463 let mutable foundString = false 464 let state2 = state.SkipToStringCI(cfs, maxChars, &foundString) 465 if foundString then Reply<_,_>((), state2) 466 else Reply<_,_>(Error, error, state2) 467 468let charsTillString (s: string) maxChars : Parser<string,'u> = 469 checkStringContainsNoNewlineChar s "charsTillString" 470 if maxChars < 0 then raise (System.ArgumentOutOfRangeException("maxChars", "maxChars is negative.")) 471 let error = messageError (concat3 "Could not find the string " (quoteString s) ".") 472 fun state -> 473 let mutable charsBeforeString = null 474 let state2 = state.SkipToString(s, maxChars, &charsBeforeString) 475 if isNotNull charsBeforeString then Reply<_,_>(charsBeforeString, state2.Advance(s.Length)) 476 else Reply<_,_>(Error, error, state2) 477 478let charsTillStringCI (s: string) maxChars : Parser<string,'u> = 479 checkStringContainsNoNewlineChar s "charsTillStringCI" 480 if maxChars < 0 then raise (System.ArgumentOutOfRangeException("maxChars", "maxChars is negative.")) 481 let cfs = foldCase s 482 let error = messageError (concat3 "Could not find the case-insensitive string " (quoteString s) ".") 483 fun state -> 484 let mutable charsBeforeString = null 485 let state2 = state.SkipToStringCI(cfs, maxChars, &charsBeforeString) 486 if isNotNull charsBeforeString then Reply<_,_>(charsBeforeString, state2.Advance(s.Length)) 487 else Reply<_,_>(Error, error, state2) 488 489let skipCharsTillString (s: string) maxChars : Parser<unit,'u> = 490 checkStringContainsNoNewlineChar s "skipCharsTillString" 491 if maxChars < 0 then raise (System.ArgumentOutOfRangeException("maxChars", "maxChars is negative.")) 492 let error = messageError (concat3 "Could not find the string " (quoteString s) ".") 493 fun state -> 494 let mutable foundString = false 495 let state2 = state.SkipToString(s, maxChars, &foundString) 496 if foundString then Reply<_,_>((), state2.Advance(s.Length)) 497 else Reply<_,_>(Error, error, state2) 498 499let skipCharsTillStringCI (s: string) maxChars : Parser<unit,'u> = 500 checkStringContainsNoNewlineChar s "skipCharsTillStringCI" 501 if maxChars < 0 then raise (System.ArgumentOutOfRangeException("maxChars", "maxChars is negative.")) 502 let cfs = foldCase s 503 let error = messageError (concat3 "Could not find the case-insensitive string " (quoteString s) ".") 504 fun state -> 505 let mutable foundString = false 506 let state2 = state.SkipToStringCI(cfs, maxChars, &foundString) 507 if foundString then Reply<_,_>((), state2.Advance(s.Length)) 508 else Reply<_,_>(Error, error, state2) 509 510 511let inline internal manySatisfyImpl require1 f1 f error : Parser<string,'u> = 512 fun state -> 513 let mutable str = null 514 let newState = state.SkipCharsOrNewlinesWhile(f1, f, &str) 515 if not require1 || not (referenceEquals newState state) then Reply<_,_>(str, newState) 516 else Reply<_,_>(Error, error, newState) 517 518let inline internal skipManySatisfyImpl require1 f1 f error : Parser<unit,'u> = 519 fun state -> 520 let newState = state.SkipCharsOrNewlinesWhile(f1, f) 521 if not require1 || not (referenceEquals newState state) then Reply<_,_>((), newState) 522 else Reply<_,_>(Error, error, newState) 523 524let manySatisfy2 f1 f = manySatisfyImpl false f1 f NoErrorMessages 525let many1Satisfy2 f1 f = manySatisfyImpl true f1 f NoErrorMessages 526let many1Satisfy2L f1 f label = manySatisfyImpl true f1 f (expectedError label) 527 528let skipManySatisfy2 f1 f = skipManySatisfyImpl false f1 f NoErrorMessages 529let skipMany1Satisfy2 f1 f = skipManySatisfyImpl true f1 f NoErrorMessages 530let skipMany1Satisfy2L f1 f label = skipManySatisfyImpl true f1 f (expectedError label) 531 532let manySatisfy f = manySatisfy2 f f 533let many1Satisfy f = many1Satisfy2 f f 534let many1SatisfyL f label = many1Satisfy2L f f label 535 536let skipManySatisfy f = skipManySatisfy2 f f 537let skipMany1Satisfy f = skipMany1Satisfy2 f f 538let skipMany1SatisfyL f label = skipMany1Satisfy2L f f label 539 540 541let internal manyMinMaxSatisfy2E minChars maxChars f1 f error : Parser<string,'u> = 542 if maxChars < 0 then raise (System.ArgumentOutOfRangeException("maxChars", "maxChars is negative.")) 543 if minChars > 0 then 544 fun state -> 545 let mutable str = null 546 let newState = state.SkipCharsOrNewlinesWhile(f1, f, minChars, maxChars, &str) 547 if not (referenceEquals newState state) then Reply<_,_>(str, newState) 548 else Reply<_,_>(Error, error, newState) 549 else 550 fun state -> 551 let mutable str = null 552 let newState = state.SkipCharsOrNewlinesWhile(f1, f, 0, maxChars, &str) 553 Reply<_,_>(str, newState) 554 555let internal skipManyMinMaxSatisfy2E minChars maxChars f1 f error : Parser<unit,'u> = 556 if maxChars < 0 then raise (System.ArgumentOutOfRangeException("maxChars", "maxChars is negative.")) 557 if minChars > 0 then 558 fun state -> 559 let newState = state.SkipCharsOrNewlinesWhile(f1, f, minChars, maxChars) 560 if not (referenceEquals newState state) then Reply<_,_>((), newState) 561 else Reply<_,_>(Error, error, newState) 562 else 563 fun state -> 564 let mutable str = null 565 let newState = state.SkipCharsOrNewlinesWhile(f1, f, 0, maxChars) 566 Reply<_,_>((), newState) 567 568let manyMinMaxSatisfy minChars maxChars f = manyMinMaxSatisfy2E minChars maxChars f f NoErrorMessages 569let manyMinMaxSatisfyL minChars maxChars f label = manyMinMaxSatisfy2E minChars maxChars f f (expectedError label) 570let manyMinMaxSatisfy2 minChars maxChars f1 f = manyMinMaxSatisfy2E minChars maxChars f1 f NoErrorMessages 571let manyMinMaxSatisfy2L minChars maxChars f1 f label = manyMinMaxSatisfy2E minChars maxChars f1 f (expectedError label) 572 573let skipManyMinMaxSatisfy minChars maxChars f = skipManyMinMaxSatisfy2E minChars maxChars f f NoErrorMessages 574let skipManyMinMaxSatisfyL minChars maxChars f label = skipManyMinMaxSatisfy2E minChars maxChars f f (expectedError label) 575let skipManyMinMaxSatisfy2 minChars maxChars f1 f = skipManyMinMaxSatisfy2E minChars maxChars f1 f NoErrorMessages 576let skipManyMinMaxSatisfy2L minChars maxChars f1 f label = skipManyMinMaxSatisfy2E minChars maxChars f1 f (expectedError label) 577 578 579let internal regexE pattern error : Parser<string,'u> = 580 let regex = new Regex("\A" + pattern, RegexOptions.Multiline ||| 581 RegexOptions.ExplicitCapture) 582 fun state -> 583 let m = state.Iter.Match(regex) 584 if m.Success then 585 let s = m.Value 586 if not (containsNewlineChar s) then Reply<_,_>(s, if s.Length > 0 then state.Advance(s.Length) else state) 587 else 588 let s2 = normalizeNewlines s 589 let mutable nSkippedChars = 0 590 let newState = state.SkipCharsOrNewlines(s2.Length, &nSkippedChars) 591 if nSkippedChars = s2.Length then Reply<_,_>(s2, newState) 592 else Reply<_,_>(FatalError, messageError "Internal error in the regex parser. Please report this error to fparsec@quanttec.com.", newState) 593 else Reply<_,_>(Error, error, state) 594 595let regex pattern = regexE pattern (expectedError ("string matching the regex " + quoteString pattern)) 596let regexL pattern label = regexE pattern (expectedError label) 597 598// ---------------------------------------------- 599// Parsing strings with the help of other parsers 600// ---------------------------------------------- 601 602type internal StructCharList = struct 603 val mutable buffer_ui64_0: uint64 604 val mutable buffer_ui64_1: uint64 605 val mutable buffer_ui64_2: uint64 606 val mutable buffer_ui64_3: uint64 607 608 val mutable chars: char[] 609 val mutable count: int 610 611 member inline t.BufferPtr = 612 NativePtr.of_nativeint<char> (NativePtr.to_nativeint (&&t.buffer_ui64_0)) 613 614 /// an optimized version of Append(c) for the first char 615 member inline t.AppendFirst(c) = 616 Debug.Assert(t.count = 0) 617 let p = t.BufferPtr 618 NativePtr.set p 0 c 619 t.count <- 1 620 621 member inline t.Append(c) = 622 let i = t.count &&& 0xf 623 t.count <- t.count + 1 624 if i <> 0 then 625 let p = t.BufferPtr 626 NativePtr.set p i c 627 else 628 t._AppendContinue(c) 629 630 /// append char with index%16 = 0 631 member t._AppendContinue(c) = 632 let p = t.BufferPtr 633 let count = t.count - 1 634 Debug.Assert(count%16 = 0 || count = -1) 635 let mutable chars = t.chars 636 if isNotNull chars then 637 if count = chars.Length then 638 let newChars = Array.zeroCreate (count*2) 639 System.Buffer.BlockCopy(chars, 0, newChars, 0, (count - 16)*sizeof<char>) 640 t.chars <- newChars 641 chars <- newChars 642 for i = 0 to 15 do 643 chars.[count - 16 + i] <- NativePtr.get p i 644 elif count <> 0 then 645 chars <- Array.zeroCreate 48 646 t.chars <- chars 647 for i = 0 to 15 do 648 chars.[i] <- NativePtr.get p i 649 NativePtr.set p 0 c 650 651 override t.ToString() = 652 let p = t.BufferPtr 653 let count = t.count 654 if count <= 16 then new string(p, 0, count) 655 else 656 let chars = t.chars 657 for i = (count - 1) &&& 0x7ffffff0 to count - 1 do 658 chars.[i] <- NativePtr.get p (i &&& 0xf) 659 new string(chars, 0, count) 660end 661 662 663let inline internal manyCharsImpl require1 (p1: Parser<char,'u>) (p: Parser<char,'u>) : Parser<string,'u> = 664 fun state -> 665 let mutable reply = p1 state 666 if reply.Status = Ok then 667 let mutable cl = new StructCharList() 668 cl.AppendFirst(reply.Result) 669 let mutable state = reply.State 670 reply <- p state 671 while reply.Status = Ok do 672 if referenceEquals reply.State state then 673 _raiseInfiniteLoopException "manyChars" state 674 cl.Append(reply.Result) 675 state <- reply.State 676 reply <- p state 677 let error = if reply.State == state then reply.Error 678 else backtrackError reply.State reply.Error 679 Reply<_,_>(Ok, cl.ToString(), error, state) 680 else 681 let error = if reply.State == state then reply.Error 682 else backtrackError reply.State reply.Error 683 if require1 then Reply<_,_>(Error, error, state) 684 else Reply<_,_>(Ok, "", error, state) 685 686let inline internal skipManyCharsImpl require1 (p1: Parser<'a,'u>) (p: Parser<'a,'u>) : Parser<unit,'u> = 687 fun state -> 688 let mutable reply = p1 state 689 if reply.Status = Ok then 690 let mutable state = reply.State 691 reply <- p state 692 while reply.Status = Ok do 693 if referenceEquals reply.State state then 694 _raiseInfiniteLoopException "skipManyChars" state 695 state <- reply.State 696 reply <- p state 697 let error = if reply.State == state then reply.Error 698 else backtrackError reply.State reply.Error 699 Reply<_,_>(Ok, (), error, state) 700 else 701 let error = if reply.State == state then reply.Error 702 else backtrackError reply.State reply.Error 703 if require1 then Reply<_,_>(Error, error, state) 704 else Reply<_,_>(Ok, (), error, state) 705 706 707let manyChars2 p1 p = manyCharsImpl false p1 p 708let manyChars p = manyChars2 p p 709 710let many1Chars2 p1 p = manyCharsImpl true p1 p 711let many1Chars p = many1Chars2 p p 712 713let skipManyChars2 (p1: Parser<'a,'u>) (p: Parser<'a,'u>) = skipManyCharsImpl false p1 p 714let skipManyChars p = skipManyChars2 p p 715 716let skipMany1Chars2 (p1: Parser<'a,'u>) (p: Parser<'a,'u>) = skipManyCharsImpl true p1 p 717let skipMany1Chars p = skipMany1Chars2 p p 718 719 720let inline inlineManyCharsTillApply (p: Parser<char,'u>) (endp: Parser<'b,'u>) (f: string -> 'b -> 'c) = 721 fun state -> 722 let mutable state = state 723 let mutable reply2 = endp state 724 if reply2.Status <> Ok then 725 let mutable reply1 = p state 726 let mutable cl = new StructCharList() 727 if reply1.Status = Ok then 728 cl.AppendFirst(reply1.Result) 729 state <- reply1.State 730 reply2 <- endp state 731 while reply2.Status <> Ok && (reply1 <- p state; reply1.Status = Ok) do 732 if referenceEquals reply1.State state then 733 _raiseInfiniteLoopException "manyCharsTill" state 734 cl.Append(reply1.Result) 735 state <- reply1.State 736 reply2 <- endp state 737 if reply2.Status = Ok then 738 let error = if not (referenceEquals reply2.State state) then reply2.Error 739 else mergeErrors reply1.Error reply2.Error 740 Reply<_,_>(Ok, f (cl.ToString()) reply2.Result, error, reply2.State) 741 elif reply1.Status = Error && reply1.State == state then 742 let error = if reply2.State != state then reply2.Error 743 else mergeErrors reply1.Error reply2.Error 744 Reply<_,_>(reply2.Status, error, reply2.State) 745 else 746 Reply<_,_>(reply1.Status, reply1.Error, reply1.State) 747 else 748 Reply<_,_>(Ok, f "" reply2.Result, reply2.Error, reply2.State) 749 750let inline inlineMany1CharsTill2Apply (p1: Parser<char,'u>) (p: Parser<char,'u>) (endp: Parser<'b,'u>) (f: string -> 'b -> 'c) = 751 fun state -> 752 let mutable reply1 = p1 state 753 if reply1.Status = Ok then 754 let mutable cl = new StructCharList() 755 cl.AppendFirst(reply1.Result) 756 let mutable state = reply1.State 757 let mutable reply2 = endp state 758 while reply2.Status <> Ok && (reply1 <- p state; reply1.Status = Ok) do 759 if referenceEquals reply1.State state then 760 _raiseInfiniteLoopException "manyCharsTill" state 761 cl.Append(reply1.Result) 762 state <- reply1.State 763 reply2 <- endp state 764 if reply2.Status = Ok then 765 let error = if not (referenceEquals reply2.State state) then reply2.Error 766 else mergeErrors reply1.Error reply2.Error 767 Reply<_,_>(Ok, f (cl.ToString()) reply2.Result, error, reply2.State) 768 elif reply1.Status = Error && reply1.State == state then 769 let error = if reply2.State != state then reply2.Error 770 else mergeErrors reply1.Error reply2.Error 771 Reply<_,_>(reply2.Status, error, reply2.State) 772 else 773 Reply<_,_>(reply1.Status, reply1.Error, reply1.State) 774 else 775 Reply<_,_>(reply1.Status, reply1.Error, reply1.State) 776 777 778let manyCharsTill p endp = inlineManyCharsTillApply p endp (fun str _ -> str) 779let manyCharsTillApply p endp f = let optF = OptimizedClosures.FastFunc2.Adapt(f) 780 inlineManyCharsTillApply p endp (fun str x -> optF.Invoke(str, x)) 781let skipManyCharsTill p endp = skipManyTill p endp 782 783let many1CharsTill2 p1 p endp = inlineMany1CharsTill2Apply p1 p endp (fun str _ -> str) 784let many1CharsTillApply2 p1 p endp f = let optF = OptimizedClosures.FastFunc2.Adapt(f) 785 inlineMany1CharsTill2Apply p1 p endp (fun str x -> optF.Invoke(str, x)) 786let many1CharsTill p endp = many1CharsTill2 p p endp 787let many1CharsTillApply p endp f = many1CharsTillApply2 p p endp f 788 789let skipMany1CharsTill2 (p1: Parser<'a,'u>) (p: Parser<'a,'u>) endp = p1 >>. skipManyTill p endp 790let skipMany1CharsTill p endp = skipMany1CharsTill2 p p endp 791 792 793let inline manyStringsImpl require1 (p1: Parser<string,'u>) (p: Parser<string,'u>) : Parser<string,'u> = 794 fun state -> 795 let mutable reply = p1 state 796 if reply.Status = Ok then 797 let result1 = reply.Result 798 let mutable error = reply.Error 799 let mutable state = reply.State 800 reply <- p state 801 if reply.Status <> Ok then reply.Result <- result1 802 else 803 let result2 = reply.Result 804 error <- reply.Error 805 state <- reply.State 806 reply <- p state 807 if reply.Status <> Ok then reply.Result <- result1 + result2 808 else 809 let result3 = reply.Result 810 error <- reply.Error 811 state <- reply.State 812 reply <- p state 813 if reply.Status <> Ok then reply.Result <- concat3 result1 result2 result3 814 else 815 let result4 = reply.Result 816 error <- reply.Error 817 state <- reply.State 818 reply <- p state 819 if reply.Status <> Ok then reply.Result <- concat4 result1 result2 result3 result4 820 else 821 let n = 2*(result1.Length + result2.Length + result3.Length + result4.Length) + reply.Result.Length 822 let sb = new StringBuilder(n) 823 sb.Append(result1).Append(result2).Append(result3).Append(result4).Append(reply.Result) |> ignore 824 error <- reply.Error 825 state <- reply.State 826 reply <- p state 827 while reply.Status = Ok do 828 if reply.State == state then 829 _raiseInfiniteLoopException "manyStrings" state 830 error <- reply.Error 831 sb.Append(reply.Result) |> ignore 832 state <- reply.State 833 reply <- p state 834 reply.Result <- sb.ToString() 835 // we assume that the string parser changes the state when it succeeds, so we don't need to merge more than one error 836 if reply.Status = Error then 837 if reply.State == state then 838 reply.Status <- Ok 839 if isNotNull error then 840 reply.Error <- concatErrorMessages error reply.Error 841 else 842 reply.Error <- mergeErrorsIfNeeded state error reply.State reply.Error 843 elif not require1 && reply.Status = Error && reply.State == state then 844 reply.Status <- Ok 845 reply.Result <- "" 846 reply 847 848let manyStrings2 p1 p = manyStringsImpl false p1 p 849let manyStrings p = manyStrings2 p p 850let many1Strings2 p1 p = manyStringsImpl true p1 p 851let many1Strings p = many1Strings2 p p 852 853 854let skipped (p: Parser<unit,'u>) : Parser<string,'u> = 855 fun state -> 856 let reply = p state 857 let result = if reply.Status = Ok then state.ReadUntil(reply.State) else "" 858 Reply<_,_>(reply.Status, result, reply.Error, reply.State) 859 860let withSkippedString (f: string -> 'a -> 'b) (p: Parser<'a,'u>) : Parser<'b,'u> = 861 let optF = OptimizedClosures.FastFunc2<_,_,_>.Adapt(f) 862 fun state -> 863 let reply = p state 864 let result = if reply.Status = Ok then 865 optF.Invoke(state.ReadUntil(reply.State), reply.Result) 866 else Unchecked.defaultof<_> 867 Reply<_,_>(reply.Status, result, reply.Error, reply.State) 868 869 870// --------------- 871// Parsing numbers 872// --------------- 873 874[<System.Flags>] 875type NumberLiteralOptions = 876 | None = 0 877 | AllowSuffix = 0b000000000001 878 | AllowMinusSign = 0b000000000010 879 | AllowPlusSign = 0b000000000100 880 | AllowFraction = 0b000000001000 881 | AllowFractionWOIntegerPart = 0b000000010000 882 | AllowExponent = 0b000000100000 883 | AllowHexadecimal = 0b000001000000 884 | AllowBinary = 0b000010000000 885 | AllowOctal = 0b000100000000 886 | AllowInfinity = 0b001000000000 887 | AllowNaN = 0b010000000000 888 889 | DefaultInteger = 0b000111000110 890 | DefaultUnsignedInteger = 0b000111000000 891 | DefaultFloat = 0b011001101110 892 893type internal NLO = NumberLiteralOptions 894 895[<System.Flags>] 896type NumberLiteralResultFlags = 897 | None = 0 898 | SuffixLengthMask = 0b0000000000001111 899 | HasMinusSign = 0b0000000000010000 900 | HasPlusSign = 0b0000000000100000 901 | HasIntegerPart = 0b0000000001000000 902 | HasFraction = 0b0000000010000000 903 | HasExponent = 0b0000000100000000 904 | IsDecimal = 0b0000001000000000 905 | IsHexadecimal = 0b0000010000000000 906 | IsBinary = 0b0000100000000000 907 | IsOctal = 0b0001000000000000 908 | BaseMask = 0b0001111000000000 909 | IsInfinity = 0b0010000000000000 910 | IsNaN = 0b0100000000000000 911 912type internal NLF = NumberLiteralResultFlags 913 914type NumberLiteral(string, info, suffixChar1, suffixChar2, suffixChar3, suffixChar4) = struct 915 member t.String = string 916 917 member t.SuffixLength = int (info &&& NLF.SuffixLengthMask) 918 member t.SuffixChar1 = suffixChar1 919 member t.SuffixChar2 = suffixChar2 920 member t.SuffixChar3 = suffixChar3 921 member t.SuffixChar4 = suffixChar4 922 923 member t.Info = info 924 925 member t.HasMinusSign = int (info &&& NLF.HasMinusSign) <> 0 926 member t.HasPlusSign = int (info &&& NLF.HasPlusSign) <> 0 927 member t.HasIntegerPart = int (info &&& NLF.HasIntegerPart) <> 0 928 member t.HasFraction = int (info &&& NLF.HasFraction) <> 0 929 member t.HasExponent = int (info &&& NLF.HasExponent) <> 0 930 member t.IsInteger = info &&& (NLF.HasIntegerPart ||| NLF.HasFraction ||| NLF.HasExponent) = NLF.HasIntegerPart 931 member t.IsDecimal = int (info &&& NLF.IsDecimal) <> 0 932 member t.IsHexadecimal = int (info &&& NLF.IsHexadecimal) <> 0 933 member t.IsBinary = int (info &&& NLF.IsBinary) <> 0 934 member t.IsOctal = int (info &&& NLF.IsOctal) <> 0 935 member t.IsNaN = int (info &&& NLF.IsNaN) <> 0 936 member t.IsInfinity = int (info &&& NLF.IsInfinity) <> 0 937end 938 939 940 941let numberLiteralE (opt: NumberLiteralOptions) (errorInCaseNoLiteralFound: ErrorMessageList) (state: State<'u>) = 942 let mutable iter = state.Iter 943 let mutable c = iter.Read() 944 let mutable error = NoErrorMessages 945 let mutable flags = NLF.None 946 947 if c = '-' && int (opt &&& NLO.AllowMinusSign) <> 0 then 948 flags <- NLF.HasMinusSign 949 c <- iter._Increment() 950 elif c = '+' && int (opt &&& NLO.AllowPlusSign) <> 0 then 951 flags <- NLF.HasPlusSign 952 c <- iter._Increment() 953 954 let allowStartingPoint = NLO.AllowFraction ||| NLO.AllowFractionWOIntegerPart // for starting point both flags are required 955 956 if isDigit c || (c = '.' && (opt &&& allowStartingPoint = allowStartingPoint)) then 957 if int (opt &&& (NLO.AllowBinary ||| NLO.AllowOctal ||| NLO.AllowHexadecimal)) <> 0 958 && c = '0' 959 then 960 match iter.Peek() with 961 | 'b' | 'B' -> 962 if int (opt &&& NLO.AllowBinary) <> 0 then 963 flags <- flags ||| NLF.IsBinary 964 c <- iter._Increment(2u) 965 if c = '0' || c = '1' then 966 flags <- flags ||| NLF.HasIntegerPart 967 c <- iter._Increment() 968 else 969 error <- expectedBinaryDigit 970 while c = '0' || c = '1' do 971 c <- iter._Increment() 972 | 'o' | 'O' -> 973 if int (opt &&& NLO.AllowOctal) <> 0 then 974 flags <- flags ||| NLF.IsOctal 975 c <- iter._Increment(2u) 976 if isOctal c then 977 flags <- flags ||| NLF.HasIntegerPart 978 c <- iter._Increment() 979 else 980 error <- expectedOctalDigit 981 while isOctal c do 982 c <- iter._Increment() 983 | 'x' | 'X' -> 984 if int (opt &&& NLO.AllowHexadecimal) <> 0 then 985 flags <- flags ||| NLF.IsHexadecimal 986 c <- iter._Increment(2u) 987 if isHex c then 988 flags <- flags ||| NLF.HasIntegerPart 989 c <- iter._Increment() 990 elif int (opt &&& NLO.AllowFractionWOIntegerPart) = 0 then 991 // integer part required 992 error <- expectedHexadecimalDigit 993 while isHex c do 994 c <- iter._Increment() 995 if c = '.' && isNull error && int (opt &&& NLO.AllowFraction) <> 0 then 996 flags <- flags ||| NLF.HasFraction 997 c <- iter._Increment() 998 if isHex c then 999 c <- iter._Increment() 1000 elif int (flags &&& NLF.HasIntegerPart) = 0 then 1001 // at least one digit before or after the . is required 1002 error <- expectedHexadecimalDigit 1003 while isHex c do 1004 c <- iter._Increment() 1005 elif int (flags &&& NLF.HasIntegerPart) = 0 then 1006 // we neither have an integer part nor a fraction 1007 error <- expectedHexadecimalDigit 1008 if (c = 'p' || c = 'P') && isNull error && int (opt &&& NLO.AllowExponent) <> 0 then 1009 flags <- flags ||| NLF.HasExponent 1010 c <- iter._Increment() 1011 if c = '-' || c = '+' then 1012 c <- iter._Increment() 1013 if not (isDigit c) then 1014 error <- expectedDecimalDigit 1015 while isDigit c do 1016 c <- iter._Increment() 1017 | _ -> () 1018 1019 if int (flags &&& (NLF.IsBinary ||| NLF.IsOctal ||| NLF.IsHexadecimal)) = 0 then 1020 flags <- flags ||| NLF.IsDecimal 1021 if c <> '.' then 1022 flags <- flags ||| NLF.HasIntegerPart 1023 c <- iter._Increment() 1024 while isDigit c do 1025 c <- iter._Increment() 1026 if c = '.' && int (opt &&& NLO.AllowFraction) <> 0 then 1027 flags <- flags ||| NLF.HasFraction 1028 c <- iter._Increment() 1029 if isDigit c then 1030 c <- iter._Increment() 1031 elif int (flags &&& NLF.HasIntegerPart) = 0 then 1032 // at least one digit before or after the . is required 1033 error <- expectedDecimalDigit 1034 while isDigit c do 1035 c <- iter._Increment() 1036 if (c = 'e' || c = 'E') && isNull error && int (opt &&& NLO.AllowExponent) <> 0 then 1037 flags <- flags ||| NLF.HasExponent 1038 c <- iter._Increment() 1039 if c = '-' || c = '+' then 1040 c <- iter._Increment() 1041 if not (isDigit c) then 1042 error <- expectedDecimalDigit 1043 while isDigit c do 1044 c <- iter._Increment() 1045 1046 if isNull error then 1047 let str = state.Iter.ReadUntil(iter) 1048 let mutable nSuffix = 0 1049 let mutable s1 = EOS 1050 let mutable s2 = EOS 1051 let mutable s3 = EOS 1052 let mutable s4 = EOS 1053 if int (opt &&& NLO.AllowSuffix) <> 0 && isNull error then 1054 if isAsciiLetter c then 1055 nSuffix <- 1 1056 s1 <- c 1057 c <- iter._Increment() 1058 if isAsciiLetter c then 1059 nSuffix <- nSuffix + 1 1060 s2 <- c 1061 c <- iter._Increment() 1062 if isAsciiLetter c then 1063 nSuffix <- nSuffix + 1 1064 s3 <- c 1065 c <- iter._Increment() 1066 if isAsciiLetter c then 1067 nSuffix <- nSuffix + 1 1068 s4 <- c 1069 c <- iter._Increment() 1070 flags <- flags ||| (enum) nSuffix 1071 let nl = NumberLiteral(str, flags, s1, s2, s3, s4) 1072 Reply<_,_>(nl, state.AdvanceTo(iter)) 1073 else 1074 Reply<_,_>(Error, error, state.AdvanceTo(iter)) 1075 else 1076 if int (opt &&& (NLO.AllowInfinity ||| NLO.AllowNaN)) <> 0 then 1077 if c = 'i' || c = 'I' then 1078 if int (opt &&& NLO.AllowInfinity) <> 0 then 1079 c <- iter.Peek(1u) 1080 if c = 'n' || c = 'N' then 1081 c <- iter.Peek(2u) 1082 if c = 'f' || c = 'F' then 1083 flags <- flags ||| NLF.IsInfinity 1084 c <- iter._Increment(3u) 1085 if c = 'i' || c = 'I' then 1086 c <- iter.Peek(1u) 1087 if c = 'n' || c = 'N' then 1088 c <- iter.Peek(2u) 1089 if c = 'i' || c = 'I' then 1090 c <- iter.Peek(3u) 1091 if c = 't' || c = 'T' then 1092 c <- iter.Peek(4u) 1093 if c = 'y' || c = 'Y' then 1094 iter._Increment(5u) |> ignore 1095 1096 elif (c = 'n' || c = 'N') && int (opt &&& NLO.AllowNaN) <> 0 then 1097 c <- iter.Peek(1u) 1098 if c = 'a' || c = 'A' then 1099 c <- iter.Peek(2u) 1100 if c = 'n' || c = 'N' then 1101 flags <- flags ||| NLF.IsNaN 1102 iter._Increment(3u) |> ignore 1103 1104 if int (flags &&& (NLF.IsInfinity ||| NLF.IsNaN)) <> 0 then 1105 Reply<_,_>(NumberLiteral(state.Iter.ReadUntil(iter), flags, EOS, EOS, EOS, EOS), state.AdvanceTo(iter)) 1106 else…
Large files files are truncated, but you can click here to view the full file