---------------------------------------------------------------------- -- | -- Maintainer : PL -- Stability : (stable) -- Portability : (portable) -- -- > CVS $Date: 2005/08/08 09:01:25 $ -- > CVS $Author: peb $ -- > CVS $Revision: 1.5 $ -- -- MCFG parsing, the naive algorithm ----------------------------------------------------------------------------- module GF.Parsing.MCFG.Naive (parse, parseR) where import Control.Monad (guard) -- GF modules import GF.Data.GeneralDeduction import GF.Formalism.GCFG import GF.Formalism.MCFG import GF.Formalism.Utilities import GF.Parsing.MCFG.Range import GF.Parsing.MCFG.PInfo import GF.Data.SortedList import GF.Data.Assoc import GF.System.Tracing import GF.Infra.Print ---------------------------------------------------------------------- -- * parsing -- | Builds a chart from the initial agenda, given by prediction, and the inference rules parse :: (Ord t, Ord n, Ord c, Ord l) => MCFParser c n l t parse pinfo starts toks = accumAssoc groupSyntaxNodes $ [ ((cat, makeRangeRec lins), SNode fun (zip rhs rrecs)) | Active (Abs cat _Nil fun, rhs) lins rrecs <- chartLookup chart Final ] where chart = process pinfo toks -- | Builds a chart from the initial agenda, given by prediction, and the inference rules -- parseR :: (Ord t, Ord n, Ord c, Ord l) => MCFParser c n l t parseR pinfo starts = accumAssoc groupSyntaxNodes $ [ ((cat, makeRangeRec lins), SNode fun (zip rhs rrecs)) | Active (Abs cat _Nil fun, rhs) lins rrecs <- chartLookup chart Final ] where chart = processR pinfo process :: (Ord t, Ord n, Ord c, Ord l) => MCFPInfo c n l t -> Input t -> NChart c n l process pinfo toks = tracePrt "MCFG.Naive - chart size" prtSizes $ buildChart keyof [convert, combine] (predict pinfo toks) processR :: (Ord n, Ord c, Ord l) => MCFPInfo c n l Range -> NChart c n l processR pinfo = tracePrt "MCFG.Naive Range - chart size" prtSizes $ buildChart keyof [convert, combine] (predictR pinfo) ---------------------------------------------------------------------- -- * inference rules -- Creates an Active Item of every Rule in the Grammar to give the initial Agenda predict :: (Ord l, Ord t) => MCFPInfo c n l t -> Input t -> [Item c n l] predict pinfo toks = tracePrt "MCFG.Naive - predicted rules" (prt . length) $ do Rule abs (Cnc _ _ lins) <- rulesMatchingInput pinfo toks lins' <- rangeRestRec toks lins return $ Active (abs, []) lins' [] -- Creates an Active Item of every Rule in the Grammar to give the initial Agenda predictR :: (Ord l) => MCFPInfo c n l Range -> [Item c n l] predictR pinfo = tracePrt "MCFG.Naive Range - predicted rules" (prt . length) $ do Rule abs (Cnc _ _ lins) <- allRules pinfo return $ Active (abs, []) lins [] -- | Creates an Active Item every time it is possible to combine -- an Active Item from the agenda with a Passive Item from the Chart combine :: (Ord n, Ord c, Ord l) => NChart c n l -> Item c n l -> [Item c n l] combine chart item@(Active (Abs _ (c:_) _, _) _ _) = do Passive _c rrec <- chartLookup chart (Pass c) combine2 chart rrec item combine chart (Passive c rrec) = do item <- chartLookup chart (Act c) combine2 chart rrec item combine _ _ = [] combine2 chart rrec (Active (Abs nt (c:find) f, found) lins rrecs) = do lins' <- substArgRec (length found) rrec lins return $ Active (Abs nt find f, found ++ [c]) lins' (rrecs ++ [rrec]) -- | Active Items with nothing to find are converted to Passive Items convert :: (Ord n, Ord c, Ord l) => NChart c n l -> Item c n l -> [Item c n l] convert _ (Active (Abs cat [] fun, _) lins _) = [Passive cat (makeRangeRec lins)] convert _ _ = [] ---------------------------------------------------------------------- -- * type definitions type NChart c n l = ParseChart (Item c n l) (NKey c) data Item c n l = Active (DottedRule c n) (LinRec c l Range) [RangeRec l] | Passive c (RangeRec l) deriving (Eq, Ord, Show) type DottedRule c n = (Abstract c n, [c]) data NKey c = Act c | Pass c | Final deriving (Eq, Ord, Show) keyof :: Item c n l -> NKey c keyof (Active (Abs _ (next:_) _, _) _ _) = Act next keyof (Passive cat _) = Pass cat keyof _ = Final -- for tracing purposes prtSizes chart = "final=" ++ show (length (chartLookup chart Final)) ++ ", passive=" ++ show (sum [length (chartLookup chart k) | k@(Pass _) <- chartKeys chart ]) ++ ", active=" ++ show (sum [length (chartLookup chart k) | k@(Act _) <- chartKeys chart ]) prtChart chart = concat [ "\n*** KEY: " ++ prt k ++ prtBefore "\n " (chartLookup chart k) | k <- chartKeys chart ] instance (Print c, Print n, Print l) => Print (Item c n l) where prt (Active (abs, cs) lrec rrecs) = "? " ++ prt abs ++ " . " ++ prtSep " " cs ++ ";\n\t" ++ "{" ++ prtSep " " lrec ++ "}" ++ ( if null rrecs then ";" else ";\n\t" ++ "{" ++ prtSep "} {" (map (prtSep " ") rrecs) ++ "}" ) prt (Passive c rrec) = "- " ++ prt c ++ "; {" ++ prtSep " " rrec ++ "}" instance Print c => Print (NKey c) where prt (Act c) = "Active " ++ prt c prt (Pass c) = "Passive " ++ prt c prt (Final) = "Final"