sexp-grammar: Invertible grammar combinators for S-expressions

[ bsd3, language, library ] [ Propose Tags ]

Serialisation to and deserialisation from S-expressions derived from a single grammar definition.


[Skip to Readme]

Downloads

Note: This package has metadata revisions in the cabal description newer than included in the tarball. To unpack the package including the revisions, use 'cabal get'.

Maintainer's Corner

Package maintainers

For package maintainers and hackage trustees

Candidates

Versions [RSS] 1.0.0, 1.1.0, 1.1.1, 1.2.0, 1.2.0.1, 1.2.1, 1.2.2, 1.2.3, 1.2.4, 1.3.0, 2.0.0, 2.0.1, 2.0.2, 2.1.0, 2.2.0, 2.2.1, 2.3.0, 2.3.1, 2.3.2, 2.3.3, 2.3.3.1, 2.3.4.0, 2.3.4.1, 2.3.4.2 (info)
Dependencies array (>=0.5 && <0.6), base (>=4.9 && <5.0), bytestring (>=0.10 && <0.11), containers (>=0.5.5 && <0.7), deepseq (>=1.0 && <2.0), invertible-grammar (>=0.1.3 && <0.2), prettyprinter (>=1 && <1.8), recursion-schemes (>=5.0 && <5.2), scientific (>=0.3.3 && <0.4), semigroups (>=0.16 && <0.20), text (>=1.2 && <1.3), utf8-string (>=1.0 && <2.0) [details]
License BSD-3-Clause
Author Yevhen Smolanka, Sergey Vinokurov
Maintainer Yevhen Smolanka <ys@polymorphic.me>
Revised Revision 1 made by Bodigrim at 2021-09-23T20:53:41Z
Category Language
Home page https://github.com/esmolanka/sexp-grammar
Source repo head: git clone https://github.com/esmolanka/sexp-grammar
Uploaded by EugeneSmolanka at 2020-08-11T18:10:00Z
Distributions LTSHaskell:2.3.4.2, NixOS:2.3.4.2, Stackage:2.3.4.2
Reverse Dependencies 2 direct, 1 indirect [details]
Downloads 10354 total (87 in the last 30 days)
Rating (no votes yet) [estimated by Bayesian average]
Your Rating
  • λ
  • λ
  • λ
Status Docs available [build log]
Last success reported on 2020-08-11 [all 1 reports]

Readme for sexp-grammar-2.2.1

[back to package description]

Build Status

sexp-grammar

Library of invertible parsing combinators for S-expressions. The combinators define primitive grammars and ways to compose them. A grammar constructed with these combinators can be run in two directions: parsing from S-expressions direction (forward) and serialising to S-expressions direction (backward).

The approach used in sexp-grammar is inspired by the paper Invertible syntax descriptions: Unifying parsing and pretty printing and a similar implementation of invertible grammar approach for JSON, library by Martijn van Steenbergen called JsonGrammar2.

Let's have a look at sexp-grammar at work:

{-# LANGUAGE DeriveGeneric     #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeOperators     #-}

import GHC.Generics
import Data.Text (Text)
import Language.SexpGrammar
import Language.SexpGrammar.Generic

data Person = Person
  { pName    :: Text
  , pAddress :: Text
  , pAge     :: Maybe Int
  } deriving (Show, Generic)

instance SexpIso Person where
  sexpIso = with $ \person ->  -- Person is isomorphic to:
    list (                           -- a list with
      el (sym "person") >>>          -- a symbol "person",
      el string         >>>          -- a string, and
      props (                        -- a property-list with
        "address" .:  string >>>     -- a keyword :address and a string value, and
        "age"     .:? int))  >>>     -- an optional keyword :age with int value.
    person

We've just defined an isomorphism between S-expression representation and Haskell data record representation of the same information.

ghci> :set -XTypeApplications
ghci> import Language.SexpGrammar
ghci> import Data.ByteString.Lazy.Char8 (pack, unpack)
ghci> person <- either error return . decode @Person . pack =<< getLine
(person "John Doe" :address "42 Whatever str." :age 25)
ghci> person
Person {pName = "John Doe", pAddress = "42 Whatever str.", pAge = Just 25}
ghci> putStrLn (either id unpack (encode person))
(person "John Doe" :address "42 Whatever str." :age 25)

See more examples in the repository.