syntax-example-json (empty) → 0.2.0.0
raw patch · 4 files changed
+170/−0 lines, 4 filesdep +attoparsecdep +basedep +containerssetup-changed
Dependencies added: attoparsec, base, containers, lens, scientific, semi-iso, syntax, syntax-attoparsec, syntax-printer, text
Files
- LICENSE +20/−0
- Main.hs +116/−0
- Setup.hs +2/−0
- syntax-example-json.cabal +32/−0
+ LICENSE view
@@ -0,0 +1,20 @@+Copyright (c) 2014 Paweł Nowak++Permission is hereby granted, free of charge, to any person obtaining+a copy of this software and associated documentation files (the+"Software"), to deal in the Software without restriction, including+without limitation the rights to use, copy, modify, merge, publish,+distribute, sublicense, and/or sell copies of the Software, and to+permit persons to whom the Software is furnished to do so, subject to+the following conditions:++The above copyright notice and this permission notice shall be included+in all copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ Main.hs view
@@ -0,0 +1,116 @@+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE OverloadedStrings #-}++import Control.Applicative+import Control.Lens+import Control.Lens.SemiIso+import qualified Data.Attoparsec.Text.Lazy as AP+import Data.Map (Map)+import qualified Data.Map as Map+import Data.Scientific (Scientific)+import Data.SemiIsoFunctor+import qualified Data.Syntax as S+import qualified Data.Syntax.Attoparsec.Text.Lazy as S+import Data.Syntax.Char (SyntaxText)+import qualified Data.Syntax.Char as S+import qualified Data.Syntax.Combinator as S+import Data.Syntax.Indent (Indent)+import qualified Data.Syntax.Indent as S+import qualified Data.Syntax.Printer.Text as S+import Data.Text (Text)+import qualified Data.Text.Lazy.Builder as T+import qualified Data.Text.Lazy.IO as T++-- | A JSON value.+data Value = Object (Map Text Value)+ | Array [Value]+ | String Text+ | Number Scientific+ | Bool Bool+ | Null+ deriving (Show)++$(makePrisms ''Value)++-- Indent is basically a Reader monad transformer.+-- S.breakLine inserts a new line and correct indentation,+-- but does not require any formatting when parsing (it just+-- skips all white space).+-- S.indented increases the indentation level.++-- | Char encoded as 4 hex digits.+hexCode :: SyntaxText syn => Indent syn Char+hexCode = from enum . bifoldl1_ (iso u f) /$/ sireplicate 4 S.digitHex+ where+ f (x, y) = 16 * x + y+ u 0 = Nothing+ u n = Just (n `quotRem` 16)++string :: SyntaxText syn => Indent syn Text+string = S.packed /$/ S.char '"' */ simany character /* S.char '"'+ where+ character = S.satisfy (\x -> x /= '"' && x /= '\\')+ /|/ S.char '\\' */ escapedChar++ escapedChar = S.char 'u' */ hexCode+ /|/ S.choice+ [ exact v /$/ S.char e+ | (v, e) <- [ ('"', '"'), ('\\', '\\'), ('/', '/'), ('\b', 'b')+ , ('\f', 'f'), ('\n', 'n') , ('\r', 'r'), ('\t', 't')]+ ]++mapFromList :: Ord i => Iso' (Map i v) [(i, v)]+mapFromList = iso Map.toList Map.fromList++object :: SyntaxText syn => Indent syn Value+object = _Object . mapFromList + /$~ S.char '{'+ /*/ S.indented (+ S.breakLine /*/+ S.sepBy field (S.spaces_ /* S.char ',' /* S.breakLine)+ )+ /*/ S.breakLine /*/ S.char '}'+ where field = string /* S.spaces_ /* S.char ':' /* S.spaces /*/ value++array :: SyntaxText syn => Indent syn Value+array = _Array + /$~ S.char '[' + /*/ S.indented (+ S.breakLine /*/+ S.sepBy value (S.spaces_ /* S.char ',' /* S.breakLine)+ )+ /*/ S.breakLine /*/ S.char ']'++value :: SyntaxText syn => Indent syn Value+value = _String /$/ string+ /|/ _Number /$/ S.scientific+ /|/ object+ /|/ array+ /|/ _Bool . exact True /$/ S.string "true"+ /|/ _Bool . exact False /$/ S.string "false"+ /|/ _Null /$/ S.string "null"+ /?/ "Invalid JSON."++main :: IO ()+main = do+ -- Load the standard input.+ t <- T.getContents++ -- Indent with 2 spaces.+ let tab :: SyntaxText syn => syn ()+ tab = sireplicate_ 2 (S.char ' ')+ parser = S.getParser $ S.runIndent value tab+ printer = S.runPrinter $ S.runIndent value tab++ -- Try to parse it.+ case AP.parse (AP.skipSpace *> parser <* AP.skipSpace <* AP.endOfInput) t of+ AP.Fail _ _ err -> putStrLn err+ AP.Done _ val -> do+ -- Try to pretty print it.+ -- (Printing cannot really fail in this example)+ case printer val of+ Left err -> putStrLn err+ Right bld -> T.putStrLn (T.toLazyText bld)++ return ()
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ syntax-example-json.cabal view
@@ -0,0 +1,32 @@+name: syntax-example-json+version: 0.2.0.0+synopsis: Example JSON parser/pretty-printer.+description:+ Example JSON parser/pretty-printer.+ .+ Source code:+ .+ * <https://github.com/Pawel834/syntax-example-json/blob/master/Main.hs Main.hs>+ .+ Example input and output:+ .+ * <https://github.com/Pawel834/syntax-example-json/blob/master/in.json in.json>+ * <https://github.com/Pawel834/syntax-example-json/blob/master/out.json out.json>+license: MIT+license-file: LICENSE+author: Paweł Nowak+maintainer: Paweł Nowak <pawel834@gmail.com>+copyright: Paweł Nowak 2014+category: Data+build-type: Simple+cabal-version: >=1.10++source-repository head+ type: git+ location: git@github.com:Pawel834/syntax-example-json.git++executable syntax-example-json+ main-is: Main.hs+ default-language: Haskell2010+ build-depends: base <5, semi-iso >= 0.5, syntax >= 0.3, syntax-attoparsec, syntax-printer,+ containers, text, scientific, lens, attoparsec