{-# LANGUAGE MagicHash, UnboxedTuples #-} module UU.Parsing.MachineInterface where import GHC.Prim -- | The 'InputState' class contains the interface that the AnaParser -- parsers expect for the input. A minimal complete instance definition -- consists of 'splitStateE', 'splitState' and 'getPosition'. class InputState state s pos | state -> s, state -> pos where -- | Splits the state in a strict variant of 'Either', with 'Left'' if a symbol -- can be split off and 'Right'' if none can splitStateE :: state -> Either' state s -- | Splits the state in the first symbol and the remaining state splitState :: state -> (# s, state #) -- | Gets the current position in the input getPosition :: state -> pos -- | Reports an error reportError :: Message s pos -> state -> state reportError _ = id -- | Modify the state as the result of inserting a symbol 's' in the input. -- The symbol that has already been considered as having been inserted -- is passed. It should normally not be added to the state. insertSymbol :: s -> state -> state insertSymbol _ = id -- | Modify the state as the result of deleting a symbol 's' from the input. -- The symbol that has already been deleted from the input state is passed. -- It should normally not be deleted from the state. deleteSymbol :: s -> state -> state deleteSymbol _ = id {- {-# INLINE splitStateE #-} {-# INLINE splitState #-} {-# INLINE insertSymbol #-} {-# INLINE deleteSymbol #-} -} class OutputState r where acceptR :: v -> rest -> r v rest nextR :: (a -> rest -> rest') -> (b -> a) -> (r b rest) -> rest' {- {-# INLINE acceptR #-} {-# INLINE nextR #-} -} class Symbol s where deleteCost :: s -> Int# symBefore :: s -> s symAfter :: s -> s deleteCost b = 5# symBefore = error "You should have made your token type an instance of the Class Symbol. eg by defining symBefore = pred" symAfter = error "You should have made your token type an instance of the Class Symbol. eg by defining symAfter = succ" data Either' state s = Left' !s (state ) | Right' (state ) -- ======================================================================================= -- ===== STEPS =========================================================================== -- ======================================================================================= data Steps val s p = forall a . OkVal (a -> val) (Steps a s p) | Ok { rest :: Steps val s p} | Cost {costing::Int# , rest :: Steps val s p} | StRepair {costing::Int# , m :: !(Message s p) , rest :: Steps val s p} | Best (Steps val s p) (Steps val s p) ( Steps val s p) | NoMoreSteps val data Action s = Insert s | Delete s | Other String val :: (a -> b) -> Steps a s p -> Steps b s p val f (OkVal a rest) = OkVal (f.a) rest val f (Ok rest) = OkVal f rest val f (Cost i rest) = Cost i (val f rest) val f (StRepair c m r) = StRepair c m (val f r) val f (Best l s r) = Best (val f l) (val f s) (val f r) val f (NoMoreSteps v) = NoMoreSteps (f v) evalSteps :: Steps a s p -> a evalSteps (OkVal v rest ) = v (evalSteps rest) evalSteps (Ok rest ) = evalSteps rest evalSteps (Cost _ rest ) = evalSteps rest evalSteps (StRepair _ msg rest ) = evalSteps rest evalSteps (Best _ rest _) = evalSteps rest evalSteps (NoMoreSteps v ) = v getMsgs :: Steps a s p -> [Message s p] getMsgs (OkVal _ rest) = getMsgs rest getMsgs (Ok rest) = getMsgs rest getMsgs (Cost _ rest) = getMsgs rest getMsgs (StRepair _ m rest) = m:getMsgs rest getMsgs (Best _ m _) = getMsgs m getMsgs (NoMoreSteps _ ) = [] data Message sym pos = Msg (Expecting sym) !pos (Action sym) -- Msg (String, String, Expecting s) -- action, position, expecting instance (Eq s, Show s) => Show (Expecting s) where show (ESym s) = show s show (EStr str) = str show (EOr []) = "Nothing expected " show (EOr [e]) = show e show (EOr (e:ee)) = show e ++ " or " ++ show (EOr ee) show (ESeq seq) = concat (map show seq) instance (Eq s, Show s, Show p) => Show (Message s p) where show (Msg expecting position action) = "\n?? Error : " ++ show position ++ "\n?? Expecting : " ++ show expecting ++ "\n?? Repaired by: " ++ show action ++"\n" instance Show s => Show (Action s) where show (Insert s) = "inserting: " ++ show s show (Delete s) = "deleting: " ++ show s show (Other s) = s data Expecting s = ESym (SymbolR s) | EStr String | EOr [Expecting s] | ESeq [Expecting s] deriving (Ord, Eq) -- ======================================================================================= -- ===== SYMBOLS and RANGES ============================================================== -- ======================================================================================= data SymbolR s = Range !s !s | EmptyR deriving (Eq,Ord) instance (Eq s,Show s) => Show (SymbolR s) where show EmptyR = "the empty range" show (Range a b) = if a == b then show a else show a ++ ".." ++ show b mk_range l r = if l > r then EmptyR else Range l r symInRange (Range l r) = if l == r then (l==) else (\ s -> s >= l && s <= r) symRS (Range l r) = if l == r then (compare l) else (\ s -> if s < l then GT else if s > r then LT else EQ) range `except` elems = foldr removeelem [range] elems where removeelem elem ranges = [r | ran <- ranges, r <- ran `minus` elem] EmptyR `minus` _ = [] ran@(Range l r) `minus` elem = if symInRange ran elem then [mk_range l (symBefore elem), mk_range (symAfter elem) r] else [ran] -- ======================================================================================= -- ===== TRACING and ERRORS and MISC =================================================== -- ======================================================================================= usererror m = error ("Your grammar contains a problem:\n" ++ m) systemerror modname m = error ("I apologise: I made a mistake in my design. This should not have happened.\n" ++ " Please report: " ++ modname ++": " ++ m ++ " to doaitse@cs.uu.nl\n")