mirror of
https://github.com/GrammaticalFramework/gf-core.git
synced 2026-05-08 02:32:50 -06:00
replace aeson with json
This commit is contained in:
3
gf.cabal
3
gf.cabal
@@ -143,8 +143,7 @@ Library
|
|||||||
---- GF compiler as a library:
|
---- GF compiler as a library:
|
||||||
|
|
||||||
build-depends: filepath, directory, time, time-compat,
|
build-depends: filepath, directory, time, time-compat,
|
||||||
process, haskeline, parallel>=3,
|
process, haskeline, parallel>=3
|
||||||
aeson>=1.3, yaml, unordered-containers, scientific, text
|
|
||||||
|
|
||||||
hs-source-dirs: src/compiler
|
hs-source-dirs: src/compiler
|
||||||
exposed-modules:
|
exposed-modules:
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ exportPGF opts fmt pgf =
|
|||||||
FmtPGFPretty -> multi "txt" (render . ppPGF)
|
FmtPGFPretty -> multi "txt" (render . ppPGF)
|
||||||
FmtCanonicalGF -> [] -- canon "gf" (render80 . abstract2canonical)
|
FmtCanonicalGF -> [] -- canon "gf" (render80 . abstract2canonical)
|
||||||
FmtCanonicalJson-> []
|
FmtCanonicalJson-> []
|
||||||
FmtCanonicalYaml-> []
|
|
||||||
FmtJavaScript -> multi "js" pgf2js
|
FmtJavaScript -> multi "js" pgf2js
|
||||||
FmtPython -> multi "py" pgf2python
|
FmtPython -> multi "py" pgf2python
|
||||||
FmtHaskell -> multi "hs" (grammar2haskell opts name)
|
FmtHaskell -> multi "hs" (grammar2haskell opts name)
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ import Data.Maybe
|
|||||||
import qualified Data.Map as Map
|
import qualified Data.Map as Map
|
||||||
import qualified Data.Set as Set
|
import qualified Data.Set as Set
|
||||||
import qualified Data.ByteString.Lazy as BSL
|
import qualified Data.ByteString.Lazy as BSL
|
||||||
import GF.Grammar.CanonicalJSON (encodeJSON, encodeYAML)
|
import GF.Grammar.CanonicalJSON (encodeJSON)
|
||||||
import System.FilePath
|
import System.FilePath
|
||||||
import Control.Monad(when,unless,forM_)
|
import Control.Monad(when,unless,forM_)
|
||||||
|
|
||||||
@@ -65,7 +65,6 @@ compileSourceFiles opts fs =
|
|||||||
mapM_ abs2canonical canonical
|
mapM_ abs2canonical canonical
|
||||||
mapM_ cnc2canonical canonical
|
mapM_ cnc2canonical canonical
|
||||||
when (FmtCanonicalJson `elem` ofmts) $ mapM_ grammar2json canonical
|
when (FmtCanonicalJson `elem` ofmts) $ mapM_ grammar2json canonical
|
||||||
when (FmtCanonicalYaml `elem` ofmts) $ mapM_ grammar2yaml canonical
|
|
||||||
where
|
where
|
||||||
ofmts = flag optOutputFormats opts
|
ofmts = flag optOutputFormats opts
|
||||||
|
|
||||||
@@ -86,10 +85,6 @@ compileSourceFiles opts fs =
|
|||||||
where absname = srcAbsName gr cnc
|
where absname = srcAbsName gr cnc
|
||||||
gr_canon = grammar2canonical opts absname gr
|
gr_canon = grammar2canonical opts absname gr
|
||||||
|
|
||||||
grammar2yaml (cnc,gr) = encodeYAML (render absname ++ ".yaml") gr_canon
|
|
||||||
where absname = srcAbsName gr cnc
|
|
||||||
gr_canon = grammar2canonical opts absname gr
|
|
||||||
|
|
||||||
writeExport (path,s) = writing opts path $ writeUTF8File path s
|
writeExport (path,s) = writing opts path $ writeUTF8File path s
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,35 +1,14 @@
|
|||||||
{-# language OverloadedStrings, OverloadedLists #-}
|
|
||||||
|
|
||||||
module GF.Grammar.CanonicalJSON (
|
module GF.Grammar.CanonicalJSON (
|
||||||
encodeJSON, encodeYAML,
|
encodeJSON
|
||||||
decodeJSON, decodeYAML
|
|
||||||
) where
|
) where
|
||||||
|
|
||||||
|
import Text.JSON
|
||||||
import qualified Control.Monad as CM (mapM, msum)
|
import qualified Control.Monad as CM (mapM, msum)
|
||||||
import qualified Data.HashMap.Strict as HM (toList)
|
|
||||||
import qualified Data.Yaml as Yaml (encodeFile, decodeFileEither, ParseException)
|
|
||||||
import qualified Data.Aeson as Aeson (encodeFile, eitherDecodeFileStrict')
|
|
||||||
import Data.Aeson (ToJSON(..), object, (.=))
|
|
||||||
import Data.Aeson (FromJSON(..), Value(..), withObject, (.:), (.:?), (.!=))
|
|
||||||
import Data.Aeson.Types (typeMismatch, modifyFailure, Pair, Parser)
|
|
||||||
import Data.Text (Text, pack, unpack)
|
|
||||||
import Data.Scientific (floatingOrInteger)
|
|
||||||
|
|
||||||
import GF.Grammar.Canonical
|
import GF.Grammar.Canonical
|
||||||
|
|
||||||
|
|
||||||
encodeJSON :: FilePath -> Grammar -> IO ()
|
encodeJSON :: FilePath -> Grammar -> IO ()
|
||||||
encodeJSON = Aeson.encodeFile
|
encodeJSON fpath g = writeFile fpath (encode g)
|
||||||
|
|
||||||
encodeYAML :: FilePath -> Grammar -> IO ()
|
|
||||||
encodeYAML = Yaml.encodeFile
|
|
||||||
|
|
||||||
decodeJSON :: FilePath -> IO (Either String Grammar)
|
|
||||||
decodeJSON = Aeson.eitherDecodeFileStrict'
|
|
||||||
|
|
||||||
decodeYAML :: FilePath -> IO (Either Yaml.ParseException Grammar)
|
|
||||||
decodeYAML = Yaml.decodeFileEither
|
|
||||||
|
|
||||||
|
|
||||||
-- in general we encode grammars using JSON objects/records,
|
-- in general we encode grammars using JSON objects/records,
|
||||||
@@ -38,317 +17,157 @@ decodeYAML = Yaml.decodeFileEither
|
|||||||
-- the top-level definitions use normal record labels,
|
-- the top-level definitions use normal record labels,
|
||||||
-- but recursive types/values/ids use labels staring with a "."
|
-- but recursive types/values/ids use labels staring with a "."
|
||||||
|
|
||||||
instance ToJSON Grammar where
|
instance JSON Grammar where
|
||||||
toJSON (Grammar abs cncs) = object ["abstract" .= abs, "concretes" .= cncs]
|
showJSON (Grammar abs cncs) = makeObj [("abstract", showJSON abs), ("concretes", showJSON cncs)]
|
||||||
|
|
||||||
instance FromJSON Grammar where
|
|
||||||
parseJSON = withObject "Grammar" $ \o -> Grammar <$> o .: "abstract" <*> o .: "concretes"
|
|
||||||
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
-- ** Abstract Syntax
|
-- ** Abstract Syntax
|
||||||
|
|
||||||
instance ToJSON Abstract where
|
instance JSON Abstract where
|
||||||
toJSON (Abstract absid flags cats funs)
|
showJSON (Abstract absid flags cats funs)
|
||||||
= object ["abs" .= absid,
|
= makeObj [("abs", showJSON absid),
|
||||||
"flags" .= flags,
|
("flags", showJSON flags),
|
||||||
"cats" .= cats,
|
("cats", showJSON cats),
|
||||||
"funs" .= funs]
|
("funs", showJSON funs)]
|
||||||
|
|
||||||
instance FromJSON Abstract where
|
instance JSON CatDef where
|
||||||
parseJSON = withObject "Abstract" $ \o -> Abstract
|
|
||||||
<$> o .: "abs"
|
|
||||||
<*> o .:? "flags" .!= Flags []
|
|
||||||
<*> o .: "cats"
|
|
||||||
<*> o .: "funs"
|
|
||||||
|
|
||||||
|
|
||||||
instance ToJSON CatDef where
|
|
||||||
-- non-dependent categories are encoded as simple strings:
|
-- non-dependent categories are encoded as simple strings:
|
||||||
toJSON (CatDef c []) = toJSON c
|
showJSON (CatDef c []) = showJSON c
|
||||||
toJSON (CatDef c cs) = object ["cat" .= c, "args" .= cs]
|
showJSON (CatDef c cs) = makeObj [("cat", showJSON c), ("args", showJSON cs)]
|
||||||
|
|
||||||
instance FromJSON CatDef where
|
|
||||||
parseJSON (String s) = return $ CatDef (CatId (unpack s)) []
|
|
||||||
parseJSON (Object o) = CatDef <$> o .: "cat" <*> o .: "args"
|
|
||||||
parseJSON val = typeMismatch "CatDef" val
|
|
||||||
|
|
||||||
|
|
||||||
instance ToJSON FunDef where
|
|
||||||
toJSON (FunDef f ty) = object ["fun" .= f, "type" .= ty]
|
|
||||||
|
|
||||||
|
instance JSON FunDef where
|
||||||
|
showJSON (FunDef f ty) = makeObj [("fun", showJSON f), ("type", showJSON ty)]
|
||||||
|
{-
|
||||||
instance FromJSON FunDef where
|
instance FromJSON FunDef where
|
||||||
parseJSON = withObject "FunDef" $ \o -> FunDef <$> o .: "fun" <*> o .: "type"
|
parseJSON = withObject "FunDef" $ \o -> FunDef <$> o .: "fun" <*> o .: "type"
|
||||||
|
-}
|
||||||
|
|
||||||
|
instance JSON Type where
|
||||||
|
showJSON (Type bs ty) = makeObj [("args", showJSON bs), ("result", showJSON ty)]
|
||||||
|
|
||||||
instance ToJSON Type where
|
instance JSON TypeApp where
|
||||||
toJSON (Type bs ty) = object [".args" .= bs, ".result" .= ty]
|
|
||||||
|
|
||||||
instance FromJSON Type where
|
|
||||||
parseJSON = withObject "Type" $ \o -> Type <$> o .: ".args" <*> o .: ".result"
|
|
||||||
|
|
||||||
|
|
||||||
instance ToJSON TypeApp where
|
|
||||||
-- non-dependent categories are encoded as simple strings:
|
-- non-dependent categories are encoded as simple strings:
|
||||||
toJSON (TypeApp c []) = toJSON c
|
showJSON (TypeApp c []) = showJSON c
|
||||||
toJSON (TypeApp c args) = object [".cat" .= c, ".args" .= args]
|
showJSON (TypeApp c args) = makeObj [("cat", showJSON c), ("args", showJSON args)]
|
||||||
|
|
||||||
instance FromJSON TypeApp where
|
instance JSON TypeBinding where
|
||||||
parseJSON (String s) = return $ TypeApp (CatId (unpack s)) []
|
|
||||||
parseJSON (Object o) = TypeApp <$> o .: ".cat" <*> o .: ".args"
|
|
||||||
parseJSON val = typeMismatch "TypeApp" val
|
|
||||||
|
|
||||||
|
|
||||||
instance ToJSON TypeBinding where
|
|
||||||
-- non-dependent categories are encoded as simple strings:
|
-- non-dependent categories are encoded as simple strings:
|
||||||
toJSON (TypeBinding Anonymous (Type [] (TypeApp c []))) = toJSON c
|
showJSON (TypeBinding Anonymous (Type [] (TypeApp c []))) = showJSON c
|
||||||
toJSON (TypeBinding x ty) = object [".var" .= x, ".type" .= ty]
|
showJSON (TypeBinding x ty) = makeObj [("var", showJSON x), ("type", showJSON ty)]
|
||||||
|
|
||||||
instance FromJSON TypeBinding where
|
|
||||||
parseJSON (String s) = return $ TypeBinding Anonymous (Type [] (TypeApp (CatId (unpack s)) []))
|
|
||||||
parseJSON (Object o) = TypeBinding <$> o .: ".var" <*> o .: ".type"
|
|
||||||
parseJSON val = typeMismatch "TypeBinding" val
|
|
||||||
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
-- ** Concrete syntax
|
-- ** Concrete syntax
|
||||||
|
|
||||||
instance ToJSON Concrete where
|
instance JSON Concrete where
|
||||||
toJSON (Concrete cncid absid flags params lincats lins)
|
showJSON (Concrete cncid absid flags params lincats lins)
|
||||||
= object ["cnc" .= cncid,
|
= makeObj [("cnc", showJSON cncid),
|
||||||
"abs" .= absid,
|
("abs", showJSON absid),
|
||||||
"flags" .= flags,
|
("flags", showJSON flags),
|
||||||
"params" .= params,
|
("params", showJSON params),
|
||||||
"lincats" .= lincats,
|
("lincats", showJSON lincats),
|
||||||
"lins" .= lins]
|
("lins", showJSON lins)]
|
||||||
|
|
||||||
instance FromJSON Concrete where
|
instance JSON ParamDef where
|
||||||
parseJSON = withObject "Concrete" $ \o -> Concrete
|
showJSON (ParamDef p pvs) = makeObj [("param", showJSON p), ("values", showJSON pvs)]
|
||||||
<$> o .: "cnc"
|
showJSON (ParamAliasDef p t) = makeObj [("param", showJSON p), ("alias", showJSON t)]
|
||||||
<*> o .: "abs"
|
|
||||||
<*> o .:? "flags" .!= Flags []
|
|
||||||
<*> o .: "params"
|
|
||||||
<*> o .: "lincats"
|
|
||||||
<*> o .: "lins"
|
|
||||||
|
|
||||||
|
instance JSON LincatDef where
|
||||||
|
showJSON (LincatDef c lt) = makeObj [("cat", showJSON c), ("lintype", showJSON lt)]
|
||||||
|
|
||||||
instance ToJSON ParamDef where
|
instance JSON LinDef where
|
||||||
toJSON (ParamDef p pvs) = object ["param" .= p, "values" .= pvs]
|
showJSON (LinDef f xs lv) = makeObj [("fun", showJSON f), ("args", showJSON xs), ("lin", showJSON lv)]
|
||||||
toJSON (ParamAliasDef p t) = object ["param" .= p, "alias" .= t]
|
|
||||||
|
|
||||||
instance FromJSON ParamDef where
|
instance JSON LinType where
|
||||||
parseJSON = withObject "ParamDef" $ \o ->
|
showJSON lt = case lt of
|
||||||
choose [ ParamDef <$> o .: "param" <*> o .: "values"
|
|
||||||
, ParamAliasDef <$> o .: "param" <*> o .: "alias"
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
instance ToJSON LincatDef where
|
|
||||||
toJSON (LincatDef c lt) = object ["cat" .= c, "lintype" .= lt]
|
|
||||||
|
|
||||||
instance FromJSON LincatDef where
|
|
||||||
parseJSON = withObject "LincatDef" $ \v -> LincatDef <$> v .: "cat" <*> v .: "lintype"
|
|
||||||
|
|
||||||
|
|
||||||
instance ToJSON LinDef where
|
|
||||||
toJSON (LinDef f xs lv) = object ["fun" .= f, "args" .= xs, "lin" .= lv]
|
|
||||||
|
|
||||||
instance FromJSON LinDef where
|
|
||||||
parseJSON = withObject "LinDef" $ \v -> LinDef <$> v .: "fun" <*> v .: "args" <*> v .: "lin"
|
|
||||||
|
|
||||||
|
|
||||||
instance ToJSON LinType where
|
|
||||||
toJSON lt = case lt of
|
|
||||||
-- the basic types (Str, Float, Int) are encoded as strings:
|
-- the basic types (Str, Float, Int) are encoded as strings:
|
||||||
StrType -> "Str"
|
StrType -> showJSON "Str"
|
||||||
FloatType -> "Float"
|
FloatType -> showJSON "Float"
|
||||||
IntType -> "Int"
|
IntType -> showJSON "Int"
|
||||||
-- parameters are also encoded as strings:
|
-- parameters are also encoded as strings:
|
||||||
ParamType pt -> toJSON pt
|
ParamType pt -> showJSON pt
|
||||||
-- tables/tuples are encoded as JSON objects:
|
-- tables/tuples are encoded as JSON objects:
|
||||||
TableType pt lt -> object [".tblarg" .= pt, ".tblval" .= lt]
|
TableType pt lt -> makeObj [("tblarg", showJSON pt), ("tblval", showJSON lt)]
|
||||||
TupleType lts -> object [".tuple" .= lts]
|
TupleType lts -> makeObj [("tuple", showJSON lts)]
|
||||||
-- records are encoded as records:
|
-- records are encoded as records:
|
||||||
RecordType rows -> toJSON rows
|
RecordType rows -> showJSON rows
|
||||||
|
|
||||||
instance FromJSON LinType where
|
instance JSON LinValue where
|
||||||
parseJSON (String "Str") = return StrType
|
showJSON lv = case lv of
|
||||||
parseJSON (String "Float") = return FloatType
|
|
||||||
parseJSON (String "Int") = return IntType
|
|
||||||
parseJSON (String param) = return (ParamType (ParamTypeId (ParamId (unpack param))))
|
|
||||||
parseJSON val@(Object o) = choose [ (TableType <$> o .: ".tblarg" <*> o .: ".tblval")
|
|
||||||
, (TupleType <$> o .: ".tuple")
|
|
||||||
, (RecordType <$> parseJSON val)
|
|
||||||
]
|
|
||||||
parseJSON val = typeMismatch "LinType" val
|
|
||||||
|
|
||||||
|
|
||||||
instance ToJSON LinValue where
|
|
||||||
toJSON lv = case lv of
|
|
||||||
-- basic values (Str, Float, Int) are encoded as JSON strings/numbers:
|
-- basic values (Str, Float, Int) are encoded as JSON strings/numbers:
|
||||||
StrConstant s -> toJSON s
|
StrConstant s -> showJSON s
|
||||||
FloatConstant f -> toJSON f
|
FloatConstant f -> showJSON f
|
||||||
IntConstant n -> toJSON n
|
IntConstant n -> showJSON n
|
||||||
-- concatenation is encoded as a JSON array:
|
-- concatenation is encoded as a JSON array:
|
||||||
ConcatValue v v' -> Array [toJSON v, toJSON v']
|
ConcatValue v v' -> showJSON [showJSON v, showJSON v']
|
||||||
-- most values are encoded as JSON objects:
|
-- most values are encoded as JSON objects:
|
||||||
ParamConstant pv -> object [".param" .= pv]
|
ParamConstant pv -> makeObj [("param", showJSON pv)]
|
||||||
PredefValue p -> object [".predef" .= p]
|
PredefValue p -> makeObj [("predef", showJSON p)]
|
||||||
TableValue t tvs -> object [".tblarg" .= t, ".tblrows" .= tvs]
|
TableValue t tvs -> makeObj [("tblarg", showJSON t), ("tblrows", showJSON tvs)]
|
||||||
-- VTableValue t ts -> object [".vtblarg" .= t, ".vtblrows" .= ts]
|
TupleValue lvs -> makeObj [("tuple", showJSON lvs)]
|
||||||
TupleValue lvs -> object [".tuple" .= lvs]
|
VarValue v -> makeObj [("var", showJSON v)]
|
||||||
VarValue v -> object [".var" .= v]
|
ErrorValue s -> makeObj [("error", showJSON s)]
|
||||||
ErrorValue s -> object [".error" .= s]
|
Projection lv l -> makeObj [("project", showJSON lv), ("label", showJSON l)]
|
||||||
Projection lv l -> object [".project" .= lv, ".label" .= l]
|
Selection tv pv -> makeObj [("select", showJSON tv), ("key", showJSON pv)]
|
||||||
Selection tv pv -> object [".select" .= tv, ".key" .= pv]
|
VariantValue vs -> makeObj [("variants", showJSON vs)]
|
||||||
VariantValue vs -> object [".variants" .= vs]
|
PreValue alts def -> makeObj [("pre", showJSON alts), ("default", showJSON def)]
|
||||||
PreValue alts def -> object [".pre" .= alts, ".default" .= def]
|
|
||||||
-- records are encoded directly as JSON records:
|
-- records are encoded directly as JSON records:
|
||||||
RecordValue rows -> toJSON rows
|
RecordValue rows -> showJSON rows
|
||||||
|
|
||||||
instance FromJSON LinValue where
|
instance JSON LinPattern where
|
||||||
parseJSON (String s) = return (StrConstant (unpack s))
|
showJSON linpat = case linpat of
|
||||||
parseJSON (Number n) = return (either FloatConstant IntConstant (floatingOrInteger n))
|
|
||||||
parseJSON (Array [v,v']) = ConcatValue <$> parseJSON v <*> parseJSON v'
|
|
||||||
parseJSON val@(Object o) = choose [ ParamConstant <$> o .: ".param"
|
|
||||||
, PredefValue <$> o .: ".predef"
|
|
||||||
, TableValue <$> o .: ".tblarg" <*> o .: ".tblrows"
|
|
||||||
-- , VTableValue <$> o .: ".vtblarg" <*> o .: ".vtblrows"
|
|
||||||
, TupleValue <$> o .: ".tuple"
|
|
||||||
, VarValue <$> o .: ".var"
|
|
||||||
, ErrorValue <$> o .: ".error"
|
|
||||||
, Projection <$> o .: ".project" <*> o .: ".label"
|
|
||||||
, Selection <$> o .: ".select" <*> o .: ".key"
|
|
||||||
, VariantValue <$> o .: ".variants"
|
|
||||||
, PreValue <$> o .: ".pre" <*> o .: ".default"
|
|
||||||
, RecordValue <$> parseJSON val
|
|
||||||
]
|
|
||||||
parseJSON val = typeMismatch "LinValue" val
|
|
||||||
|
|
||||||
|
|
||||||
instance ToJSON LinPattern where
|
|
||||||
toJSON linpat = case linpat of
|
|
||||||
-- wildcards and patterns without arguments are encoded as strings:
|
-- wildcards and patterns without arguments are encoded as strings:
|
||||||
WildPattern -> "_"
|
WildPattern -> showJSON "_"
|
||||||
ParamPattern (Param p []) -> toJSON p
|
ParamPattern (Param p []) -> showJSON p
|
||||||
-- complex patterns are encoded as JSON objects:
|
-- complex patterns are encoded as JSON objects:
|
||||||
ParamPattern pv -> toJSON pv
|
ParamPattern pv -> showJSON pv
|
||||||
-- and records as records:
|
-- and records as records:
|
||||||
RecordPattern r -> toJSON r
|
RecordPattern r -> showJSON r
|
||||||
|
|
||||||
instance FromJSON LinPattern where
|
instance JSON arg => JSON (Param arg) where
|
||||||
parseJSON (String "_") = return WildPattern
|
|
||||||
parseJSON (String s) = return (ParamPattern (Param (ParamId (unpack s)) []))
|
|
||||||
parseJSON val = choose [ ParamPattern <$> parseJSON val
|
|
||||||
, RecordPattern <$> parseJSON val
|
|
||||||
, typeMismatch "LinPattern" val
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
instance ToJSON arg => ToJSON (Param arg) where
|
|
||||||
-- parameters without arguments are encoded as strings:
|
-- parameters without arguments are encoded as strings:
|
||||||
toJSON (Param p []) = toJSON p
|
showJSON (Param p []) = showJSON p
|
||||||
toJSON (Param p args) = object [".paramid" .= p, ".args" .= args]
|
showJSON (Param p args) = makeObj [("paramid", showJSON p), ("args", showJSON args)]
|
||||||
|
|
||||||
instance FromJSON arg => FromJSON (Param arg) where
|
instance JSON a => JSON (RecordRow a) where
|
||||||
parseJSON (String p) = return (Param (ParamId (unpack p)) [])
|
|
||||||
parseJSON (Object o) = Param <$> o .: ".paramid" <*> o .: ".args"
|
|
||||||
parseJSON val = typeMismatch "Param" val
|
|
||||||
|
|
||||||
|
|
||||||
instance ToJSON a => ToJSON (RecordRow a) where
|
|
||||||
-- record rows and lists of record rows are both encoded as JSON records (i.e., objects)
|
-- record rows and lists of record rows are both encoded as JSON records (i.e., objects)
|
||||||
toJSON row = object [toJSONRecordRow row]
|
showJSON row = makeObj [toJSONRecordRow row]
|
||||||
toJSONList = object . map toJSONRecordRow
|
|
||||||
|
|
||||||
toJSONRecordRow :: ToJSON a => RecordRow a -> Pair
|
toJSONRecordRow :: JSON a => RecordRow a -> (String,JSValue)
|
||||||
toJSONRecordRow (RecordRow (LabelId lbl) val) = pack lbl .= val
|
toJSONRecordRow (RecordRow (LabelId lbl) val) = (lbl, showJSON val)
|
||||||
|
|
||||||
instance FromJSON a => FromJSON (RecordRow a) where
|
instance JSON TableRowValue where
|
||||||
parseJSON = withObject "RecordRow" $ \o -> parseJSONRecordRow (head (HM.toList o))
|
showJSON (TableRowValue l v) = makeObj [("pattern", showJSON l), ("value", showJSON l)]
|
||||||
parseJSONList = withObject "[RecordRow]" $ \o -> CM.mapM parseJSONRecordRow (HM.toList o)
|
|
||||||
|
|
||||||
parseJSONRecordRow :: FromJSON a => (Text, Value) -> Parser (RecordRow a)
|
|
||||||
parseJSONRecordRow (lbl, val) = do val' <- parseJSON val
|
|
||||||
return (RecordRow (LabelId (unpack lbl)) val')
|
|
||||||
|
|
||||||
|
|
||||||
instance ToJSON TableRowValue where
|
|
||||||
toJSON (TableRowValue l v) = object [".pattern" .= l, ".value" .= v]
|
|
||||||
|
|
||||||
instance FromJSON TableRowValue where
|
|
||||||
parseJSON = withObject "TableRowValue" $ \v -> TableRowValue <$> v .: ".pattern" <*> v .: ".value"
|
|
||||||
|
|
||||||
|
|
||||||
-- *** Identifiers in Concrete Syntax
|
-- *** Identifiers in Concrete Syntax
|
||||||
|
|
||||||
instance ToJSON PredefId where toJSON (PredefId s) = toJSON s
|
instance JSON PredefId where showJSON (PredefId s) = showJSON s
|
||||||
instance ToJSON LabelId where toJSON (LabelId s) = toJSON s
|
instance JSON LabelId where showJSON (LabelId s) = showJSON s
|
||||||
instance ToJSON VarValueId where toJSON (VarValueId s) = toJSON s
|
instance JSON VarValueId where showJSON (VarValueId s) = showJSON s
|
||||||
instance ToJSON ParamId where toJSON (ParamId s) = toJSON s
|
instance JSON ParamId where showJSON (ParamId s) = showJSON s
|
||||||
instance ToJSON ParamType where toJSON (ParamTypeId s) = toJSON s
|
instance JSON ParamType where showJSON (ParamTypeId s) = showJSON s
|
||||||
|
|
||||||
instance FromJSON PredefId where parseJSON = coerceFrom "PredefId" PredefId
|
|
||||||
instance FromJSON LabelId where parseJSON = coerceFrom "LabelId" LabelId
|
|
||||||
instance FromJSON VarValueId where parseJSON = coerceFrom "VarValueId" VarValueId
|
|
||||||
instance FromJSON ParamId where parseJSON = coerceFrom "ParamId" ParamId
|
|
||||||
instance FromJSON ParamType where parseJSON = coerceFrom "ParamType" ParamTypeId
|
|
||||||
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
-- ** Used in both Abstract and Concrete Syntax
|
-- ** Used in both Abstract and Concrete Syntax
|
||||||
|
|
||||||
instance ToJSON ModId where toJSON (ModId s) = toJSON s
|
instance JSON ModId where showJSON (ModId s) = showJSON s
|
||||||
instance ToJSON CatId where toJSON (CatId s) = toJSON s
|
instance JSON CatId where showJSON (CatId s) = showJSON s
|
||||||
instance ToJSON FunId where toJSON (FunId s) = toJSON s
|
instance JSON FunId where showJSON (FunId s) = showJSON s
|
||||||
|
|
||||||
instance FromJSON ModId where parseJSON = coerceFrom "ModId" ModId
|
instance JSON VarId where
|
||||||
instance FromJSON CatId where parseJSON = coerceFrom "CatId" CatId
|
|
||||||
instance FromJSON FunId where parseJSON = coerceFrom "FunId" FunId
|
|
||||||
|
|
||||||
|
|
||||||
instance ToJSON VarId where
|
|
||||||
-- the anonymous variable is the underscore:
|
-- the anonymous variable is the underscore:
|
||||||
toJSON Anonymous = "_"
|
showJSON Anonymous = showJSON "_"
|
||||||
toJSON (VarId x) = toJSON x
|
showJSON (VarId x) = showJSON x
|
||||||
|
|
||||||
instance FromJSON VarId where
|
instance JSON Flags where
|
||||||
parseJSON (String "_") = return Anonymous
|
|
||||||
parseJSON (String s) = return (VarId (unpack s))
|
|
||||||
parseJSON val = typeMismatch "VarId" val
|
|
||||||
|
|
||||||
|
|
||||||
instance ToJSON Flags where
|
|
||||||
-- flags are encoded directly as JSON records (i.e., objects):
|
-- flags are encoded directly as JSON records (i.e., objects):
|
||||||
toJSON (Flags fs) = object [ pack f .= v | (f, v) <- fs ]
|
showJSON (Flags fs) = makeObj [(f,showJSON v) | (f, v) <- fs]
|
||||||
|
|
||||||
instance FromJSON Flags where
|
instance JSON FlagValue where
|
||||||
parseJSON = withObject "Flags" $ \o -> Flags <$> CM.mapM parseJSONFlag (HM.toList o)
|
|
||||||
where parseJSONFlag (flag, val) = do val' <- parseJSON val
|
|
||||||
return (unpack flag, val')
|
|
||||||
|
|
||||||
|
|
||||||
instance ToJSON FlagValue where
|
|
||||||
-- flag values are encoded as basic JSON types:
|
-- flag values are encoded as basic JSON types:
|
||||||
toJSON (Str s) = toJSON s
|
showJSON (Str s) = showJSON s
|
||||||
toJSON (Int i) = toJSON i
|
showJSON (Int i) = showJSON i
|
||||||
toJSON (Flt f) = toJSON f
|
showJSON (Flt f) = showJSON f
|
||||||
|
|
||||||
instance FromJSON FlagValue where
|
|
||||||
parseJSON (String s) = return $ Str (unpack s)
|
|
||||||
parseJSON (Number n) = return $ case floatingOrInteger n of
|
|
||||||
Left f -> Flt f
|
|
||||||
Right i -> Int i
|
|
||||||
parseJSON invalid = typeMismatch "FlagValue" invalid
|
|
||||||
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
|
||||||
-- ** Helper functions
|
|
||||||
|
|
||||||
choose :: [Parser a] -> Parser a
|
|
||||||
choose = CM.msum
|
|
||||||
|
|
||||||
coerceFrom :: FromJSON s => String -> (s -> a) -> Value -> Parser a
|
|
||||||
coerceFrom expected constructor obj = modifyFailure failure $ fmap constructor $ parseJSON obj
|
|
||||||
where failure f = "(while parsing " ++ expected ++ ") " ++ f
|
|
||||||
|
|
||||||
|
|||||||
@@ -89,7 +89,6 @@ data Phase = Preproc | Convert | Compile | Link
|
|||||||
data OutputFormat = FmtPGFPretty
|
data OutputFormat = FmtPGFPretty
|
||||||
| FmtCanonicalGF
|
| FmtCanonicalGF
|
||||||
| FmtCanonicalJson
|
| FmtCanonicalJson
|
||||||
| FmtCanonicalYaml
|
|
||||||
| FmtJavaScript
|
| FmtJavaScript
|
||||||
| FmtPython
|
| FmtPython
|
||||||
| FmtHaskell
|
| FmtHaskell
|
||||||
@@ -474,7 +473,6 @@ outputFormatsExpl =
|
|||||||
[(("pgf_pretty", FmtPGFPretty),"human-readable pgf"),
|
[(("pgf_pretty", FmtPGFPretty),"human-readable pgf"),
|
||||||
(("canonical_gf", FmtCanonicalGF),"Canonical GF source files"),
|
(("canonical_gf", FmtCanonicalGF),"Canonical GF source files"),
|
||||||
(("canonical_json", FmtCanonicalJson),"Canonical JSON source files"),
|
(("canonical_json", FmtCanonicalJson),"Canonical JSON source files"),
|
||||||
(("canonical_yaml", FmtCanonicalYaml),"Canonical YAML source files"),
|
|
||||||
(("js", FmtJavaScript),"JavaScript (whole grammar)"),
|
(("js", FmtJavaScript),"JavaScript (whole grammar)"),
|
||||||
(("python", FmtPython),"Python (whole grammar)"),
|
(("python", FmtPython),"Python (whole grammar)"),
|
||||||
(("haskell", FmtHaskell),"Haskell (abstract syntax)"),
|
(("haskell", FmtHaskell),"Haskell (abstract syntax)"),
|
||||||
|
|||||||
Reference in New Issue
Block a user