forked from GitHub/gf-core
Use ebnf srg generation in PrSRGS.
This commit is contained in:
@@ -8,7 +8,7 @@
|
|||||||
-- Utilities for creating XML documents.
|
-- Utilities for creating XML documents.
|
||||||
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
|
|
||||||
module GF.Data.XML (XML(..), Attr, comments, showsXMLDoc, showsXML) where
|
module GF.Data.XML (XML(..), Attr, comments, showsXMLDoc, showsXML, bottomUpXML) where
|
||||||
|
|
||||||
import GF.Data.Utilities
|
import GF.Data.Utilities
|
||||||
|
|
||||||
@@ -48,3 +48,7 @@ escape = concatMap escChar
|
|||||||
escChar '&' = "&"
|
escChar '&' = "&"
|
||||||
escChar '"' = """
|
escChar '"' = """
|
||||||
escChar c = [c]
|
escChar c = [c]
|
||||||
|
|
||||||
|
bottomUpXML :: (XML -> XML) -> XML -> XML
|
||||||
|
bottomUpXML f (Tag n attrs cs) = f (Tag n attrs (map (bottomUpXML f) cs))
|
||||||
|
bottomUpXML f x = f x
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ srgsXmlPrinter name start opts sisr probs cfg = prSrgsXml sisr srg ""
|
|||||||
prSrgsXml :: Maybe SISRFormat -> SRG -> ShowS
|
prSrgsXml :: Maybe SISRFormat -> SRG -> ShowS
|
||||||
prSrgsXml sisr (SRG{grammarName=name,startCat=start,
|
prSrgsXml sisr (SRG{grammarName=name,startCat=start,
|
||||||
origStartCat=origStart,grammarLanguage=l,rules=rs})
|
origStartCat=origStart,grammarLanguage=l,rules=rs})
|
||||||
= showsXMLDoc xmlGr
|
= showsXMLDoc $ optimizeSRGS xmlGr
|
||||||
where
|
where
|
||||||
root = cfgCatToGFCat origStart
|
root = cfgCatToGFCat origStart
|
||||||
xmlGr = grammar sisr root l $
|
xmlGr = grammar sisr root l $
|
||||||
@@ -58,13 +58,8 @@ prSrgsXml sisr (SRG{grammarName=name,startCat=start,
|
|||||||
++ topCatRules
|
++ topCatRules
|
||||||
++ concatMap ruleToXML rs
|
++ concatMap ruleToXML rs
|
||||||
ruleToXML (SRGRule cat origCat alts) =
|
ruleToXML (SRGRule cat origCat alts) =
|
||||||
comments ["Category " ++ origCat] ++ [rule (prCat cat) (prRhs isList alts)]
|
comments ["Category " ++ origCat] ++ [rule (prCat cat) (prRhs $ ebnfSRGAlts alts)]
|
||||||
where isList = False
|
prRhs rhss = [oneOf (map (mkProd sisr) rhss)]
|
||||||
-- Disabled list build since OptimTalk can't handle it ATM
|
|
||||||
{- "List" `isPrefixOf` origCat && length cs == 2
|
|
||||||
&& isBase (cs!!0) && isCons (cs!!1) -}
|
|
||||||
cs = sortNub [f | SRGAlt _ (Name f _) _ <- alts]
|
|
||||||
prRhs isList rhss = [oneOf (map (mkProd sisr isList) rhss)]
|
|
||||||
-- externally visible rules for each of the GF categories
|
-- externally visible rules for each of the GF categories
|
||||||
topCatRules = [topRule tc [oneOf (map (it tc) cs)] | (tc,cs) <- topCats]
|
topCatRules = [topRule tc [oneOf (map (it tc) cs)] | (tc,cs) <- topCats]
|
||||||
where topCats = buildMultiMap [(cfgCatToGFCat origCat, cat) | SRGRule cat origCat _ <- rs]
|
where topCats = buildMultiMap [(cfgCatToGFCat origCat, cat) | SRGRule cat origCat _ <- rs]
|
||||||
@@ -78,39 +73,21 @@ rule i = Tag "rule" [("id",i)]
|
|||||||
cfgCatToGFCat :: String -> String
|
cfgCatToGFCat :: String -> String
|
||||||
cfgCatToGFCat = takeWhile (/='{')
|
cfgCatToGFCat = takeWhile (/='{')
|
||||||
|
|
||||||
isBase :: Fun -> Bool
|
mkProd :: Maybe SISRFormat -> EBnfSRGAlt -> XML
|
||||||
isBase f = "Base" `isPrefixOf` prIdent f
|
mkProd sisr (EBnfSRGAlt mp n@(Name f prs) rhs) = Tag "item" w (t ++ xs)
|
||||||
|
where xs = [mkItem sisr rhs]
|
||||||
|
w = maybe [] (\p -> [("weight", show p)]) mp
|
||||||
|
t = [tag sisr ts]
|
||||||
|
ts = [(EThis :. "name") := (EStr (prIdent f))] ++
|
||||||
|
[(EThis :. ("arg" ++ show n)) := (EStr (argInit (prs!!n)))
|
||||||
|
| n <- [0..length prs-1]]
|
||||||
|
argInit (Unify _) = "?"
|
||||||
|
argInit (Constant f) = maybe "?" prIdent (forestName f)
|
||||||
|
|
||||||
isCons :: Fun -> Bool
|
mkItem :: Maybe SISRFormat -> EBnfSRGItem -> XML
|
||||||
isCons f = "Cons" `isPrefixOf` prIdent f
|
mkItem sisr (EBnfOneOf xs) = oneOf (map (mkItem sisr) xs)
|
||||||
|
mkItem sisr (EBnfSeq xs) = Tag "item" [] (map (mkItem sisr) xs)
|
||||||
mkProd :: Maybe SISRFormat -> Bool -> SRGAlt -> XML
|
mkItem sisr (EBnfSymbol s) = symItem sisr s
|
||||||
mkProd sisr isList (SRGAlt p n@(Name f pr) rhs)
|
|
||||||
= prodItem sisr n p (r ++ if isList then [tag sisr buildList] else [])
|
|
||||||
where
|
|
||||||
r = map (symItem sisr) rhs
|
|
||||||
buildList | isBase f = [EThis := (ENew "Array" args)]
|
|
||||||
| isCons f = [EApp (EThis :. "arg1" :. "unshift") [EThis :. "arg0"],
|
|
||||||
EThis := (EThis :. "arg1")]
|
|
||||||
where args = [EThis :. ("arg"++show n) | n <- [0..length pr-1]]
|
|
||||||
|
|
||||||
prodItem :: Maybe SISRFormat -> Name -> Maybe Double -> [XML] -> XML
|
|
||||||
prodItem sisr n mp xs = Tag "item" w (t++cs)
|
|
||||||
where
|
|
||||||
w = maybe [] (\p -> [("weight", show p)]) mp
|
|
||||||
t = prodTag sisr n
|
|
||||||
cs = case xs of
|
|
||||||
[Tag "item" [] xs'] -> xs'
|
|
||||||
_ -> xs
|
|
||||||
|
|
||||||
prodTag :: Maybe SISRFormat -> Name -> [XML]
|
|
||||||
prodTag sisr (Name f prs) = [tag sisr ts]
|
|
||||||
where
|
|
||||||
ts = [(EThis :. "name") := (EStr (prIdent f))] ++
|
|
||||||
[(EThis :. ("arg" ++ show n)) := (EStr (argInit (prs!!n)))
|
|
||||||
| n <- [0..length prs-1]]
|
|
||||||
argInit (Unify _) = "?"
|
|
||||||
argInit (Constant f) = maybe "?" prIdent (forestName f)
|
|
||||||
|
|
||||||
symItem :: Maybe SISRFormat -> Symbol SRGNT Token -> XML
|
symItem :: Maybe SISRFormat -> Symbol SRGNT Token -> XML
|
||||||
symItem sisr (Cat (c,slots)) = Tag "item" [] ([Tag "ruleref" [("uri","#" ++ prCat c)] []]++t)
|
symItem sisr (Cat (c,slots)) = Tag "item" [] ([Tag "ruleref" [("uri","#" ++ prCat c)] []]++t)
|
||||||
@@ -148,6 +125,12 @@ grammar sisr root l =
|
|||||||
meta :: String -> String -> XML
|
meta :: String -> String -> XML
|
||||||
meta n c = Tag "meta" [("name",n),("content",c)] []
|
meta n c = Tag "meta" [("name",n),("content",c)] []
|
||||||
|
|
||||||
|
optimizeSRGS :: XML -> XML
|
||||||
|
optimizeSRGS = bottomUpXML f
|
||||||
|
where f (Tag "item" [] [x@(Tag "item" [] _)]) = x
|
||||||
|
f (Tag "one-of" [] [x]) = x
|
||||||
|
f x = x
|
||||||
|
|
||||||
{-
|
{-
|
||||||
|
|
||||||
--
|
--
|
||||||
|
|||||||
@@ -22,7 +22,10 @@ module GF.Speech.SRG (SRG(..), SRGRule(..), SRGAlt(..),
|
|||||||
SRGCat, SRGNT,
|
SRGCat, SRGNT,
|
||||||
makeSimpleSRG, makeSRG
|
makeSimpleSRG, makeSRG
|
||||||
, lookupFM_, prtS
|
, lookupFM_, prtS
|
||||||
, topDownFilter) where
|
, topDownFilter
|
||||||
|
, EBnfSRGAlt(..), EBnfSRGItem(..)
|
||||||
|
, ebnfSRGAlts
|
||||||
|
) where
|
||||||
|
|
||||||
import GF.Data.Operations
|
import GF.Data.Operations
|
||||||
import GF.Data.Utilities
|
import GF.Data.Utilities
|
||||||
@@ -163,6 +166,26 @@ topDownFilter srg@(SRG { startCat = start, rules = rs }) = srg { rules = rs' }
|
|||||||
allSRGCats :: SRG -> [String]
|
allSRGCats :: SRG -> [String]
|
||||||
allSRGCats SRG { rules = rs } = [c | SRGRule c _ _ <- rs]
|
allSRGCats SRG { rules = rs } = [c | SRGRule c _ _ <- rs]
|
||||||
|
|
||||||
|
--
|
||||||
|
-- * Size-optimized EBNF SRGs
|
||||||
|
--
|
||||||
|
|
||||||
|
data EBnfSRGAlt = EBnfSRGAlt (Maybe Double) Name EBnfSRGItem
|
||||||
|
deriving (Eq,Show)
|
||||||
|
|
||||||
|
data EBnfSRGItem =
|
||||||
|
EBnfOneOf [EBnfSRGItem]
|
||||||
|
| EBnfSeq [EBnfSRGItem]
|
||||||
|
| EBnfSymbol (Symbol SRGNT Token)
|
||||||
|
deriving (Eq,Show)
|
||||||
|
|
||||||
|
ebnfSRGAlts :: [SRGAlt] -> [EBnfSRGAlt]
|
||||||
|
ebnfSRGAlts alts = [EBnfSRGAlt p n (ebnfSRGItem sss)
|
||||||
|
| ((p,n),sss) <- buildMultiMap [((p,n),ss) | SRGAlt p n ss <- alts]]
|
||||||
|
|
||||||
|
ebnfSRGItem :: [[Symbol SRGNT Token]] -> EBnfSRGItem
|
||||||
|
ebnfSRGItem sss = EBnfOneOf (map (EBnfSeq . map EBnfSymbol) sss)
|
||||||
|
|
||||||
--
|
--
|
||||||
-- * Utilities for building and printing SRGs
|
-- * Utilities for building and printing SRGs
|
||||||
--
|
--
|
||||||
|
|||||||
Reference in New Issue
Block a user