"Committed_by_peb"

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

View File

@@ -5,9 +5,9 @@
-- Stability : (stable)
-- Portability : (portable)
--
-- > CVS $Date: 2005/04/11 13:53:38 $
-- > CVS $Date: 2005/04/14 18:38:36 $
-- > CVS $Author: peb $
-- > CVS $Revision: 1.13 $
-- > CVS $Revision: 1.14 $
--
-- Handles printing a CFGrammar in CFGM format.
-----------------------------------------------------------------------------
@@ -19,12 +19,20 @@ import qualified PrintCFG
import Ident
import GFC
import Modules
import qualified GF.OldParsing.ConvertGrammar as Cnv
import qualified GF.Printing.PrintParser as Prt
import qualified GF.OldParsing.CFGrammar as CFGrammar
import qualified GF.OldParsing.GrammarTypes as GT
-- import qualified GF.OldParsing.ConvertGrammar as Cnv
-- import qualified GF.Printing.PrintParser as Prt
-- 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 GF.OldParsing.Utilities as Parser
import GF.Formalism.Utilities (Symbol(..))
import ErrM
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'
-- instead of 'Cnv.pInfo' (which recalculates the grammar every time)
prLangAsCFGM :: CanonGrammar -> Ident -> Maybe String -> String
prLangAsCFGM gr i start = prCFGrammarAsCFGM (Cnv.cfg (Cnv.pInfo opts gr i)) i start
where opts = Option.Opts [Option.gfcConversion "nondet"]
prLangAsCFGM gr i start = prCFGrammarAsCFGM (Cnv.gfc2cfg (gr, i)) i start
-- 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
@@ -57,21 +66,21 @@ prCFGrammarAsCFGM gr i@(IC lang) start = (header . startcat . rules . footer) ""
where
header = showString "grammar " . showString lang . showString "\n"
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
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
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)
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:
ruleToCFGMRule (CFGrammar.Rule c rhs (GT.CFName fun profile))
ruleToCFGMRule (CFRule c rhs (GT.Name fun profile))
= AbsCFG.Rule fun' p' c' rhs'
where
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'
where
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
c' = catToCFGMCat c
rhs' = map symbolToGFCMSymbol rhs
-}
profileToCFGMProfile :: GT.CFProfile -> AbsCFG.Profile
profileToCFGMProfile = AbsCFG.Profile . map (AbsCFG.Ints . map fromIntegral)
profileToCFGMProfile :: [GT.Profile a] -> AbsCFG.Profile
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 = AbsCFG.Ident . Prt.prt
identToCFGMIdent = AbsCFG.Ident . prt
identToFun :: Ident -> AbsCFG.Fun
identToFun IW = AbsCFG.Coerce
@@ -103,12 +115,12 @@ identToFun i = AbsCFG.Cons (identToCFGMIdent i)
strToCFGMCat :: String -> AbsCFG.Category
strToCFGMCat = AbsCFG.Category . AbsCFG.SingleQuoteString . quoteSingle
catToCFGMCat :: GT.CFCat -> AbsCFG.Category
catToCFGMCat = strToCFGMCat . Prt.prt
catToCFGMCat :: GT.CCat -> AbsCFG.Category
catToCFGMCat = strToCFGMCat . prt
symbolToGFCMSymbol :: Parser.Symbol GT.CFCat GT.Tokn -> AbsCFG.Symbol
symbolToGFCMSymbol (Parser.Cat c) = AbsCFG.CatS (catToCFGMCat c)
symbolToGFCMSymbol (Parser.Tok t) = AbsCFG.TermS (Prt.prt t)
symbolToGFCMSymbol :: Symbol GT.CCat GT.Token -> AbsCFG.Symbol
symbolToGFCMSymbol (Cat c) = AbsCFG.CatS (catToCFGMCat c)
symbolToGFCMSymbol (Tok t) = AbsCFG.TermS (prt t)
quoteSingle :: String -> String
quoteSingle s = "'" ++ escapeSingle s ++ "'"

View File

@@ -4,9 +4,9 @@
-- Stability : (stable)
-- Portability : (portable)
--
-- > CVS $Date: 2005/04/14 11:42:05 $
-- > CVS $Date: 2005/04/14 18:38:36 $
-- > CVS $Author: peb $
-- > CVS $Revision: 1.3 $
-- > CVS $Revision: 1.4 $
--
-- 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.MCFGtoCFG as M2C
----------------------------------------------------------------------
-- * single step conversions
gfc2simple :: (CanonGrammar, Ident) -> SGrammar
gfc2simple = G2S.convertGrammar
@@ -43,4 +46,21 @@ simple2mcfg_strict = S2M.convertGrammarStrict
mcfg2cfg :: MGrammar -> CGrammar
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)
-- Portability : (portable)
--
-- > CVS $Date: 2005/04/11 13:52:51 $
-- > CVS $Date: 2005/04/14 18:38:36 $
-- > CVS $Author: peb $
-- > CVS $Revision: 1.1 $
-- > CVS $Revision: 1.2 $
--
-- CFG parsing
-----------------------------------------------------------------------------
@@ -24,7 +24,7 @@ import qualified GF.NewParsing.CFG.General as Gen
----------------------------------------------------------------------
-- 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 "gt" = Gen.parse topdown
parseCF "ib" = Inc.parse (bottomup, noFilter)

View File

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

View File

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

View File

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

View File

@@ -5,22 +5,28 @@
-- Stability : (stable)
-- Portability : (portable)
--
-- > CVS $Date: 2005/04/11 13:53:39 $
-- > CVS $Date: 2005/04/14 18:38:36 $
-- > CVS $Author: peb $
-- > CVS $Revision: 1.9 $
-- > CVS $Revision: 1.10 $
--
-- This module does some useful transformations on CFGs.
--
-- FIXME: remove cycles
--
-- peb thinks: most of this module should be moved to GF.Conversion...
-----------------------------------------------------------------------------
module TransformCFG (makeNice, CFRule_) where
import Ident
import GF.OldParsing.CFGrammar
import GF.OldParsing.Utilities (Symbol(..))
import GF.OldParsing.GrammarTypes
import GF.Printing.PrintParser
-- import GF.OldParsing.CFGrammar
-- import GF.OldParsing.Utilities (Symbol(..))
-- import GF.OldParsing.GrammarTypes
-- 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.List
@@ -30,63 +36,65 @@ import Debug.Trace
-- | 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
where makeNice' = removeLeftRecursion . removeEmptyCats
cfgToCFRules :: CFGrammar -> [CFRule_]
cfgToCFRules cfg = [Rule (catToString c) (map symb r) n | Rule c r n <- cfg]
where symb (Cat c) = Cat (catToString c)
symb (Tok t) = Tok t
cfgToCFRules :: CGrammar -> [CFRule_]
cfgToCFRules cfg = [CFRule (catToString c) (map symb r) n | CFRule c r n <- cfg]
where symb = mapSymbol catToString id
-- symb (Cat c) = Cat (catToString c)
-- symb (Tok t) = Tok t
catToString = prt
-- | Group productions by their lhs categories
groupProds :: [CFRule_] -> CFRules
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
removeEmptyCats :: CFRules -> CFRules
removeEmptyCats rss = listToFM $ fix removeEmptyCats' $ fmToList rss
where
removeEmptyCats' :: [(String,[CFRule_])] -> [(String,[CFRule_])]
removeEmptyCats' :: [(Cat_,[CFRule_])] -> [(Cat_,[CFRule_])]
removeEmptyCats' rs = k'
where
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
k' = map (\ (c,xs) -> (c, filter (not . anyUsedBy emptyCats) xs)) keep
anyUsedBy :: [String] -> CFRule_ -> Bool
anyUsedBy ss (Rule _ r _) = or [c `elem` ss | Cat c <- r]
anyUsedBy :: [Cat_] -> CFRule_ -> Bool
anyUsedBy ss (CFRule _ r _) = or [c `elem` ss | Cat c <- r]
removeLeftRecursion :: CFRules -> CFRules
removeLeftRecursion rs = listToFM $ concatMap removeDirectLeftRecursion $ map handleProds $ fmToList rs
where
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
[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]
removeDirectLeftRecursion :: (String,[CFRule_]) -- ^ All productions for a category
-> [(String,[CFRule_])]
removeDirectLeftRecursion :: (Cat_,[CFRule_]) -- ^ All productions for a category
-> [(Cat_,[CFRule_])]
removeDirectLeftRecursion (a,rs) | null dr = [(a,rs)]
| otherwise = [(a, as), (a', a's)]
where
a' = a ++ "'" -- FIXME: this might not be unique
(dr,nr) = partition isDirectLeftRecursive rs
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
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 (Rule c (Cat c':_) _) = c == c'
isDirectLeftRecursive (CFRule c (Cat c':_) _) = c == c'
isDirectLeftRecursive _ = False

View File

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

View File

@@ -5,9 +5,9 @@
-- Stability : (stable)
-- Portability : (portable)
--
-- > CVS $Date: 2005/04/14 11:42:06 $
-- > CVS $Date: 2005/04/14 18:38:36 $
-- > CVS $Author: peb $
-- > CVS $Revision: 1.17 $
-- > CVS $Revision: 1.18 $
--
-- (Description of the module)
-----------------------------------------------------------------------------
@@ -35,7 +35,7 @@ import Custom
import ShellState
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 Operations