mirror of
https://github.com/GrammaticalFramework/gf-core.git
synced 2026-05-22 09:32:53 -06:00
Merge branch 'master' of https://github.com/GrammaticalFramework/gf-core
This commit is contained in:
@@ -3,7 +3,8 @@ module GF.Grammar.CanonicalJSON (
|
|||||||
) where
|
) where
|
||||||
|
|
||||||
import Text.JSON
|
import Text.JSON
|
||||||
import qualified Control.Monad as CM (mapM, msum)
|
import Control.Applicative ((<|>))
|
||||||
|
import Data.Ratio (denominator, numerator)
|
||||||
import GF.Grammar.Canonical
|
import GF.Grammar.Canonical
|
||||||
|
|
||||||
|
|
||||||
@@ -20,6 +21,8 @@ encodeJSON fpath g = writeFile fpath (encode g)
|
|||||||
instance JSON Grammar where
|
instance JSON Grammar where
|
||||||
showJSON (Grammar abs cncs) = makeObj [("abstract", showJSON abs), ("concretes", showJSON cncs)]
|
showJSON (Grammar abs cncs) = makeObj [("abstract", showJSON abs), ("concretes", showJSON cncs)]
|
||||||
|
|
||||||
|
readJSON o = Grammar <$> o!"abstract" <*> o!"concretes"
|
||||||
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
-- ** Abstract Syntax
|
-- ** Abstract Syntax
|
||||||
@@ -31,30 +34,46 @@ instance JSON Abstract where
|
|||||||
("cats", showJSON cats),
|
("cats", showJSON cats),
|
||||||
("funs", showJSON funs)]
|
("funs", showJSON funs)]
|
||||||
|
|
||||||
|
readJSON o = Abstract
|
||||||
|
<$> o!"abs"
|
||||||
|
<*>(o!"flags" <|> return (Flags []))
|
||||||
|
<*> o!"cats"
|
||||||
|
<*> o!"funs"
|
||||||
|
|
||||||
instance JSON CatDef where
|
instance JSON CatDef where
|
||||||
-- non-dependent categories are encoded as simple strings:
|
-- non-dependent categories are encoded as simple strings:
|
||||||
showJSON (CatDef c []) = showJSON c
|
showJSON (CatDef c []) = showJSON c
|
||||||
showJSON (CatDef c cs) = makeObj [("cat", showJSON c), ("args", showJSON cs)]
|
showJSON (CatDef c cs) = makeObj [("cat", showJSON c), ("args", showJSON cs)]
|
||||||
|
|
||||||
|
readJSON o = CatDef <$> readJSON o <*> return []
|
||||||
|
<|> CatDef <$> o!"cat" <*> o!"args"
|
||||||
|
|
||||||
instance JSON FunDef where
|
instance JSON FunDef where
|
||||||
showJSON (FunDef f ty) = makeObj [("fun", showJSON f), ("type", showJSON ty)]
|
showJSON (FunDef f ty) = makeObj [("fun", showJSON f), ("type", showJSON ty)]
|
||||||
{-
|
|
||||||
instance FromJSON FunDef where
|
readJSON o = FunDef <$> o!"fun" <*> o!"type"
|
||||||
parseJSON = withObject "FunDef" $ \o -> FunDef <$> o .: "fun" <*> o .: "type"
|
|
||||||
-}
|
|
||||||
|
|
||||||
instance JSON Type where
|
instance JSON Type where
|
||||||
showJSON (Type bs ty) = makeObj [("args", showJSON bs), ("result", showJSON ty)]
|
showJSON (Type bs ty) = makeObj [(".args", showJSON bs), (".result", showJSON ty)]
|
||||||
|
|
||||||
|
readJSON o = Type <$> o!".args" <*> o!".result"
|
||||||
|
|
||||||
instance JSON TypeApp where
|
instance JSON TypeApp where
|
||||||
-- non-dependent categories are encoded as simple strings:
|
-- non-dependent categories are encoded as simple strings:
|
||||||
showJSON (TypeApp c []) = showJSON c
|
showJSON (TypeApp c []) = showJSON c
|
||||||
showJSON (TypeApp c args) = makeObj [("cat", showJSON c), ("args", showJSON args)]
|
showJSON (TypeApp c args) = makeObj [(".cat", showJSON c), (".args", showJSON args)]
|
||||||
|
|
||||||
|
readJSON o = TypeApp <$> readJSON o <*> return []
|
||||||
|
<|> TypeApp <$> o!".cat" <*> o!".args"
|
||||||
|
|
||||||
instance JSON TypeBinding where
|
instance JSON TypeBinding where
|
||||||
-- non-dependent categories are encoded as simple strings:
|
-- non-dependent categories are encoded as simple strings:
|
||||||
showJSON (TypeBinding Anonymous (Type [] (TypeApp c []))) = showJSON c
|
showJSON (TypeBinding Anonymous (Type [] (TypeApp c []))) = showJSON c
|
||||||
showJSON (TypeBinding x ty) = makeObj [("var", showJSON x), ("type", showJSON ty)]
|
showJSON (TypeBinding x ty) = makeObj [(".var", showJSON x), (".type", showJSON ty)]
|
||||||
|
|
||||||
|
readJSON o = do c <- readJSON o
|
||||||
|
return (TypeBinding Anonymous (Type [] (TypeApp c [])))
|
||||||
|
<|> TypeBinding <$> o!".var" <*> o!".type"
|
||||||
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
@@ -69,113 +88,202 @@ instance JSON Concrete where
|
|||||||
("lincats", showJSON lincats),
|
("lincats", showJSON lincats),
|
||||||
("lins", showJSON lins)]
|
("lins", showJSON lins)]
|
||||||
|
|
||||||
|
readJSON o = Concrete
|
||||||
|
<$> o!"cnc"
|
||||||
|
<*> o!"abs"
|
||||||
|
<*>(o!"flags" <|> return (Flags []))
|
||||||
|
<*> o!"params"
|
||||||
|
<*> o!"lincats"
|
||||||
|
<*> o!"lins"
|
||||||
|
|
||||||
instance JSON ParamDef where
|
instance JSON ParamDef where
|
||||||
showJSON (ParamDef p pvs) = makeObj [("param", showJSON p), ("values", showJSON pvs)]
|
showJSON (ParamDef p pvs) = makeObj [("param", showJSON p), ("values", showJSON pvs)]
|
||||||
showJSON (ParamAliasDef p t) = makeObj [("param", showJSON p), ("alias", showJSON t)]
|
showJSON (ParamAliasDef p t) = makeObj [("param", showJSON p), ("alias", showJSON t)]
|
||||||
|
|
||||||
|
readJSON o = ParamDef <$> o!"param" <*> o!"values"
|
||||||
|
<|> ParamAliasDef <$> o!"param" <*> o!"alias"
|
||||||
|
|
||||||
instance JSON LincatDef where
|
instance JSON LincatDef where
|
||||||
showJSON (LincatDef c lt) = makeObj [("cat", showJSON c), ("lintype", showJSON lt)]
|
showJSON (LincatDef c lt) = makeObj [("cat", showJSON c), ("lintype", showJSON lt)]
|
||||||
|
|
||||||
|
readJSON o = LincatDef <$> o!"cat" <*> o!"lintype"
|
||||||
|
|
||||||
instance JSON LinDef where
|
instance JSON LinDef where
|
||||||
showJSON (LinDef f xs lv) = makeObj [("fun", showJSON f), ("args", showJSON xs), ("lin", showJSON lv)]
|
showJSON (LinDef f xs lv) = makeObj [("fun", showJSON f), ("args", showJSON xs), ("lin", showJSON lv)]
|
||||||
|
|
||||||
|
readJSON o = LinDef <$> o!"fun" <*> o!"args" <*> o!"lin"
|
||||||
|
|
||||||
instance JSON LinType where
|
instance JSON LinType where
|
||||||
showJSON 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 -> showJSON "Str"
|
showJSON (StrType) = showJSON "Str"
|
||||||
FloatType -> showJSON "Float"
|
showJSON (FloatType) = showJSON "Float"
|
||||||
IntType -> showJSON "Int"
|
showJSON (IntType) = showJSON "Int"
|
||||||
-- parameters are also encoded as strings:
|
-- parameters are also encoded as strings:
|
||||||
ParamType pt -> showJSON pt
|
showJSON (ParamType pt) = showJSON pt
|
||||||
-- tables/tuples are encoded as JSON objects:
|
-- tables/tuples are encoded as JSON objects:
|
||||||
TableType pt lt -> makeObj [("tblarg", showJSON pt), ("tblval", showJSON lt)]
|
showJSON (TableType pt lt) = makeObj [(".tblarg", showJSON pt), (".tblval", showJSON lt)]
|
||||||
TupleType lts -> makeObj [("tuple", showJSON lts)]
|
showJSON (TupleType lts) = makeObj [(".tuple", showJSON lts)]
|
||||||
-- records are encoded as records:
|
-- records are encoded as records:
|
||||||
RecordType rows -> showJSON rows
|
showJSON (RecordType rows) = showJSON rows
|
||||||
|
|
||||||
|
readJSON o = do "Str" <- readJSON o; return StrType
|
||||||
|
<|> do "Float" <- readJSON o; return FloatType
|
||||||
|
<|> do "Int" <- readJSON o; return IntType
|
||||||
|
<|> do ptype <- readJSON o; return (ParamType ptype)
|
||||||
|
<|> TableType <$> o!".tblarg" <*> o!".tblval"
|
||||||
|
<|> TupleType <$> o!".tuple"
|
||||||
|
<|> RecordType <$> readJSON o
|
||||||
|
|
||||||
instance JSON LinValue where
|
instance JSON LinValue where
|
||||||
showJSON lv = case lv of
|
showJSON (LiteralValue l ) = showJSON l
|
||||||
LiteralValue l -> showJSON l
|
|
||||||
-- concatenation is encoded as a JSON array:
|
|
||||||
ConcatValue v v' -> showJSON [showJSON v, showJSON v']
|
|
||||||
-- most values are encoded as JSON objects:
|
-- most values are encoded as JSON objects:
|
||||||
ParamConstant pv -> makeObj [("param", showJSON pv)]
|
showJSON (ParamConstant pv) = makeObj [(".param", showJSON pv)]
|
||||||
PredefValue p -> makeObj [("predef", showJSON p)]
|
showJSON (PredefValue p ) = makeObj [(".predef", showJSON p)]
|
||||||
TableValue t tvs -> makeObj [("tblarg", showJSON t), ("tblrows", showJSON tvs)]
|
showJSON (TableValue t tvs) = makeObj [(".tblarg", showJSON t), (".tblrows", showJSON tvs)]
|
||||||
TupleValue lvs -> makeObj [("tuple", showJSON lvs)]
|
showJSON (TupleValue lvs) = makeObj [(".tuple", showJSON lvs)]
|
||||||
VarValue v -> makeObj [("var", showJSON v)]
|
showJSON (VarValue v ) = makeObj [(".var", showJSON v)]
|
||||||
ErrorValue s -> makeObj [("error", showJSON s)]
|
showJSON (ErrorValue s ) = makeObj [(".error", showJSON s)]
|
||||||
Projection lv l -> makeObj [("project", showJSON lv), ("label", showJSON l)]
|
showJSON (Projection lv l ) = makeObj [(".project", showJSON lv), (".label", showJSON l)]
|
||||||
Selection tv pv -> makeObj [("select", showJSON tv), ("key", showJSON pv)]
|
showJSON (Selection tv pv) = makeObj [(".select", showJSON tv), (".key", showJSON pv)]
|
||||||
VariantValue vs -> makeObj [("variants", showJSON vs)]
|
showJSON (VariantValue vs) = makeObj [(".variants", showJSON vs)]
|
||||||
PreValue alts def -> makeObj [("pre", showJSON alts), ("default", showJSON def)]
|
showJSON (PreValue pre def) = makeObj [(".pre", showJSON pre),(".default", showJSON def)]
|
||||||
-- records are encoded directly as JSON records:
|
-- records are encoded directly as JSON records:
|
||||||
RecordValue rows -> showJSON rows
|
showJSON (RecordValue rows) = showJSON rows
|
||||||
|
-- concatenation is encoded as a JSON array:
|
||||||
|
showJSON v@(ConcatValue _ _) = showJSON (flatten v [])
|
||||||
|
where flatten (ConcatValue v v') = flatten v . flatten v'
|
||||||
|
flatten v = (v :)
|
||||||
|
|
||||||
|
readJSON o = LiteralValue <$> readJSON o
|
||||||
|
<|> ParamConstant <$> o!".param"
|
||||||
|
<|> PredefValue <$> o!".predef"
|
||||||
|
<|> TableValue <$> o!".tblarg" <*> o!".tblrows"
|
||||||
|
<|> 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 <$> readJSON o
|
||||||
|
<|> do vs <- readJSON o :: Result [LinValue]
|
||||||
|
return (foldr1 ConcatValue vs)
|
||||||
|
|
||||||
instance JSON LinLiteral where
|
instance JSON LinLiteral where
|
||||||
showJSON l = case l 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 -> showJSON s
|
showJSON (StrConstant s) = showJSON s
|
||||||
FloatConstant f -> showJSON f
|
showJSON (FloatConstant f) = showJSON f
|
||||||
IntConstant n -> showJSON n
|
showJSON (IntConstant n) = showJSON n
|
||||||
|
|
||||||
|
readJSON = readBasicJSON StrConstant IntConstant FloatConstant
|
||||||
|
|
||||||
instance JSON LinPattern where
|
instance JSON LinPattern where
|
||||||
showJSON linpat = case linpat of
|
|
||||||
-- wildcards and patterns without arguments are encoded as strings:
|
-- wildcards and patterns without arguments are encoded as strings:
|
||||||
WildPattern -> showJSON "_"
|
showJSON (WildPattern) = showJSON "_"
|
||||||
ParamPattern (Param p []) -> showJSON p
|
showJSON (ParamPattern (Param p [])) = showJSON p
|
||||||
-- complex patterns are encoded as JSON objects:
|
-- complex patterns are encoded as JSON objects:
|
||||||
ParamPattern pv -> showJSON pv
|
showJSON (ParamPattern pv) = showJSON pv
|
||||||
-- and records as records:
|
-- and records as records:
|
||||||
RecordPattern r -> showJSON r
|
showJSON (RecordPattern r) = showJSON r
|
||||||
|
|
||||||
|
readJSON o = do "_" <- readJSON o; return WildPattern
|
||||||
|
<|> do p <- readJSON o; return (ParamPattern (Param p []))
|
||||||
|
<|> ParamPattern <$> readJSON o
|
||||||
|
<|> RecordPattern <$> readJSON o
|
||||||
|
|
||||||
instance JSON arg => JSON (Param arg) where
|
instance JSON arg => JSON (Param arg) where
|
||||||
-- parameters without arguments are encoded as strings:
|
-- parameters without arguments are encoded as strings:
|
||||||
showJSON (Param p []) = showJSON p
|
showJSON (Param p []) = showJSON p
|
||||||
showJSON (Param p args) = makeObj [("paramid", showJSON p), ("args", showJSON args)]
|
showJSON (Param p args) = makeObj [(".paramid", showJSON p), (".args", showJSON args)]
|
||||||
|
|
||||||
|
readJSON o = Param <$> readJSON o <*> return []
|
||||||
|
<|> Param <$> o!".paramid" <*> o!".args"
|
||||||
|
|
||||||
instance JSON a => JSON (RecordRow a) where
|
instance JSON a => JSON (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)
|
||||||
showJSON row = makeObj [toJSONRecordRow row]
|
showJSON row = showJSONs [row]
|
||||||
|
showJSONs rows = makeObj (map toRow rows)
|
||||||
|
where toRow (RecordRow (LabelId lbl) val) = (lbl, showJSON val)
|
||||||
|
|
||||||
toJSONRecordRow :: JSON a => RecordRow a -> (String,JSValue)
|
readJSON obj = head <$> readJSONs obj
|
||||||
toJSONRecordRow (RecordRow (LabelId lbl) val) = (lbl, showJSON val)
|
readJSONs obj = mapM fromRow (assocsJSObject obj)
|
||||||
|
where fromRow (lbl, jsvalue) = do value <- readJSON jsvalue
|
||||||
|
return (RecordRow (LabelId lbl) value)
|
||||||
|
|
||||||
instance JSON TableRowValue where
|
instance JSON TableRowValue where
|
||||||
showJSON (TableRowValue l v) = makeObj [("pattern", showJSON l), ("value", showJSON l)]
|
showJSON (TableRowValue l v) = makeObj [(".pattern", showJSON l), (".value", showJSON v)]
|
||||||
|
|
||||||
|
readJSON o = TableRowValue <$> o!".pattern" <*> o!".value"
|
||||||
|
|
||||||
|
|
||||||
-- *** Identifiers in Concrete Syntax
|
-- *** Identifiers in Concrete Syntax
|
||||||
|
|
||||||
instance JSON PredefId where showJSON (PredefId s) = showJSON s
|
instance JSON PredefId where showJSON (PredefId s) = showJSON s ; readJSON = fmap PredefId . readJSON
|
||||||
instance JSON LabelId where showJSON (LabelId s) = showJSON s
|
instance JSON LabelId where showJSON (LabelId s) = showJSON s ; readJSON = fmap LabelId . readJSON
|
||||||
instance JSON VarValueId where showJSON (VarValueId s) = showJSON s
|
instance JSON VarValueId where showJSON (VarValueId s) = showJSON s ; readJSON = fmap VarValueId . readJSON
|
||||||
instance JSON ParamId where showJSON (ParamId s) = showJSON s
|
instance JSON ParamId where showJSON (ParamId s) = showJSON s ; readJSON = fmap ParamId . readJSON
|
||||||
instance JSON ParamType where showJSON (ParamTypeId s) = showJSON s
|
instance JSON ParamType where showJSON (ParamTypeId s) = showJSON s ; readJSON = fmap ParamTypeId . readJSON
|
||||||
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
-- ** Used in both Abstract and Concrete Syntax
|
-- ** Used in both Abstract and Concrete Syntax
|
||||||
|
|
||||||
instance JSON ModId where showJSON (ModId s) = showJSON s
|
instance JSON ModId where showJSON (ModId s) = showJSON s ; readJSON = fmap ModId . readJSON
|
||||||
instance JSON CatId where showJSON (CatId s) = showJSON s
|
instance JSON CatId where showJSON (CatId s) = showJSON s ; readJSON = fmap CatId . readJSON
|
||||||
instance JSON FunId where showJSON (FunId s) = showJSON s
|
instance JSON FunId where showJSON (FunId s) = showJSON s ; readJSON = fmap FunId . readJSON
|
||||||
|
|
||||||
instance JSON VarId where
|
instance JSON VarId where
|
||||||
-- the anonymous variable is the underscore:
|
-- the anonymous variable is the underscore:
|
||||||
showJSON Anonymous = showJSON "_"
|
showJSON Anonymous = showJSON "_"
|
||||||
showJSON (VarId x) = showJSON x
|
showJSON (VarId x) = showJSON x
|
||||||
|
|
||||||
|
readJSON o = do "_" <- readJSON o; return Anonymous
|
||||||
|
<|> VarId <$> readJSON o
|
||||||
|
|
||||||
instance JSON QualId where
|
instance JSON QualId where
|
||||||
showJSON (Qual (ModId m) n) = showJSON (m++"_"++n)
|
showJSON (Qual (ModId m) n) = showJSON (m++"."++n)
|
||||||
showJSON (Unqual n) = showJSON n
|
showJSON (Unqual n) = showJSON n
|
||||||
|
|
||||||
|
readJSON o = do qualid <- readJSON o
|
||||||
|
let (mod, id) = span (/= '.') qualid
|
||||||
|
return $ if null mod then Unqual id else Qual (ModId mod) id
|
||||||
|
|
||||||
instance JSON Flags where
|
instance JSON Flags where
|
||||||
-- flags are encoded directly as JSON records (i.e., objects):
|
-- flags are encoded directly as JSON records (i.e., objects):
|
||||||
showJSON (Flags fs) = makeObj [(f, showJSON v) | (f, v) <- fs]
|
showJSON (Flags fs) = makeObj [(f, showJSON v) | (f, v) <- fs]
|
||||||
|
|
||||||
|
readJSON obj = Flags <$> mapM fromRow (assocsJSObject obj)
|
||||||
|
where fromRow (lbl, jsvalue) = do value <- readJSON jsvalue
|
||||||
|
return (lbl, value)
|
||||||
|
|
||||||
instance JSON FlagValue where
|
instance JSON FlagValue where
|
||||||
-- flag values are encoded as basic JSON types:
|
-- flag values are encoded as basic JSON types:
|
||||||
showJSON (Str s) = showJSON s
|
showJSON (Str s) = showJSON s
|
||||||
showJSON (Int i) = showJSON i
|
showJSON (Int i) = showJSON i
|
||||||
showJSON (Flt f) = showJSON f
|
showJSON (Flt f) = showJSON f
|
||||||
|
|
||||||
|
readJSON = readBasicJSON Str Int Flt
|
||||||
|
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
-- ** Convenience functions
|
||||||
|
|
||||||
|
(!) :: JSON a => JSValue -> String -> Result a
|
||||||
|
obj ! key = maybe (fail $ "CanonicalJSON.(!): Could not find key: " ++ show key)
|
||||||
|
readJSON
|
||||||
|
(lookup key (assocsJSObject obj))
|
||||||
|
|
||||||
|
assocsJSObject :: JSValue -> [(String, JSValue)]
|
||||||
|
assocsJSObject (JSObject o) = fromJSObject o
|
||||||
|
assocsJSObject (JSArray _) = fail $ "CanonicalJSON.assocsJSObject: Expected a JSON object, found an Array"
|
||||||
|
assocsJSObject jsvalue = fail $ "CanonicalJSON.assocsJSObject: Expected a JSON object, found " ++ show jsvalue
|
||||||
|
|
||||||
|
|
||||||
|
readBasicJSON :: (JSON int, Integral int, JSON flt, RealFloat flt) =>
|
||||||
|
(String -> v) -> (int -> v) -> (flt -> v) -> JSValue -> Result v
|
||||||
|
readBasicJSON str int flt o
|
||||||
|
= str <$> readJSON o
|
||||||
|
<|> int_or_flt <$> readJSON o
|
||||||
|
where int_or_flt f | f == fromIntegral n = int n
|
||||||
|
| otherwise = flt f
|
||||||
|
where n = round f
|
||||||
|
|||||||
@@ -327,7 +327,7 @@ optDescr =
|
|||||||
Option [] ["gfo-dir"] (ReqArg gfoDir "DIR") "Directory to put .gfo files in (default = '.').",
|
Option [] ["gfo-dir"] (ReqArg gfoDir "DIR") "Directory to put .gfo files in (default = '.').",
|
||||||
Option ['f'] ["output-format"] (ReqArg outFmt "FMT")
|
Option ['f'] ["output-format"] (ReqArg outFmt "FMT")
|
||||||
(unlines ["Output format. FMT can be one of:",
|
(unlines ["Output format. FMT can be one of:",
|
||||||
"Canonical GF grammar: canonical_gf, canonical_json, canonical_yaml, (and haskell with option --haskell=concrete)",
|
"Canonical GF grammar: canonical_gf, canonical_json, (and haskell with option --haskell=concrete)",
|
||||||
"Multiple concrete: pgf (default), js, pgf_pretty, prolog, python, ...", -- gar,
|
"Multiple concrete: pgf (default), js, pgf_pretty, prolog, python, ...", -- gar,
|
||||||
"Single concrete only: bnf, ebnf, fa, gsl, jsgf, regexp, slf, srgs_xml, srgs_abnf, vxml, ....", -- cf, lbnf,
|
"Single concrete only: bnf, ebnf, fa, gsl, jsgf, regexp, slf, srgs_xml, srgs_abnf, vxml, ....", -- cf, lbnf,
|
||||||
"Abstract only: haskell, ..."]), -- prolog_abs,
|
"Abstract only: haskell, ..."]), -- prolog_abs,
|
||||||
|
|||||||
Reference in New Issue
Block a user