The parsergen package

[Tags: bsd3, library]

For more information, see the README:

https://github.com/tsurucapital/parsergen/blob/master/README.markdown


[Skip to ReadMe]

Properties

Versions0.2.0.0, 0.2.0.1, 0.2.0.2, 0.2.0.3, 0.2.0.4, 0.2.0.6, 0.2.0.7
Change logNone available
Dependenciesbase (>=3 && <5), bytestring (>=0.9 && <0.11), directory (>=1.1 && <2), filepath (>=1.2 && <2), parsec (==3.*), template-haskell (>=2.5 && <3) [details]
LicenseBSD3
AuthorMichael Baikov
Maintainermanpacket@gmail.com
CategoryData
Source repositoryhead: git clone git://github.com/tsurucapital/parsergen.git
UploadedThu Nov 20 06:31:05 UTC 2014 by AkioTakano
DistributionsNixOS:0.2.0.7
Downloads969 total (42 in last 30 days)
Votes
0 []
StatusDocs uploaded by user
Build status unknown [no reports yet]

Modules

[Index]

Downloads

Maintainers' corner

For package maintainers and hackage trustees

Readme for parsergen-0.2.0.7

parsergen

Build Status

Introduction

parsergen is a library aimed at generating fast Haskell parsers for fixed width packets. It uses a DSL in which these packets can be specified, augmented with Haskell parsers.

In order to create a packet and a parser for it, usually two files are used, Foo.hs and Foo.ths.

Tutorial

Datatypes and parsers

Syntax

Let's start by defining a datatype in the .ths file. The syntax here is:

TypeName
  ConstructorName [fields prefix]
    [Nx] [_]FieldName [!] FieldType [+]FieldWidth [FieldParser]

where

In the .hs file, one can now use:

$(genDataTypeFromFile "Foo.ths")
$(genParserFromFile   "Foo.ths")

to generate a parser and a datatype for it.

Example

Let's look at an example .ths file:

Packet
  Warning
    _PacketType       ByteString     4  "WARN"
    DangerType        DangerType     2  dangerType
    ChanceOfSurvival  Int            3

  LotteryWin
    _PacketType       ByteString     4  "LOTT"
    Amount            Money         10
    6x WinningEntry   LotteryEntry   2

And the .hs file:

{-# LANGUAGE OverloadedStrings, TemplateHaskell #-}
import Data.ByteString (ByteString)
import ParserGen.Gen
import ParserGen.Repack  -- Needed later on
import qualified ParserGen.Parser as P

data DangerType
    = Earthquake
    | ZombieApocalypse
    | RobotUprising
    | AngryGirlfriend
    deriving (Eq, Show)

dangerType :: P.Parser DangerType
dangerType = do
    bs <- P.take 2
    case bs of
        "EQ" -> return Earthquake
        "ZA" -> return ZombieApocalypse
        "RI" -> return RobotUprising
        "AG" -> return AngryGirlfriend
        _    -> fail $ "Unknown danger type: " ++ show bs

newtype Money = Money Int
    deriving (Eq, Show)

type LotteryEntry = Int

$(genDataTypeFromFile "Packet.ths")
$(genParserFromFile   "Packet.ths")

sampleWarning :: ByteString
sampleWarning = "WARNRI002"

sampleLotteryWin :: ByteString
sampleLotteryWin = "LOTT9999999999040815162342"

main :: IO ()
main = do
    print $ P.parse parserForWarning sampleWarning
    print $ P.parse parserForLotteryWin sampleLotteryWin

The parsergen generates:

Note how we have used three kinds of parsers:

Repackers

A powerful feature from the library, repackers allow us to change the contents of multiple fields without actually parsing a packet.

Syntax

The syntax looks like this:

repackerForName ConstructorName
  FieldName [FieldUnParser]

Example

Let's add the following the bottom of our .ths file:

repackerForLotteryNumbers LotteryWin
  WinningEntry

And the following to our Haskell file:

$(genRepackFromFile "Packet.ths")

which generates the function

repackerForLotteryNumbers :: [LotteryEntry] -> ByteString -> ByteString

Use it like:

print $ repackerForLotteryNumbers [1 .. 6] sampleLotteryWin

Things to note: