{-# LANGUAGE StandaloneDeriving #-} module GLL.Types.BSR where import qualified Data.Array as A import qualified Data.Map as M import qualified Data.IntMap as IM import qualified Data.Set as S import qualified Data.IntSet as IS import Data.List (elemIndices, findIndices) import GLL.Types.Grammar type Input t = A.Array Int t -- make sure that tokens are equal independent of their character level value type SlotL t = (Slot t, Int) -- slot with left extent type PrL t = (Prod t, Int) -- Production rule with left extent type NtL = (Nt, Int) -- Nonterminal with left extent -- | -- Stores packed nodes using nested "Data.IntMap"s, nesting is as follows: -- -- * left extent -- * right extent -- * dot position (from left to right) -- * mapping from productions to set of pivots type BSRs t = IM.IntMap (IM.IntMap (IM.IntMap (M.Map (Prod t) IS.IntSet))) type BSR t = (Slot t, Int, Int, Int) emptyBSRs :: (Ord t) => BSRs t emptyBSRs = IM.empty pNodeLookup :: (Ord t) => BSRs t -> (Slot t, Int, Int) -> Maybe [Int] pNodeLookup bsrs (Slot x alpha beta,l,r)= pNodeLookup' bsrs ((Prod x (alpha++beta),length alpha),l,r) pNodeLookup' :: (Ord t) => BSRs t -> ((Prod t, Int), Int, Int) -> Maybe [Int] pNodeLookup' pMap ((alt,j),l,r) = maybe Nothing inner $ IM.lookup l pMap where inner = maybe Nothing inner2 . IM.lookup r inner2 = maybe Nothing inner3 . IM.lookup j inner3 = maybe Nothing (Just . IS.toList) . M.lookup alt addBSR = pMapInsert addBSR, pMapInsert :: (Ord t) => BSR t -> BSRs t -> BSRs t pMapInsert f@((Slot x alpha beta), l, k, r) pMap = add (Prod x (alpha++beta)) (length alpha) l r k where add alt j l r k = IM.alter addInnerL l pMap where addInnerL mm = case mm of Nothing -> Just singleRJAK Just m -> Just $ IM.alter addInnerR r m addInnerR mm = case mm of Nothing -> Just singleJAK Just m -> Just $ IM.alter addInnerJ j m addInnerJ mm = case mm of Nothing -> Just singleAK Just m -> Just $ M.insertWith IS.union alt singleK m singleRJAK= IM.fromList [(r, singleJAK)] singleJAK = IM.fromList [(j, singleAK)] singleAK = M.fromList [(alt, singleK)] singleK = IS.singleton k showBSRs pMap = unlines [ show ((a,j),l,r) ++ " --> " ++ show kset | (l,r2j) <- IM.assocs pMap, (r,j2a) <- IM.assocs r2j , (j,a2k) <- IM.assocs j2a, (a,kset) <- M.assocs a2k ] mkInput :: (Parseable t) => [t] -> Input t mkInput input = A.listArray (0,m) (input++[eos]) where m = length input