"Committed_by_peb"

This commit is contained in:
peb
2005-04-14 17:38:36 +00:00
parent b63b29a247
commit 95c6e8a58f
11 changed files with 302 additions and 97 deletions

View File

@@ -5,9 +5,9 @@
-- Stability : (stable) -- Stability : (stable)
-- Portability : (portable) -- Portability : (portable)
-- --
-- > CVS $Date: 2005/04/11 13:53:38 $ -- > CVS $Date: 2005/04/14 18:38:36 $
-- > CVS $Author: peb $ -- > CVS $Author: peb $
-- > CVS $Revision: 1.13 $ -- > CVS $Revision: 1.14 $
-- --
-- Handles printing a CFGrammar in CFGM format. -- Handles printing a CFGrammar in CFGM format.
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
@@ -19,12 +19,20 @@ import qualified PrintCFG
import Ident import Ident
import GFC import GFC
import Modules import Modules
import qualified GF.OldParsing.ConvertGrammar as Cnv
import qualified GF.Printing.PrintParser as Prt -- import qualified GF.OldParsing.ConvertGrammar as Cnv
import qualified GF.OldParsing.CFGrammar as CFGrammar -- import qualified GF.Printing.PrintParser as Prt
import qualified GF.OldParsing.GrammarTypes as GT -- import qualified GF.OldParsing.CFGrammar as CFGrammar
-- import qualified GF.OldParsing.GrammarTypes as GT
-- import qualified AbsCFG
-- import qualified GF.OldParsing.Utilities as Parser
import qualified GF.Conversion.GFC as Cnv
import GF.Infra.Print (prt)
import GF.Formalism.CFG (CFRule(..))
import qualified GF.Conversion.Types as GT
import qualified AbsCFG import qualified AbsCFG
import qualified GF.OldParsing.Utilities as Parser import GF.Formalism.Utilities (Symbol(..))
import ErrM import ErrM
import qualified Option import qualified Option
@@ -48,8 +56,9 @@ getFlag fs x = listToMaybe [v | Flg (IC k) (IC v) <- fs, k == x]
-- | OBS! Should use 'ShellState.statePInfo' or 'ShellState.pInfos' -- | OBS! Should use 'ShellState.statePInfo' or 'ShellState.pInfos'
-- instead of 'Cnv.pInfo' (which recalculates the grammar every time) -- instead of 'Cnv.pInfo' (which recalculates the grammar every time)
prLangAsCFGM :: CanonGrammar -> Ident -> Maybe String -> String prLangAsCFGM :: CanonGrammar -> Ident -> Maybe String -> String
prLangAsCFGM gr i start = prCFGrammarAsCFGM (Cnv.cfg (Cnv.pInfo opts gr i)) i start prLangAsCFGM gr i start = prCFGrammarAsCFGM (Cnv.gfc2cfg (gr, i)) i start
where opts = Option.Opts [Option.gfcConversion "nondet"] -- prLangAsCFGM gr i start = prCFGrammarAsCFGM (Cnv.cfg (Cnv.pInfo opts gr i)) i start
-- where opts = Option.Opts [Option.gfcConversion "nondet"]
{- {-
prCFGrammarAsCFGM :: GT.CFGrammar -> Ident -> Maybe String -> String prCFGrammarAsCFGM :: GT.CFGrammar -> Ident -> Maybe String -> String
@@ -57,21 +66,21 @@ prCFGrammarAsCFGM gr i@(IC lang) start = (header . startcat . rules . footer) ""
where where
header = showString "grammar " . showString lang . showString "\n" header = showString "grammar " . showString lang . showString "\n"
startcat = maybe id (\s -> showString "startcat " . showString (s++"{}.s") . showString ";\n") start startcat = maybe id (\s -> showString "startcat " . showString (s++"{}.s") . showString ";\n") start
rules0 = map Prt.prt gr rules0 = map prt gr
rules = showString $ concat $ map (\l -> init l++";\n") rules0 rules = showString $ concat $ map (\l -> init l++";\n") rules0
footer = showString "end grammar\n" footer = showString "end grammar\n"
-} -}
prCFGrammarAsCFGM :: GT.CFGrammar -> Ident -> Maybe String -> String prCFGrammarAsCFGM :: GT.CGrammar -> Ident -> Maybe String -> String
prCFGrammarAsCFGM gr i start = PrintCFG.printTree $ cfGrammarToCFGM gr i start prCFGrammarAsCFGM gr i start = PrintCFG.printTree $ cfGrammarToCFGM gr i start
cfGrammarToCFGM :: GT.CFGrammar -> Ident -> Maybe String -> AbsCFG.Grammar cfGrammarToCFGM :: GT.CGrammar -> Ident -> Maybe String -> AbsCFG.Grammar
cfGrammarToCFGM gr i start = AbsCFG.Grammar (identToCFGMIdent i) flags (map ruleToCFGMRule gr) cfGrammarToCFGM gr i start = AbsCFG.Grammar (identToCFGMIdent i) flags (map ruleToCFGMRule gr)
where flags = maybe [] (\c -> [AbsCFG.StartCat $ strToCFGMCat (c++"{}.s")]) start where flags = maybe [] (\c -> [AbsCFG.StartCat $ strToCFGMCat (c++"{}.s")]) start
ruleToCFGMRule :: GT.CFRule -> AbsCFG.Rule ruleToCFGMRule :: GT.CRule -> AbsCFG.Rule
-- new version, without the MCFName constructor: -- new version, without the MCFName constructor:
ruleToCFGMRule (CFGrammar.Rule c rhs (GT.CFName fun profile)) ruleToCFGMRule (CFRule c rhs (GT.Name fun profile))
= AbsCFG.Rule fun' p' c' rhs' = AbsCFG.Rule fun' p' c' rhs'
where where
fun' = identToFun fun fun' = identToFun fun
@@ -84,17 +93,20 @@ ruleToCFGMRule (CFGrammar.Rule c rhs (GT.CFName (GT.MCFName fun cat args) lbl pr
= AbsCFG.Rule fun' n' p' c' rhs' = AbsCFG.Rule fun' n' p' c' rhs'
where where
fun' = identToCFGMIdent fun fun' = identToCFGMIdent fun
n' = strToCFGMName (Prt.prt cat ++ concat [ "/" ++ Prt.prt arg | arg <- args ] ++ Prt.prt lbl) n' = strToCFGMName (prt cat ++ concat [ "/" ++ prt arg | arg <- args ] ++ prt lbl)
p' = profileToCFGMProfile profile p' = profileToCFGMProfile profile
c' = catToCFGMCat c c' = catToCFGMCat c
rhs' = map symbolToGFCMSymbol rhs rhs' = map symbolToGFCMSymbol rhs
-} -}
profileToCFGMProfile :: GT.CFProfile -> AbsCFG.Profile profileToCFGMProfile :: [GT.Profile a] -> AbsCFG.Profile
profileToCFGMProfile = AbsCFG.Profile . map (AbsCFG.Ints . map fromIntegral) profileToCFGMProfile = AbsCFG.Profile . map cnvProfile
where cnvProfile (GT.Unify ns) = AbsCFG.Ints $ map fromIntegral ns
cnvProfile (GT.Constant a) = AbsCFG.Ints []
-- this should be replaced with a new constructor in 'AbsCFG'
identToCFGMIdent :: Ident -> AbsCFG.Ident identToCFGMIdent :: Ident -> AbsCFG.Ident
identToCFGMIdent = AbsCFG.Ident . Prt.prt identToCFGMIdent = AbsCFG.Ident . prt
identToFun :: Ident -> AbsCFG.Fun identToFun :: Ident -> AbsCFG.Fun
identToFun IW = AbsCFG.Coerce identToFun IW = AbsCFG.Coerce
@@ -103,12 +115,12 @@ identToFun i = AbsCFG.Cons (identToCFGMIdent i)
strToCFGMCat :: String -> AbsCFG.Category strToCFGMCat :: String -> AbsCFG.Category
strToCFGMCat = AbsCFG.Category . AbsCFG.SingleQuoteString . quoteSingle strToCFGMCat = AbsCFG.Category . AbsCFG.SingleQuoteString . quoteSingle
catToCFGMCat :: GT.CFCat -> AbsCFG.Category catToCFGMCat :: GT.CCat -> AbsCFG.Category
catToCFGMCat = strToCFGMCat . Prt.prt catToCFGMCat = strToCFGMCat . prt
symbolToGFCMSymbol :: Parser.Symbol GT.CFCat GT.Tokn -> AbsCFG.Symbol symbolToGFCMSymbol :: Symbol GT.CCat GT.Token -> AbsCFG.Symbol
symbolToGFCMSymbol (Parser.Cat c) = AbsCFG.CatS (catToCFGMCat c) symbolToGFCMSymbol (Cat c) = AbsCFG.CatS (catToCFGMCat c)
symbolToGFCMSymbol (Parser.Tok t) = AbsCFG.TermS (Prt.prt t) symbolToGFCMSymbol (Tok t) = AbsCFG.TermS (prt t)
quoteSingle :: String -> String quoteSingle :: String -> String
quoteSingle s = "'" ++ escapeSingle s ++ "'" quoteSingle s = "'" ++ escapeSingle s ++ "'"

View File

@@ -4,9 +4,9 @@
-- Stability : (stable) -- Stability : (stable)
-- Portability : (portable) -- Portability : (portable)
-- --
-- > CVS $Date: 2005/04/14 11:42:05 $ -- > CVS $Date: 2005/04/14 18:38:36 $
-- > CVS $Author: peb $ -- > CVS $Author: peb $
-- > CVS $Revision: 1.3 $ -- > CVS $Revision: 1.4 $
-- --
-- All conversions from GFC -- All conversions from GFC
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
@@ -25,6 +25,9 @@ import qualified GF.Conversion.RemoveSingletons as RemSing
import qualified GF.Conversion.SimpleToMCFG as S2M import qualified GF.Conversion.SimpleToMCFG as S2M
import qualified GF.Conversion.MCFGtoCFG as M2C import qualified GF.Conversion.MCFGtoCFG as M2C
----------------------------------------------------------------------
-- * single step conversions
gfc2simple :: (CanonGrammar, Ident) -> SGrammar gfc2simple :: (CanonGrammar, Ident) -> SGrammar
gfc2simple = G2S.convertGrammar gfc2simple = G2S.convertGrammar
@@ -43,4 +46,21 @@ simple2mcfg_strict = S2M.convertGrammarStrict
mcfg2cfg :: MGrammar -> CGrammar mcfg2cfg :: MGrammar -> CGrammar
mcfg2cfg = M2C.convertGrammar mcfg2cfg = M2C.convertGrammar
----------------------------------------------------------------------
-- * GFC -> MCFG
-- | default conversion:
--
-- - instantiating finite dependencies ('removeSingletons . simple2finite')
-- - nondeterministic MCFG conversion ('simple2mcfg_nondet')
gfc2mcfg :: (CanonGrammar, Ident) -> MGrammar
gfc2mcfg = simple2mcfg_nondet . removeSingletons . simple2finite . gfc2simple
----------------------------------------------------------------------
-- * GFC -> CFG
-- | default conversion = default mcfg conversion + trivial cfg conversion
gfc2cfg :: (CanonGrammar, Ident) -> CGrammar
gfc2cfg = mcfg2cfg . gfc2mcfg

View File

@@ -0,0 +1,82 @@
----------------------------------------------------------------------
-- |
-- Maintainer : PL
-- Stability : (stable)
-- Portability : (portable)
--
-- > CVS $Date: 2005/04/14 18:41:21 $
-- > CVS $Author: peb $
-- > CVS $Revision: 1.1 $
--
-- Instantiating all types which only have one single element.
--
-- Should be merged into 'GF.Conversion.FiniteToSimple'
-----------------------------------------------------------------------------
module GF.Conversion.RemoveSingletons where
import GF.System.Tracing
import GF.Infra.Print
import GF.Formalism.Utilities
import GF.Formalism.GCFG
import GF.Formalism.SimpleGFC
import GF.Conversion.Types
import GF.Data.SortedList
import GF.Data.Assoc
import List (mapAccumL)
convertGrammar :: SGrammar -> SGrammar
convertGrammar grammar = if singles == emptyAssoc then grammar
else tracePrt "#singleton-removed rules" (prt . length) $
map (convertRule singles) grammar
where singles = calcSingletons grammar
convertRule :: Assoc SCat (SyntaxForest Fun, Maybe STerm) -> SRule -> SRule
convertRule singles rule@(Rule (Abs _ decls _) _)
= if all (Nothing ==) singleArgs then rule
else instantiateSingles singleArgs rule
where singleArgs = map (lookupAssoc singles . decl2cat) decls
instantiateSingles :: [Maybe (SyntaxForest Fun, Maybe STerm)] -> SRule -> SRule
instantiateSingles singleArgs (Rule (Abs decl decls (Name fun profile)) (Cnc lcat lcats lterm))
= Rule (Abs decl decls' (Name fun profile')) (Cnc lcat lcats' lterm')
where (decls', lcats') = unzip [ (d, l) | (Nothing, d, l) <- zip3 singleArgs decls lcats ]
profile' = map (fmap fst) exProfile `composeProfiles` profile
newArgs = map (fmap snd) exProfile
lterm' = fmap (instantiateLin newArgs) lterm
exProfile = snd $ mapAccumL mkProfile 0 singleArgs
mkProfile nr (Just trm) = (nr, Constant trm)
mkProfile nr (Nothing) = (nr+1, Unify [nr])
instantiateLin :: [Profile (Maybe STerm)] -> STerm -> STerm
instantiateLin newArgs = inst
where inst (Arg nr cat path)
= case newArgs !! nr of
Unify [nr'] -> Arg nr' cat path
Constant (Just term) -> termFollowPath path term
Constant Nothing -> error "instantiateLin: argument has no linearization"
inst (cn :^ terms) = cn :^ map inst terms
inst (Rec rec) = Rec [ (lbl, inst term) | (lbl, term) <- rec ]
inst (term :. lbl) = inst term +. lbl
inst (Tbl tbl) = Tbl [ (pat, inst term) | (pat, term) <- tbl ]
inst (term :! sel) = inst term +! inst sel
inst (Variants ts) = variants (map inst ts)
inst (t1 :++ t2) = inst t1 ?++ inst t2
inst term = term
----------------------------------------------------------------------
calcSingletons :: SGrammar -> Assoc SCat (SyntaxForest Fun, Maybe STerm)
calcSingletons rules = listAssoc singleCats
where singleCats = tracePrt "singleton cats" (prtSep " ") $
[ (cat, (constantNameToForest name, lin)) |
(cat, [([], name, lin)]) <- rulesByCat ]
rulesByCat = groupPairs $ nubsort
[ (decl2cat cat, (args, name, lin)) |
Rule (Abs cat args name) (Cnc _ _ lin) <- rules ]

65
src/GF/Parsing/CF.hs Normal file
View File

@@ -0,0 +1,65 @@
----------------------------------------------------------------------
-- |
-- Maintainer : PL
-- Stability : (stable)
-- Portability : (portable)
--
-- > CVS $Date: 2005/04/14 18:41:22 $
-- > CVS $Author: peb $
-- > CVS $Revision: 1.1 $
--
-- Chart parsing of grammars in CF format
-----------------------------------------------------------------------------
module GF.NewParsing.CF (parse) where
import GF.System.Tracing
import GF.Infra.Print
import GF.Data.SortedList (nubsort)
import GF.Data.Assoc
import qualified CF
import qualified CFIdent as CFI
import GF.Formalism.Utilities
import GF.Formalism.CFG
import qualified GF.NewParsing.CFG as P
type Token = CFI.CFTok
type Name = CFI.CFFun
type Category = CFI.CFCat
parse :: String -> CF.CF -> Category -> CF.CFParser
parse = buildParser . P.parseCF
buildParser :: P.CFParser Category Name Token -> CF.CF -> Category -> CF.CFParser
buildParser parser cf start tokens = trace "ParseCF" $
(parseResults, parseInformation)
where parseInformation = prtSep "\n" trees
parseResults = [ (tree2cfTree t, []) | t <- trees ]
theInput = input tokens
edges = tracePrt "#edges" (prt.length) $
parser pInf [start] theInput
chart = tracePrt "#chart" (prt . map (length.snd) . aAssocs) $
grammar2chart $ map addCategory edges
forests = tracePrt "#forests" (prt.length) $
chart2forests chart (const False)
[ uncurry Edge (inputBounds theInput) start ]
trees = tracePrt "#trees" (prt.length) $
concatMap forest2trees forests
pInf = P.buildCFPInfo $ cf2grammar cf (nubsort tokens)
addCategory (CFRule cat rhs name) = CFRule cat rhs (name, cat)
tree2cfTree (TNode (name, Edge _ _ cat) trees) = CF.CFTree (name, (cat, map tree2cfTree trees))
cf2grammar :: CF.CF -> [Token] -> CFGrammar Category Name Token
cf2grammar cf tokens = [ CFRule cat rhs name |
(name, (cat, rhs0)) <- cfRules,
rhs <- mapM item2symbol rhs0 ]
where cfRules = concatMap (CF.predefRules (CF.predefOfCF cf)) tokens ++
CF.rulesOfCF cf
item2symbol (CF.CFNonterm cat) = [Cat cat]
item2symbol item = map Tok $ filter (CF.matchCFTerm item) tokens

View File

@@ -4,9 +4,9 @@
-- Stability : (stable) -- Stability : (stable)
-- Portability : (portable) -- Portability : (portable)
-- --
-- > CVS $Date: 2005/04/11 13:52:51 $ -- > CVS $Date: 2005/04/14 18:38:36 $
-- > CVS $Author: peb $ -- > CVS $Author: peb $
-- > CVS $Revision: 1.1 $ -- > CVS $Revision: 1.2 $
-- --
-- CFG parsing -- CFG parsing
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
@@ -24,7 +24,7 @@ import qualified GF.NewParsing.CFG.General as Gen
---------------------------------------------------------------------- ----------------------------------------------------------------------
-- parsing -- parsing
--parseCF :: (Ord n, Ord c, Ord t) => String -> CFParser c n t parseCF :: (Ord n, Ord c, Ord t) => String -> CFParser c n t
parseCF "gb" = Gen.parse bottomup parseCF "gb" = Gen.parse bottomup
parseCF "gt" = Gen.parse topdown parseCF "gt" = Gen.parse topdown
parseCF "ib" = Inc.parse (bottomup, noFilter) parseCF "ib" = Inc.parse (bottomup, noFilter)

View File

@@ -5,9 +5,9 @@
-- Stability : (stable) -- Stability : (stable)
-- Portability : (portable) -- Portability : (portable)
-- --
-- > CVS $Date: 2005/04/11 13:53:38 $ -- > CVS $Date: 2005/04/14 18:38:36 $
-- > CVS $Author: peb $ -- > CVS $Author: peb $
-- > CVS $Revision: 1.15 $ -- > CVS $Revision: 1.16 $
-- --
-- This module prints a CFG as a Nuance GSL 2.0 grammar. -- This module prints a CFG as a Nuance GSL 2.0 grammar.
-- --
@@ -19,16 +19,20 @@ module PrGSL (gslPrinter) where
import SRG import SRG
import Ident import Ident
import GF.OldParsing.CFGrammar -- import GF.OldParsing.CFGrammar
import GF.OldParsing.Utilities (Symbol(..)) -- import GF.OldParsing.Utilities (Symbol(..))
import GF.OldParsing.GrammarTypes -- import GF.OldParsing.GrammarTypes
import GF.Printing.PrintParser -- import GF.Printing.PrintParser
import GF.Formalism.CFG
import GF.Formalism.Utilities (Symbol(..))
import GF.Conversion.Types
import GF.Infra.Print
import Option import Option
import Data.Char (toUpper,toLower) import Data.Char (toUpper,toLower)
gslPrinter :: Ident -- ^ Grammar name gslPrinter :: Ident -- ^ Grammar name
-> Options -> CFGrammar -> String -> Options -> CGrammar -> String
gslPrinter name opts cfg = prGSL srg "" gslPrinter name opts cfg = prGSL srg ""
where srg = makeSRG name opts cfg where srg = makeSRG name opts cfg
@@ -55,13 +59,13 @@ firstToUpper :: String -> String
firstToUpper [] = [] firstToUpper [] = []
firstToUpper (x:xs) = toUpper x : xs firstToUpper (x:xs) = toUpper x : xs
rmPunct :: [Symbol String Tokn] -> [Symbol String Tokn] rmPunct :: [Symbol String Token] -> [Symbol String Token]
rmPunct [] = [] rmPunct [] = []
rmPunct (Tok t:ss) | all isPunct (prt t) = rmPunct ss rmPunct (Tok t:ss) | all isPunct (prt t) = rmPunct ss
rmPunct (s:ss) = s : rmPunct ss rmPunct (s:ss) = s : rmPunct ss
-- Nuance does not like upper case characters in tokens -- Nuance does not like upper case characters in tokens
showToken :: Tokn -> String showToken :: Token -> String
showToken t = map toLower (prt t) showToken t = map toLower (prt t)
isPunct :: Char -> Bool isPunct :: Char -> Bool

View File

@@ -5,9 +5,9 @@
-- Stability : (stable) -- Stability : (stable)
-- Portability : (portable) -- Portability : (portable)
-- --
-- > CVS $Date: 2005/04/11 13:53:39 $ -- > CVS $Date: 2005/04/14 18:38:36 $
-- > CVS $Author: peb $ -- > CVS $Author: peb $
-- > CVS $Revision: 1.9 $ -- > CVS $Revision: 1.10 $
-- --
-- This module prints a CFG as a JSGF grammar. -- This module prints a CFG as a JSGF grammar.
-- --
@@ -21,14 +21,18 @@ module PrJSGF (jsgfPrinter) where
import SRG import SRG
import Ident import Ident
import GF.OldParsing.CFGrammar -- import GF.OldParsing.CFGrammar
import GF.OldParsing.Utilities (Symbol(..)) -- import GF.OldParsing.Utilities (Symbol(..))
import GF.OldParsing.GrammarTypes -- import GF.OldParsing.GrammarTypes
import GF.Printing.PrintParser -- import GF.Printing.PrintParser
import GF.Formalism.CFG
import GF.Formalism.Utilities (Symbol(..))
import GF.Conversion.Types
import GF.Infra.Print
import Option import Option
jsgfPrinter :: Ident -- ^ Grammar name jsgfPrinter :: Ident -- ^ Grammar name
-> Options -> CFGrammar -> String -> Options -> CGrammar -> String
jsgfPrinter name opts cfg = prJSGF srg "" jsgfPrinter name opts cfg = prJSGF srg ""
where srg = makeSRG name opts cfg where srg = makeSRG name opts cfg
@@ -53,7 +57,7 @@ prJSGF (SRG{grammarName=name,startCat=start,origStartCat=origStart,rules=rs})
prSymbol (Tok t) = wrap "\"" (prtS t) "\"" prSymbol (Tok t) = wrap "\"" (prtS t) "\""
prCat c = showChar '<' . showString c . showChar '>' prCat c = showChar '<' . showString c . showChar '>'
rmPunct :: [Symbol String Tokn] -> [Symbol String Tokn] rmPunct :: [Symbol String Token] -> [Symbol String Token]
rmPunct [] = [] rmPunct [] = []
rmPunct (Tok t:ss) | all isPunct (prt t) = rmPunct ss rmPunct (Tok t:ss) | all isPunct (prt t) = rmPunct ss
rmPunct (s:ss) = s : rmPunct ss rmPunct (s:ss) = s : rmPunct ss

View File

@@ -5,9 +5,9 @@
-- Stability : (stable) -- Stability : (stable)
-- Portability : (portable) -- Portability : (portable)
-- --
-- > CVS $Date: 2005/04/11 13:53:39 $ -- > CVS $Date: 2005/04/14 18:38:36 $
-- > CVS $Author: peb $ -- > CVS $Author: peb $
-- > CVS $Revision: 1.11 $ -- > CVS $Revision: 1.12 $
-- --
-- Representation of, conversion to, and utilities for -- Representation of, conversion to, and utilities for
-- printing of a general Speech Recognition Grammar. -- printing of a general Speech Recognition Grammar.
@@ -21,10 +21,14 @@
module SRG where module SRG where
import Ident import Ident
import GF.OldParsing.CFGrammar -- import GF.OldParsing.CFGrammar
import GF.OldParsing.Utilities (Symbol(..)) -- import GF.OldParsing.Utilities (Symbol(..))
import GF.OldParsing.GrammarTypes -- import GF.OldParsing.GrammarTypes
import GF.Printing.PrintParser -- import GF.Printing.PrintParser
import GF.Formalism.CFG
import GF.Formalism.Utilities (Symbol(..))
import GF.Conversion.Types
import GF.Infra.Print
import TransformCFG import TransformCFG
import Option import Option
@@ -40,7 +44,7 @@ data SRG = SRG { grammarName :: String -- ^ grammar name
} }
data SRGRule = SRGRule String String [SRGAlt] -- ^ SRG category name, original category name data SRGRule = SRGRule String String [SRGAlt] -- ^ SRG category name, original category name
-- and productions -- and productions
type SRGAlt = [Symbol String Tokn] type SRGAlt = [Symbol String Token]
-- | SRG category name and original name -- | SRG category name and original name
type CatName = (String,String) type CatName = (String,String)
@@ -49,7 +53,7 @@ type CatNames = FiniteMap String String
makeSRG :: Ident -- ^ Grammar name makeSRG :: Ident -- ^ Grammar name
-> Options -- ^ Grammar options -> Options -- ^ Grammar options
-> CFGrammar -- ^ A context-free grammar -> CGrammar -- ^ A context-free grammar
-> SRG -> SRG
makeSRG i opts gr = SRG { grammarName = name, makeSRG i opts gr = SRG { grammarName = name,
startCat = start, startCat = start,
@@ -71,11 +75,11 @@ cfgRulesToSRGRule names rs@(r:_) = SRGRule cat origCat rhs
renameCat (Cat c) = Cat (lookupFM_ names c) renameCat (Cat c) = Cat (lookupFM_ names c)
renameCat t = t renameCat t = t
ruleCat :: Rule n c t -> c ruleCat :: CFRule c n t -> c
ruleCat (Rule c _ _) = c ruleCat (CFRule c _ _) = c
ruleRhs :: Rule n c t -> [Symbol c t] ruleRhs :: CFRule c n t -> [Symbol c t]
ruleRhs (Rule _ r _) = r ruleRhs (CFRule _ r _) = r
mkCatNames :: String -- ^ Category name prefix mkCatNames :: String -- ^ Category name prefix
-> [String] -- ^ Original category names -> [String] -- ^ Original category names

View File

@@ -5,22 +5,28 @@
-- Stability : (stable) -- Stability : (stable)
-- Portability : (portable) -- Portability : (portable)
-- --
-- > CVS $Date: 2005/04/11 13:53:39 $ -- > CVS $Date: 2005/04/14 18:38:36 $
-- > CVS $Author: peb $ -- > CVS $Author: peb $
-- > CVS $Revision: 1.9 $ -- > CVS $Revision: 1.10 $
-- --
-- This module does some useful transformations on CFGs. -- This module does some useful transformations on CFGs.
-- --
-- FIXME: remove cycles -- FIXME: remove cycles
--
-- peb thinks: most of this module should be moved to GF.Conversion...
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
module TransformCFG (makeNice, CFRule_) where module TransformCFG (makeNice, CFRule_) where
import Ident import Ident
import GF.OldParsing.CFGrammar -- import GF.OldParsing.CFGrammar
import GF.OldParsing.Utilities (Symbol(..)) -- import GF.OldParsing.Utilities (Symbol(..))
import GF.OldParsing.GrammarTypes -- import GF.OldParsing.GrammarTypes
import GF.Printing.PrintParser -- import GF.Printing.PrintParser
import GF.Formalism.CFG
import GF.Formalism.Utilities (Symbol(..), mapSymbol)
import GF.Conversion.Types
import GF.Infra.Print
import Data.FiniteMap import Data.FiniteMap
import Data.List import Data.List
@@ -30,63 +36,65 @@ import Debug.Trace
-- | not very nice to get replace the structured CFCat type with a simple string -- | not very nice to get replace the structured CFCat type with a simple string
type CFRule_ = Rule CFName String Tokn type CFRule_ = CFRule Cat_ Name Token
type Cat_ = String
type CFRules = FiniteMap String [CFRule_] type CFRules = FiniteMap Cat_ [CFRule_]
makeNice :: CFGrammar -> [CFRule_] makeNice :: CGrammar -> [CFRule_]
makeNice = concat . eltsFM . makeNice' . groupProds . cfgToCFRules makeNice = concat . eltsFM . makeNice' . groupProds . cfgToCFRules
where makeNice' = removeLeftRecursion . removeEmptyCats where makeNice' = removeLeftRecursion . removeEmptyCats
cfgToCFRules :: CFGrammar -> [CFRule_] cfgToCFRules :: CGrammar -> [CFRule_]
cfgToCFRules cfg = [Rule (catToString c) (map symb r) n | Rule c r n <- cfg] cfgToCFRules cfg = [CFRule (catToString c) (map symb r) n | CFRule c r n <- cfg]
where symb (Cat c) = Cat (catToString c) where symb = mapSymbol catToString id
symb (Tok t) = Tok t -- symb (Cat c) = Cat (catToString c)
-- symb (Tok t) = Tok t
catToString = prt catToString = prt
-- | Group productions by their lhs categories -- | Group productions by their lhs categories
groupProds :: [CFRule_] -> CFRules groupProds :: [CFRule_] -> CFRules
groupProds = addListToFM_C (++) emptyFM . map (\rs -> (ruleCat rs,[rs])) groupProds = addListToFM_C (++) emptyFM . map (\rs -> (ruleCat rs,[rs]))
where ruleCat (Rule c _ _) = c where ruleCat (CFRule c _ _) = c
-- | Remove productions which use categories which have no productions -- | Remove productions which use categories which have no productions
removeEmptyCats :: CFRules -> CFRules removeEmptyCats :: CFRules -> CFRules
removeEmptyCats rss = listToFM $ fix removeEmptyCats' $ fmToList rss removeEmptyCats rss = listToFM $ fix removeEmptyCats' $ fmToList rss
where where
removeEmptyCats' :: [(String,[CFRule_])] -> [(String,[CFRule_])] removeEmptyCats' :: [(Cat_,[CFRule_])] -> [(Cat_,[CFRule_])]
removeEmptyCats' rs = k' removeEmptyCats' rs = k'
where where
keep = filter (not . null . snd) rs keep = filter (not . null . snd) rs
allCats = nub [c | (_,r) <- rs, Rule _ rhs _ <- r, Cat c <- rhs] allCats = nub [c | (_,r) <- rs, CFRule _ rhs _ <- r, Cat c <- rhs]
emptyCats = filter (nothingOrNull . flip lookup rs) allCats emptyCats = filter (nothingOrNull . flip lookup rs) allCats
k' = map (\ (c,xs) -> (c, filter (not . anyUsedBy emptyCats) xs)) keep k' = map (\ (c,xs) -> (c, filter (not . anyUsedBy emptyCats) xs)) keep
anyUsedBy :: [String] -> CFRule_ -> Bool anyUsedBy :: [Cat_] -> CFRule_ -> Bool
anyUsedBy ss (Rule _ r _) = or [c `elem` ss | Cat c <- r] anyUsedBy ss (CFRule _ r _) = or [c `elem` ss | Cat c <- r]
removeLeftRecursion :: CFRules -> CFRules removeLeftRecursion :: CFRules -> CFRules
removeLeftRecursion rs = listToFM $ concatMap removeDirectLeftRecursion $ map handleProds $ fmToList rs removeLeftRecursion rs = listToFM $ concatMap removeDirectLeftRecursion $ map handleProds $ fmToList rs
where where
handleProds (c, r) = (c, concatMap handleProd r) handleProds (c, r) = (c, concatMap handleProd r)
handleProd (Rule ai (Cat aj:alpha) n) | aj < ai = handleProd (CFRule ai (Cat aj:alpha) n) | aj < ai =
-- FIXME: this will give multiple rules with the same name -- FIXME: this will give multiple rules with the same name
[Rule ai (beta ++ alpha) n | Rule _ beta _ <- fromJust (lookupFM rs aj)] [CFRule ai (beta ++ alpha) n | CFRule _ beta _ <- fromJust (lookupFM rs aj)]
handleProd r = [r] handleProd r = [r]
removeDirectLeftRecursion :: (String,[CFRule_]) -- ^ All productions for a category removeDirectLeftRecursion :: (Cat_,[CFRule_]) -- ^ All productions for a category
-> [(String,[CFRule_])] -> [(Cat_,[CFRule_])]
removeDirectLeftRecursion (a,rs) | null dr = [(a,rs)] removeDirectLeftRecursion (a,rs) | null dr = [(a,rs)]
| otherwise = [(a, as), (a', a's)] | otherwise = [(a, as), (a', a's)]
where where
a' = a ++ "'" -- FIXME: this might not be unique a' = a ++ "'" -- FIXME: this might not be unique
(dr,nr) = partition isDirectLeftRecursive rs (dr,nr) = partition isDirectLeftRecursive rs
as = maybeEndWithA' nr as = maybeEndWithA' nr
is = [Rule a' (tail r) n | Rule _ r n <- dr] is = [CFRule a' (tail r) n | CFRule _ r n <- dr]
a's = maybeEndWithA' is a's = maybeEndWithA' is
maybeEndWithA' xs = xs ++ [Rule c (r++[Cat a']) n | Rule c r n <- xs] maybeEndWithA' xs = xs ++ [CFRule c (r++[Cat a']) n | CFRule c r n <- xs]
isDirectLeftRecursive :: CFRule_ -> Bool isDirectLeftRecursive :: CFRule_ -> Bool
isDirectLeftRecursive (Rule c (Cat c':_) _) = c == c' isDirectLeftRecursive (CFRule c (Cat c':_) _) = c == c'
isDirectLeftRecursive _ = False isDirectLeftRecursive _ = False

View File

@@ -5,9 +5,9 @@
-- Stability : (stable) -- Stability : (stable)
-- Portability : (portable) -- Portability : (portable)
-- --
-- > CVS $Date: 2005/04/14 11:42:06 $ -- > CVS $Date: 2005/04/14 18:38:36 $
-- > CVS $Author: peb $ -- > CVS $Author: peb $
-- > CVS $Revision: 1.53 $ -- > CVS $Revision: 1.54 $
-- --
-- A database for customizable GF shell commands. -- A database for customizable GF shell commands.
-- --
@@ -66,14 +66,15 @@ import GrammarToHaskell
-- the cf parsing algorithms -- the cf parsing algorithms
import ChartParser -- or some other CF Parser import ChartParser -- or some other CF Parser
import qualified GF.OldParsing.ParseCF as PCFOld import qualified GF.NewParsing.CF as PCF
import qualified GF.OldParsing.ParseCF as PCFOld -- OBSOLETE
--import qualified ParseGFCviaCFG as PGFC --import qualified ParseGFCviaCFG as PGFC
--import NewChartParser --import NewChartParser
--import NewerChartParser --import NewerChartParser
-- grammar conversions -- peb 19/4-04 -- grammar conversions -- peb 19/4-04
-- see also customGrammarPrinter -- see also customGrammarPrinter
import qualified GF.OldParsing.ConvertGrammar as CnvOld import qualified GF.OldParsing.ConvertGrammar as CnvOld -- OBSOLETE
import qualified GF.Printing.PrintParser as Prt import qualified GF.Printing.PrintParser as Prt
--import qualified GF.Data.Assoc as Assoc --import qualified GF.Data.Assoc as Assoc
--import qualified GF.OldParsing.ConvertFiniteGFC as Fin --import qualified GF.OldParsing.ConvertFiniteGFC as Fin
@@ -238,10 +239,10 @@ customGrammarPrinter =
,(strCI "srg", prSRG . stateCF) ,(strCI "srg", prSRG . stateCF)
,(strCI "gsl", \s -> let opts = stateOptions s ,(strCI "gsl", \s -> let opts = stateOptions s
name = cncId s name = cncId s
in gslPrinter name opts $ CnvOld.cfg $ statePInfoOld s) in gslPrinter name opts $ stateCFG s)
,(strCI "jsgf", \s -> let opts = stateOptions s ,(strCI "jsgf", \s -> let opts = stateOptions s
name = cncId s name = cncId s
in jsgfPrinter name opts $ CnvOld.cfg $ statePInfoOld s) in jsgfPrinter name opts $ stateCFG s)
,(strCI "plbnf", prLBNF True) ,(strCI "plbnf", prLBNF True)
,(strCI "lbnf", prLBNF False) ,(strCI "lbnf", prLBNF False)
,(strCI "bnf", prBNF False) ,(strCI "bnf", prBNF False)
@@ -266,7 +267,6 @@ customGrammarPrinter =
,(strCI "finite", Prt2.prt . Cnv.simple2finite . Cnv.gfc2simple . stateGrammarLang) ,(strCI "finite", Prt2.prt . Cnv.simple2finite . Cnv.gfc2simple . stateGrammarLang)
,(strCI "single", Prt2.prt . Cnv.removeSingletons . Cnv.simple2finite . Cnv.gfc2simple . stateGrammarLang) ,(strCI "single", Prt2.prt . Cnv.removeSingletons . Cnv.simple2finite . Cnv.gfc2simple . stateGrammarLang)
,(strCI "sg-sg", Prt2.prt . Cnv.removeSingletons . Cnv.removeSingletons . Cnv.simple2finite . Cnv.gfc2simple . stateGrammarLang) ,(strCI "sg-sg", Prt2.prt . Cnv.removeSingletons . Cnv.removeSingletons . Cnv.simple2finite . Cnv.gfc2simple . stateGrammarLang)
,(strCI "sg-sg-sg", Prt2.prt . Cnv.removeSingletons . Cnv.removeSingletons . Cnv.removeSingletons . Cnv.simple2finite . Cnv.gfc2simple . stateGrammarLang)
,(strCI "mcfg-old", Prt.prt . CnvOld.mcfg . statePInfoOld) ,(strCI "mcfg-old", Prt.prt . CnvOld.mcfg . statePInfoOld)
,(strCI "cfg-old", Prt.prt . CnvOld.cfg . statePInfoOld) ,(strCI "cfg-old", Prt.prt . CnvOld.cfg . statePInfoOld)
] ]
@@ -354,14 +354,20 @@ customStringCommand =
customParser = customParser =
customData "Parsers, selected by option -parser=x" $ customData "Parsers, selected by option -parser=x" $
[ [
(strCI "chart", PCFOld.parse "ibn" . stateCF) (strCI "chart", PCFOld.parse "ibn" . stateCF) -- DEPRECATED
,(strCI "old", chartParser . stateCF) ,(strCI "general", PCF.parse "gb" . stateCF)
,(strCI "general-bottomup", PCF.parse "gt" . stateCF)
,(strCI "general-topdown", PCF.parse "gt" . stateCF)
,(strCI "incremental", PCF.parse "ib" . stateCF)
,(strCI "incremental-bottomup", PCF.parse "ib" . stateCF)
,(strCI "incremental-topdown", PCF.parse "it" . stateCF)
,(strCI "old", chartParser . stateCF) -- DEPRECATED
,(strCI "myparser", myParser) ,(strCI "myparser", myParser)
-- add your own parsers here -- add your own parsers here
] ]
-- 31/5-04, peb: -- 31/5-04, peb: (DEPRECATED)
++ [ (strCI ("chart"++name), PCFOld.parse descr . stateCF) | -- ++ [ (strCI ("chart"++name), PCFOld.parse descr . stateCF) |
(descr, names) <- PCFOld.alternatives, name <- names ] -- (descr, names) <- PCFOld.alternatives, name <- names ]
customTokenizer = customTokenizer =
customData "Tokenizers, selected by option -lexer=x" $ customData "Tokenizers, selected by option -lexer=x" $

View File

@@ -5,9 +5,9 @@
-- Stability : (stable) -- Stability : (stable)
-- Portability : (portable) -- Portability : (portable)
-- --
-- > CVS $Date: 2005/04/14 11:42:06 $ -- > CVS $Date: 2005/04/14 18:38:36 $
-- > CVS $Author: peb $ -- > CVS $Author: peb $
-- > CVS $Revision: 1.17 $ -- > CVS $Revision: 1.18 $
-- --
-- (Description of the module) -- (Description of the module)
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
@@ -35,7 +35,7 @@ import Custom
import ShellState import ShellState
import PPrCF (prCFTree) import PPrCF (prCFTree)
import qualified GF.OldParsing.ParseGFC as NewOld import qualified GF.OldParsing.ParseGFC as NewOld -- OBSOLETE
import qualified GF.NewParsing.GFC as New import qualified GF.NewParsing.GFC as New
import Operations import Operations