Changelog

Version 1.1.0, 2020‒01‒05

  • Behaviour change: pfloat now parses out‐of‐range finite values as plus or minus infinity instead of returning an error. This unifies the pfloat behaviour on all platforms after the behaviour change of System.Double.Parse on .NET Core 3.
  • Enrico Sada modernized the F# and C# project files and the build script for the NuGet packages – thanks Enrico!
  • Added SourceLink support, which was prepared and championed by Cameron Taggart – thank Cameron!
  • Maxime Didier fixed a bug in the Low‐Trust version of the CharStream constructors that accept a file path argument: The stream’s Name property wasn’t initialized. Thanks Maxime!
  • Fixed missing parser definitions in the Parsing JSON section of the tutorial spotted by Josh Quintus – thanks Josh!
  • Andre Wesseling fixed a parser definition in the Where is the monad section of the User’s Guide – thanks Andre!
  • Frederik K. fixed an error in the ErrorMessage documentation – thanks Frederik!
  • Jonathan Roeber fixed an error in the previousCharSatisfiesNot – thanks Jonathan!
  • Vegard Løkken fixed an error in the unicodeSpaces documentation – thanks Vegard!

Version 1.0.3, 2017‒08‒20

  • Modern solution and project files for .NET Core and VS 2017 were added to the source folders. Huge thanks to Marcus Griep for spearheading the effort to make FParsec .NET Standard compatible and contributing the new project and solution files!
  • The old build script for the NuGet packages was replaced by a PowerShell script that uses the new project files.
  • The FParsec NuGet package now contains assemblies for .NET Standard 1.6.
  • The non‐netstandard assemblies of FParsec now reference the FSharp.Core 4.0.0.1 NuGet package, which should maximize compatibility when binding redirects aren’t available.
  • A .vscode/tasks.json file with some task definitions for Visual Studio Code was added.
  • The source repository was moved to GitHub.
  • Added a stringsSepBy1 parser (contributed by Robin Munn – thanks Robin!).
  • Added a link to the Russian translation of the tutorial by Dmitry Vlasov – thanks Dmitry!
  • Fixed documentation typos. One was spotted by Brandon Dimperio, another by ZelteHonor – thanks Brandon and ZelteHonor!
  • Renamed CLR45 to AGGRESSIVE_INLINING to better match its purpose.

Version 1.0.2, 2015‒09‒27

  • replaced all uses of Char.GetUnicodeCategory with CharCodeInfo.GetUnicodeCategory, since the former may or may not track the current Unicode standard and the latter is the only one supported by the PCL API subset
  • updated the case folding, whitespace and XID property data tables to Unicode 8.0.0
  • added a PCL Profile 259 version to the FParsec NuGet package
  • removed the Silverlight, VS9 and VS10 solution files and the Mono Makefile
  • updated the Lex & Yacc version of the FSharpParsingSample to use the FsLexYacc NuGet packages
  • fixed documentation typos (two were spotted by Francois Nardon and Patrick McDonald – thanks Francois and Patrick!)

Version 1.0.1, 2013‒06‒25

  • The maintainership of the FParsec NuGet package(s) was handed over from Ryan Riley, Huw Simpson, Cameron Taggart and Khan Thompson to Stephan Tolksdorf. Thanks Ryan, Huw, Cameron and Khan for creating and maintaining the previous versions of the NuGet package!
  • FParsec now has two NuGet packages, built with a new fsx script
  • fixed a bug in one of the CharStream constructors (reported and patched by Andrew Smith – thanks Andrew!)
  • added USE_STATIC_MAPPING_FOR_IS_ANY_OF and UNALIGNED_READS as default compilation options in the Visual Studio projects (the default options now match the ones used by the “Big Data edition” NuGet package)
  • some minor code tweaking / micro‐optimizations
  • fixed some minor documentation issues

Version 1.0.0, 2012‒07‒19

  • disabled code generation in isAnyOf, isNoneOf, anyOf, skipAnyOf, noneOf and skipNoneOf by default (you can reenable it using the new USE_STATIC_MAPPING_FOR_IS_ANY_OF compilation option)
  • annotated some CharStream methods with the .NET 4.5 AggressiveInlining option (see the new CLR45 compilation option)
  • updated case folding and XID property tables to Unicode 6.1.0
  • fixed two documentation typos (spotted by Rasmus Meldgaard and Kurt Schelfthout – thanks Rasmus and Kurt!)

Version 0.9.2, 2012‒03‒09

  • fixed compilation in Visual Studio 11 Beta
  • added missing ReturnFrom member to parse builder object (reported by Kurt Schelfthout and Tomas Petricek – thanks Kurt and Tomas!)
  • added workaround for .NET ConsoleStream issue (reported by Alexander Kahl – thanks Alexander!)
  • set AllowPartiallyTrustedCallers and SecurityTransparent assembly attributes in LOW_TRUST NET4 build (as suggested by hammett – thanks hammett!)
  • changed encoding of FParsecCS/Strings.cs to UTF‐8 (with signature) to fix Visual Studio build on machines with Japanese locale (the encoding issue was reported on http://d.hatena.ne.jp/ZOETROPE – thank you!)
  • fixed some documentation issues (incorporating feedback from Alexander Gelkin, Antoine Latter and Stephen Swensen – thanks Alexander, Antoine and Stephen!)
  • add link to the Japanese translation of the tutorial by Gab_km (thanks Gab_km!)

Version 0.9.1, 2011‒05‒22

  • added /nooptimizationdata compiler flag as a workaround for an F# comiler issue (reported by Michael Giagnocavo – thanks Michael!)
  • fixed an issue in the JSON sample (reported by Ryan Riley – thanks Ryan!)
  • fixed the error message formatting when an error line contains unaccounted newlines or ends with a combining character sequence
  • added warning to installation notes that the regex parser doesn’t work on Mono (reported by Laurent Le Brun – thanks Laurent!)
  • fixed some documentation issues (one of which was reported by Michael Giagnocavo – thanks Michael!)

Version 0.9.0, 2011‒04‒26

Highlights
  • a new tutorial and user’s guide
  • 2x performance improvements due to a refactored low‐level API
  • new identifier parser for parsing identifiers based on Unicode XID syntax
  • new StaticMapping module for compiling static key to value mappings into optimized functions (supports char, int and string as key types)
Changes to high‐level API
Removed variants of many, sepBy, sepEndBy and manyTill

The ...Rev, ...Fold and ...Reduce variants of many, sepBy, sepEndByand manyTill have been removed.

If you previously used these variants, you can easily define them in your own code using the |>> combinator, as documented in the reference documentation for the previous version. For example:

let manyRev p = many p |>> List.rev
let manyFold acc0 f p = many p |>> List.fold f acc0
let manyReduce f defVal p = (many1 p |>> List.reduce f) <|>% defVal.

If you need optimized implementations, you can define them using the new Inline helper class. The file Doc/misc/removed‐many‐variants.fs contains optimized definitions for all removed variants.

Details on changes to manyChars, manyCharsTill and their variants

The behaviour of all variants of manyChars and manyCharsTill has slightly changed. Now manyChars cp is equivalent to many cp, except that it returns a string instead of char list. Previously, manyChars cp behaved like many (attempt cp), i.e. it automatically backtracked if the char parser had failed after consuming input. The same change has been made to the behaviour of all other variants of manyChars and manyCharsTill. The new behaviour is more consistent with the rest of the libary and allows a faster implementation with the new low‐level API.

There probably aren’t many parsers that relied on the old behaviour.

The behaviour change made the skip variants of manyChar and manyCharsTill obsolete, since e.g. skipManyChars would do exactly the same as skipMany cp. Hence, the skip variants have been removed.

Changes to low‐level API
  • The old CharStream and State classes have been merged into a single CharStream class with a mutable interface.
  • Parser functions now take a CharStream<'u> instance as the input argument.
  • The Reply type has been moved to the main FParsec namespace and no longer has a State member.
  • Parser state comparisons are now done with the help of the CharStream’s StateTag.
  • Various methods from the old CharStream.Iterator and State types have been renamed in the new CharStream class and have new signatures:

  • New CharStream methods:

  • The ErrorMessage and ErrorMessageList types are now defined in the C# library part. This allows us to implement full parsers in C#. The FParsec.Error module contains type abbreviations and active patters that provide the familiar interface to F# clients.
  • All error messages used by built‐in FParsec parsers are now defined in the C# classes FParsec.Strings and FParsec.Errors. This should simplify customization and internationalization efforts.
Background on low‐level API changes

Previously parsers were implemented as functions operating on an immutable parser state in the form of a State instance. A parser function received a State instance as the input and returned a State instance as part of its return value. Since State instances were immutable, a parser function had to create a new State instance to advance the input stream, e.g. by calling state.Advance(2).

This architecture was motivated by the desire to provide an API as “functional” as possible, an API that shields users from the underlying imperative/mutable nature of input streams. When FParsec originally started as a relatively close port of Haskell’s Parsec library, this design felt like a natural fit for a functional parser library. However, later, when FParsec moved away from its Parsec roots (to improve performance and provide more features), it became increasingly clear that the immutable CharStreamState‐design was the main obstacle preventing FParsec from reaching the performance of hand‐optimized recursive‐descent parsers.

Initial tests with some quick prototypes revealed that the allocation and garbage collection of temporary State instances took up to 50% or more of the run time of typical parsers – even though the State class was already heavily optimized. These tests also indicated that consolidating the stream and state classes into a classical imperative stream class simplified the overall library implementation and made the library source code more accessible to new users.

The main drawback of the API change is that it requires modifications to practically all low‐level parser code. Another drawback is that backtracking is slightly less convenient with the new low‐level API (as the parser state has to be explicitly saved and restored, while previously one could just continue with an old state instance).

Since FParsec’s high‐level API is only minimally affected by the change, the advantages seem to outweigh the costs.

Version 0.8.x, no release

New features/ improvements
  • case‐insensitive matching with pstringCI, charsTillStringCI, etc. (using the Unicode 1‐to‐1 case folding mappings for chars in the BMP)
  • various new parsers and combinators, including restOfLine, skipToString, manySatisfyMinMax, manyStrings, withSkippedString
  • new functions runParserOnSubstring and runParserOnSubstream
  • various performance improvements
  • Silverlight support
  • F# 1.9.6.16 compatibility
Design changes
  • standardized on a single input stream type (FParsec.CharStream) and a single concrete parser state type (FParsec.State)
  • refactored the Reply<_,_>, ErrorMessage and ParserError types:

    • error replies now also contain a complete State
    • whether a parser has changed the state is now determined by checking the input and the output state for equality, instead of testing the Consumed flag
    • replaced the Reply<_,_>.Flags with a Status field
    • replaced the various helper functions for constructing a Reply with three overloaded Reply<_,_> constructors (with different arities)
  • all char parsers are now “newline aware”, i.e. they normalize any of the three standard newline representations ("\n", "\r\n", "\r") to “n” and they properly increment the line count whenever they parse a newline; this means that the behaviour of almost all char parsers has changed with regard to how newline chars are handled
Bug fixes
  • The CharStream class now uses the serialization API to persist the decoder state for backtracking purposes. Previously it relied on the decoder loosing its state at block boundaries after a certain sequence of method calls. The previous approach works in practice for the .NET decoders of the standard unicode encodings and for simple stateless encodings like ASCII and ANSI, but it relies on undocumented behaviour and it does not work reliably for encodings like GB18030, ISO‐2022 or ISCII.
  • In previous FParsec versions the CharStream file path/System.IO.Stream constructors failed with an IndexOutOfRange exception when the file/stream was empty and encoding detection was not turned off (reported by Vesa Karvonen ‐ thanks Vesa!).
  • In previous FParsec versions the NumberLiteral.String returned by the numberLiteral parser included parsed suffix chars despite the documentation claiming the opposite. (The testing code was buggy too.) Applications that rely on this behaviour can now use the new NumberLiteralOptions.IncludeSuffixCharsInString to force the numberLiteral parser to include any suffix chars in the returned string.
  • Fixed behaviour of >>=?, >>? and .>>? when second parser fails with fatal error without changing the parser state.
  • Fixed behaviour of nextCharSatisfies[Not] when current “char” is a "\r\n" newline.
Other breaking changes
  • renamed the module CharParser to CharParsers
  • moved CharParser.OperatorPrecedenceParser into separate module
  • FParsec.Primitives:

    • subtle change: renamed message to fail and fail to failFatally
    • renamed pair, triple and quad to tuple2, tuple3 and tuple4
    • renamed manyFoldLeft to manyFold and changed the argument order of the accumulator and function argument
    • removed manyFoldRight
    • renamed count to parray and changed the return type, renamed skipCount to skipArray
    • renamed followedBy and notFollowedBy to followedByL and notFollowedByL and introduced followedBy and notFollowedBy functions that take no second argument
    • moved ParserResult<_> to CharParsers and changed constructor arguments
    • removed applyParser
    • removed |>>=, now >>= automatically uses an optimized branch for uncurried functions
    • removed endBy and endBy1 (endBy p sep can be replaced with many (p .>> sep) and endBy1 p sep with many1 (p .>> sep))
  • FParsec.CharParsers:

    • renamed manyTillString to charsTillString
    • removed applyParser from the public interface
    • removed getIndex, skip, registerNL, extract, regexp (these low‐level operations should be done directly through the State<_>/CharStream.Iterator interface)
    • removed anyCharOrNL (no longer needed, see design changes above)
    • removed nSatisfy (can be replaced with manySatisfyMinMax)
    • removed unicodeDigit and unicodeNumber (can be replaced with satisfy System.Char.IsDigit and satisfy System.Char.IsNumber)
    • moved the helper functions expectedError, unexpectedError etc. into the Error module
  • FParsec.CharStream:

    • string constructor takes more arguments
    • Iterator.Peek(i) now returns the EndOfStreamChar char instead of throwing an exception if the char peeked at lies before the beginning of the stream

Version 0.7.3.1, 2009‒02‒26

  • Fixed a bug in CharParser.normalizeNewlines/CharStream.NormalizeNewlines. This bug also affected the skipped and manyTillString parsers, which internaly call normalizeNewlines to normalize the returned string.

    The bug was reported by Greg Chapman ‐ thanks Greg!

    When given a multi‐line string in which the lines are delimited by "\r\n" but the last line does not end in a newline, the buggy normalizeNewlines replaced the chars on the last line with '\n' chars.

  • Changed the signature of Helper.SkipOverWhitespace.

Version 0.7.3, 2008‒12‒08

Breaking changes (all of which should have little or no impact on existing code bases):

  • CharStream.Iterator instances now compare equal if and only if they belong to the same CharStream and point to the same index (previously they compared only equal if their internal representations were identical)
  • the constructor argument of Error.otherError is now expected to be comparable with F#’s structural comparison function compare, see http://research.microsoft.com/fsharp/manual/spec2.aspx#_Toc207785725
  • the signature of the second ParserError.ToString overload has changed
  • CharParser.errorToString and printErrorLine have been deprecated

New features:

  • reimplemented the error formatting code in FParsec.Error
  • added new State<_>.AdvanceTo and CharStream.Iterator.Advance overloads
  • slightly modified the error reporting in Primitives.sepEndBy
  • some documentation fixes

Version 0.7.2, 2008‒11‒17

  • added CharParser.OperatorPrecedenceParser
  • changed the overflow checking in pint32 such that it will not be affected by an expected future change in F#’s int32 -> uint64 conversion behaviour
  • added CharParser.pint16, puint16, pint8, puint8
  • changed the signatures in CharParser.fsi to use the Parser<_,_> type abbreviation
  • fixed outdated documentation of CharParser.expectedError
  • some minor optimizations

Version 0.7.1, 2008‒09‒29

Breaking changes:

  • renamed Primitives.Reply._tag member to Flags and gave it a proper enumeration type
  • CharParser.State is now a reference type
  • Removed CharParser.State.Flags member
  • deprecated Primitives.reconstructError

Version 0.7.0.1, 2008‒09‒23

Breaking change:

  • changed the case of the FParsec.Error.Pos members (This wasn’t already done in 0.7 because of an oversight.)

Version 0.7.0, 2008‒09‒13

Bugfixes:

  • made FParsec.Error.Pos IComparable to prevent ParserError.ToString from throwing an exception under rare circumstances
  • corrected the argument checking for some CharStream.Iterator methods for very large arguments

New features:

  • compatibility with the F# CTP release
  • a configurable parser for number literals: CharParser.numberLiteral
  • CharParser.pfloat now also parses NaN, Infinity and hexadecimal floating point literals as supported by IEEE754r, C99 and Java (but different from the hex representation supported by F#)
  • new helper functions CharParser.floatToHexString, floatOfHexString, float32ToHexString and float32OfHexString
  • integer parsers: Charparser.pint32, puint64, puint32, puint64
  • new sample: a JSON parser
  • various optimizations and some code cleanup
  • new CharStream.Iterator members ReadUntil, Increment and Decrement
  • new State member AdvanceTo
  • new function Primitives.createParserForwardedToRef
  • new combinator |>>= in Primitives

Breaking changes:

  • renamed the parsers char and string to pchar and pstring (This is in deference to the built‐in F# functions char and string, which weren’t yet around when the first version of FParsec was released.)
  • changed the case of the properties of the Reply and State types (This reflects the emerging consensus in the F# community that all public members of types should be named in PascalCase.)
  • deprecated State.AdvanceNL (use the 3 parameter Advance overload instead)
  • deprecated the Primitives helper functions isOk, isEmpty, … (the Reply properties IsOk, IsEmpty,… should be used instead)
  • deprecated the CharParser helper functions matchChar, readChar, … (the State.Iter methods Match, Read, … should be used instead)
  • deprecated Primitives.option, <|>$ should be used instead
  • made CharParser.CharList internal (If you need this helper class for your code, just copy the implementation to your source.)
  • State.Flags() now has more bits (and less bits are reset on a position change)

Version 0.6.0, 2008‒05‒20

  • fixed a bug in manyTillString (the code keeping track of newlines was buggy)
  • fixed a bug in CharParser.<?> (the error reporting was inconsistent with Primitives.<?> in the rare case where <?> is applied inside an attempt (...) <?> label clause to a parser that returns an EmptyOk reply)
  • various changes for F# 1.9.4.15
  • added skipped parser to CharParser
  • added nextCharSatifiesNot, prevCharSatifiesNot, currCharSatisfies, currCharSatisfiesNot to CharParser module; the behaviours of the existing nextCharSatisfies and prevCharSatisfies were slightly changed (see fparsec.html for more details)
  • added TryWith and TryFinally members to Primitivs.ParserCombinator
  • added triple and quad parsers to Primitives module
  • set CompilationRepresentationFlags.PermitNull for Error.ParserError
  • various optimizations
  • some documentation fixes, including corrections for the docs of the CharParser error generation helper functions (expectedError etc.)

Version 0.5.1, 2008‒01‒20

  • added pipe2, pipe3 and pipe4 primitives
  • replaced count and skipCount primitives with optimized versions
  • minor optimizations in spaces and spaces1
  • added pfloat char parser
  • minor documentation fixes

Version 0.5.0, 2008‒01‒15

  • Major design change: all lazy computations were removed and the types Output and Reply unified. The new implementation is considerably simpler and also compiles with F# 1.9.3.7.
  • Fixed a bug in build.bat (reported by Santosh Zachariah ‐ thanks Santosh!)

Version 0.4.4, 2008‒01‒13

  • fixed a minor issue in CharParser.attempt
  • added .>>! and >>.! primitives
  • added skipManySatisfy and skipMany1Satisfy char parsers

Version 0.4.3, 2008‒01‒12

  • fixed bugs in the CharParser versions of <?> and attempt.
  • added >>? primitive
  • added skipSatisfy and skipSatisfyL char parsers
  • minor documentation fixes

Version 0.4.2, 2008‒01‒04

  • performance improvements in CharStream.Iterator
  • minor documentation fixes

Version 0.4.1, 2008‒01‒02

  • documentation fixes
  • new sample application: a parser for Parsing Expression Grammars
  • newline and unicodeNewline now return '\n', instead of 1 or 2
  • added whitespace parser and changed unicodeWhitespace
  • added spaces parser (equivalent to skipManyChars whitespace)
  • removed newlineRepl parameter from manyTillString
  • added skipManyTill and skipManyCharsTill
  • generalized types of skipManyChars and skipManyChars1

Version 0.4.0, 2007‒12‒30

Initial public release