3 Download and installation

3.1 Getting the source

FParsec’s source code repository is hosted on BitBucket at: bitbucket.org/fparsec/main

You can “clone” the source code using Mercurial (HG) or you can download it as a zip‐file.

It’s an FParsec project policy to check only stable and tested code into the BitBucket repository, so you can normally just work with the “tip” version of FParsec.

Tip

TortoiseHG is a great Mercurial GUI for Windows.

3.2 FParsec is built as two DLLs

FParsec’s source code is written in both C# and F#. Since neither the C# nor the F# compiler directly support the other language, the respective components need to be built separately.

Hence, FParsec is built as two DLLs. The C# bits are compiled into the FParsecCS.dll and the F# bits (which depend on the C# bits) are compiled into FParsec.dll.

Projects that use FParsec thus have to reference both DLLs.

If you reference the DLLs in the F# Interactive console, you need to reference FParsecCS.dll before you reference FParsec.dll.

Note

If you don’t want to distribute the FParsec DLLs together with the assembly of your project, you can use the staticlink command‐line option of the F# compiler to merge the FParsec DLLs into your assembly.

Unfortunately, the same option cannot be used to merge FParsecCS.dll into the FParsec.dll, as the public definitions in FParsecCS.dll wouldn’t be reexported by FParsec.dll. For similar reasons it also doesn’t seem to be possible to use tools like ILMerge or il‐repack to obtain a merged FParsec.dll that can be properly consumed by F# programs.

3.3 Building FParsec with Visual Studio

The folders Build/VS9 and Build/VS10 contain solution files for Visual Studio 2008 and 2010. The folder Build/Silverlight contains a Visual Studio 2010 solution specifically configured to produce Silverlight 4‐compatible assemblies.

When you build FParsec with these solution files, the compiled assemblies will be put into the bin/Debug or bin/Release subfolders, depending on the project configuration. For example, the VS10 solution will put the assemblies into the folders Build/VS10/bin/Debug and Build/VS10/bin/Release.

The Test project in the solution files contains the unit tests for FParsec.

3.4 Building FParsec with Mono

This information is this section might be partially out‐of‐date. Please file a documentation bug if you can provide more up‐to‐date information.

FParsec is compatible with the latest version of Mono from the GitHub master branch (the 2.10 branch is missing at least commit 410b3e423f1135a9783d for FParsec to compile).

You can build FParsec for Mono using the Makefile in the Build directory. The debug and release assemblies will be put in the Build/bin/Debug and Build/bin/Release directories respectively.

Mono’s System.Text.Decoder classes have some bugs that cause issues with FParsec. Until these bugs are fixed only the Low‐Trust version of FParsec works under Mono.

Note:

There are also two issues with the official “source code drop” for the F# compiler:

  • The assemblies for the .NET 4 profile contain duplicate symbols. See here for instructions how to fix this.
  • On Unix platforms the F# compiler generates debug symbols with invalid source code file paths. This prevents debugging with tools like MonoDevelop. You can fix this by commenting out >> normalize on line 724 of fsharp/env.fs before building F# from source.

3.5 The Low‐Trust version of FParsec

For optimization reasons the normal implementation of FParsec involves unverifiable code using unmanaged pointers.

If you compile FParsec with the LOW_TRUST conditional compiler symbol, the unverifiable code is replaced with a “safe” alternative. This allows FParsec to be run in environments with “reduced trust”, such as medium trust ASP.NET applications or Silverlight applications.

The next section explains how you can set a conditional compiler symbol. If you want to use the Low‐Trust version of FParsec, you need to compile each of the FParsecCS, FParsec and Test projects with the LOW_TRUST symbol.

The Low‐Trust version of FParsec has the following two major limitations:

  • A CharStream that is constructed from a System.IO.Stream or a file path reads the complete file into a single string during construction. This severely limits the maximum practical input stream size.
  • The StaticMapping module is not supported.

3.6 Configuration options

You can configure FParsec’s source code with a number of conditional compilation symbols (a.k.a. preprocessor defines). Besides the Low‐Trust option, these symbols mostly serve tuning purposes. The Visual Studio solutions and the Mono Makefile both come with sensible defaults, so that you don’t have to worry about these options if you don’t want to.

You can set conditional compilation symbols either in the Visual Studio project configuration in the “Build” tab (multiple symbols can be separated by semicolons) or on the compiler command‐line with the /define:SYMBOL option (the F# compiler requires a separate /define: option for each symbol).

Options for FParsecCS.dll
LOW_TRUST

See above.

CLR4

Compile for a CLR version ≥ 4.

CLR45

Compile for a CLR version ≥ 4.5.

This option allows annotating methods with the new MethodImplOptions.AggressiveInlining attribute.

SILVERLIGHT

Compile for Silverlight.

SMALL_STATETAG

Use a 32‐bit StateTag in the CharStream class instead of the default 64‐bit one.

This is an optimization for 32‐bit runtimes. You can find more information about the state tag in section 5.4.3 of the user’s guide.

UNALIGNED_READS

This option does not affect the Low‐Trust version of FParsec.

Optimize for CPUs that support fast unaligned memory reads, i.e. any modern x86‐based CPU.

This option only makes a noticable difference is some specific situations.

Options for FParsec.dll
LOW_TRUST

See above.

UNALIGNED_READS

See above.

NOINLINE

Do not force inlining of certain parser combinators.

This option enables you to step through the respective combinators during debugging.

USE_STATIC_MAPPING_FOR_IS_ANY_OF

This option does not affect the Low‐Trust version of FParsec.

Use StaticMapping.createStaticCharIndicatorFunction for the implementation of isAnyOf, isNoneOf, anyOf, skipAnyOf, noneOf and skipNoneOf for generating optimized char predicate functions using runtime code generation.

Runtime code generation is a relatively expensive operation, so this optimization is primarily meant for parsers that are applied to large (or lots of) input streams. Please see the remarks for the StaticMapping module for more information.

If you run into noticable performance problems or memory leaks when enabling this option, you’re probably inadvertently recreating the same isAnyOf‐ or isNoneOf‐based parser again and again, as explained here and here.

DEBUG_STATIC_MAPPING

This option does not affect the Low‐Trust version of FParsec.