SharpBoomerang


SharpBoomerang

Parser and unparser (pretty printer) from the same grammar. Somewhat akin to the boomerang package for Haskell, or the Boomerang language.

Features

  • Written in F# 4.0
  • In F#, you can define the grammar in a functional style with combinators!

Considerations

  • Still pretty rough, especially from C#
  • Not many tests yet
  • Not yet optimized for performance
  • Not yet a complete parsing framework

Requirements

Visual Studio

You'll need Visual Studio 2015 -- earlier versions will not work. Just load SharpBoomerang.sln and go!

Xamarin Studio

If you are using Mono, you'll need version 4.3.1 or newer. Just load SharpBoomerang.sln in Xamarin Studio and go!

Docs

Documentation can be found in the docs directory, or online. The HTML docs can be built like this:

1: 
[Mac] build.fsx docs

TL;DR

For those who are impatient, here are some samples that are more fully discussed in the docs.

Hello World

1: 
2: 
3: 
4: 
5: 
let bhello =
    blit %"Hello" >>       // boomerang the literal string, "Hello"
    ~~(blit %",") %true >> // optionally parse a comma (",") -- "%true" means it will always be printed
    !+(bws %' ') >>        // parse one or more whitespace characters -- it will print one space
    blit %"World!"         // boomerang the literal string, "World!"

Parse a Name

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
type Title =
    | Mr
    | Ms
    | Dr

type Name = {
    Title : Title option;
    First : string;
    Last  : string;
}

let bspace = !+(bws %' ')
let btitle = ~~~(bdu<Title> .>> ~~(blit %".") %true .>> bspace)
let bname = btitle .>>. bstr .>> bspace .>>. bstr .>>% ((fun (t, f, l) -> { Title = t; First = f; Last = l }), (fun n -> (n.Title, n.First, n.Last)))

Parse JSON

See the full document here.

Tests

The NUnit tests are under the tests directory. The tests should be runnable from the Unit Tests pad in Xamarin Studio or the Test Explorer in Visual Studio.

Building the NuGet Package

Sometimes it's helpful to build the NuGet package locally. To do this:

1: 
[Mac] build.fsx nupkg

If you have not already built a Release build, the build will run as part of this command. Note that you'll need to have previously restored the NuGet packages otherwise it will fail.

Contributions, Feedback, etc.

All welcome! Feel free to file PRs or Issues. Also consider poking me on Twitter @chknofthescene, as I sometimes miss GitHub notifications.

val bhello : (Context -> Context)

Full name: Readme.bhello
val blit : str:channel<string> -> (Context -> Context)

Full name: SharpBoomerang.Combinators.blit


 Boomerangs a literal string
val bws : ws:channel<char> -> (Context -> Context)

Full name: SharpBoomerang.Combinators.bws


 Boomerangs a single whitespace character
type Title =
  | Mr
  | Ms
  | Dr

Full name: Readme.Title
union case Title.Mr: Title
union case Title.Ms: Title
union case Title.Dr: Title
type Name =
  {Title: Title option;
   First: string;
   Last: string;}

Full name: Readme.Name
Multiple items
Name.Title: Title option

--------------------
type Title =
  | Mr
  | Ms
  | Dr

Full name: Readme.Title
type 'T option = Option<'T>

Full name: Microsoft.FSharp.Core.option<_>
Name.First: string
Multiple items
val string : value:'T -> string

Full name: Microsoft.FSharp.Core.Operators.string

--------------------
type string = System.String

Full name: Microsoft.FSharp.Core.string
Name.Last: string
val bspace : (Context -> Context)

Full name: Readme.bspace
val btitle : (channel<Title option> -> Context -> Context)

Full name: Readme.btitle
val bdu<'a> : Boomerang<'a>

Full name: SharpBoomerang.Combinators.bdu


 Boomerangs a discriminated union case that takes no arguments
val bname : (IChannel<Name> -> Context -> Context)

Full name: Readme.bname
val bstr : Boomerang<string>

Full name: SharpBoomerang.Combinators.bstr


 Boomerangs an arbitrary length string (non-greedy sequence of characters)
val t : Title option
val f : string
val l : string
val n : Name
Name.Title: Title option
Fork me on GitHub