summaryrefslogtreecommitdiff
path: root/src/GF/Parsing/CF.hs
blob: 3079a47ec0feca0bf54d1b4dc123d576a26b5a66 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
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