1
0
forked from GitHub/gf-core
Files
gf-core/src/GF/Parsing/CFG/General.hs
2005-04-11 12:57:45 +00:00

102 lines
3.5 KiB
Haskell

----------------------------------------------------------------------
-- |
-- Maintainer : PL
-- Stability : (stable)
-- Portability : (portable)
--
-- > CVS $Date: 2005/04/11 13:52:51 $
-- > CVS $Author: peb $
-- > CVS $Revision: 1.1 $
--
-- CFG parsing with a general chart
-----------------------------------------------------------------------------
module GF.NewParsing.CFG.General
(parse, Strategy) where
import GF.System.Tracing
import GF.Infra.Print
import GF.Formalism.Utilities
import GF.Formalism.CFG
import GF.NewParsing.CFG.PInfo
import GF.NewParsing.GeneralChart
import GF.Data.Assoc
import Monad
--parse :: (Ord n, Ord c, Ord t) => Strategy -> CFParser c n t
parse strategy grammar start = extract .
tracePrt "#internal chart" (prt . length . chartList) .
process strategy grammar start
type Strategy = (Bool, Bool) -- ^ (isBottomup, isTopdown)
extract :: (Ord n, Ord c, Ord t) =>
IChart n (Symbol c t) -> CFChart c n t
extract chart = [ CFRule (Edge j k cat) daughters name |
Edge j k (Cat cat, found, [], Just name) <- chartList chart,
daughters <- path j k (reverse found) ]
where path i k [] = [ [] | i==k ]
path i k (Tok tok : found)
= [ Tok tok : daughters |
daughters <- path (i+1) k found ]
path i k (Cat cat : found)
= [ Cat (Edge i j cat) : daughters |
Edge _i j _cat <- chartLookup chart (Passive (Cat cat) i),
daughters <- path j k found ]
process :: (Ord n, Ord c, Ord t) =>
Strategy -- ^ (isBottomup, isTopdown) :: (Bool, Bool)
-> CFPInfo c n t -- ^ parser information (= grammar)
-> [c] -- ^ list of starting categories
-> Input t -- ^ input string
-> IChart n (Symbol c t)
process (isBottomup, isTopdown) grammar start
= trace2 "CFParserGeneral" ((if isBottomup then " BU" else "") ++
(if isTopdown then " TD" else "")) $
buildChart keyof [predict, combine] . axioms
where axioms input = initial ++ scan input
scan input = map (fmap mkEdge) (inputEdges input)
mkEdge tok = (Tok tok, [], [], Nothing)
-- the combine rule
combine chart (Edge j k (next, _, [], _))
= [ edge `forwardTo` k | edge <- chartLookup chart (Active next j) ]
combine chart edge@(Edge _ j (_, _, next:_, _))
= [ edge `forwardTo` k | Edge _ k _ <- chartLookup chart (Passive next j) ]
-- initial predictions
initial = [ loopingEdge 0 rule | cat <- start, rule <- tdRuleLookup ? cat ]
-- predictions
predict chart (Edge j k (next, _, [], _)) | isBottomup
= [ loopingEdge j rule `forwardTo` k | rule <- bottomupRules grammar ? next ]
-- - - - - - - - - - ^^^^^^^^^^^^^ Kilbury prediction: move dot forward
predict chart (Edge _ k (_, _, Cat cat:_, _))
= [ loopingEdge k rule | rule <- tdRuleLookup ? cat ]
predict _ _ = []
tdRuleLookup | isTopdown = topdownRules grammar
| isBottomup = emptyLeftcornerRules grammar
-- internal representation of parse items
type Item n s = Edge (s, [s], [s], Maybe n)
type IChart n s = ParseChart (Item n s) (IKey s)
data IKey s = Active s Int
| Passive s Int
deriving (Eq, Ord, Show)
keyof (Edge _ j (_, _, next:_, _)) = Active next j
keyof (Edge j _ (cat, _, [], _)) = Passive cat j
forwardTo (Edge i j (cat, found, next:tofind, name)) k
= Edge i k (cat, next:found, tofind, name)
loopingEdge k (CFRule cat tofind name) = Edge k k (Cat cat, [], tofind, Just name)