{-# LANGUAGE MultiParamTypeClasses, FlexibleContexts, FlexibleInstances #-} -- | -- Module : Text.RegExp.Matching.LeftLong -- Copyright : Thomas Wilke, Frank Huch, and Sebastian Fischer -- License : BSD3 -- Maintainer : Sebastian Fischer -- Stability : experimental -- -- This module implements leftmost longest matching based on weighted -- regular expressions. It should be imported qualified as the -- interface resembles that provided by other matching modules. -- module Text.RegExp.Matching.LeftLong ( LeftLong(..), Matching(..), matching, getLeftLong ) where import Text.RegExp -- | -- Subwords of words that match a regular expression are represented -- as values of type 'Matching'. -- data Matching = Matching { -- | Start index of the matching subword in the queried word. matchingIndex :: !Int, -- | Length of the matching subword. matchingLength :: !Int } deriving Eq instance Show Matching where showsPrec _ m = showString "" -- | -- Returns the leftmost longest of all non-empty matchings for a -- regular expression in a given word. If the empty word is the only -- matching its position is zero. -- matching :: RegExp c -> [c] -> Maybe Matching matching r = getLeftLong . partialMatch r -- | -- Semiring used for leftmost longest matching. -- -- The `LeftLong` type satisfies the distributive laws only with a -- precondition on all involved multiplications: multiplied matches -- must be adjacent and the start position must be smaller than the -- end position. This precondition is satisfied for all -- multiplications during regular expression matching. -- data LeftLong = Zero | One | LeftLong !Int !Int deriving (Eq,Show) getLeftLong :: LeftLong -> Maybe Matching getLeftLong Zero = Nothing getLeftLong One = Just $ Matching 0 0 getLeftLong (LeftLong x y) = Just $ Matching x (y-x+1) instance Semiring LeftLong where zero = Zero; one = One Zero .+. y = y x .+. Zero = x One .+. y = y x .+. One = x LeftLong a b .+. LeftLong c d | a=d = LeftLong a b | otherwise = LeftLong c d Zero .*. _ = Zero _ .*. Zero = Zero One .*. y = y x .*. One = x LeftLong a _ .*. LeftLong _ b = LeftLong a b instance Weight c (Int,c) LeftLong where symWeight p (n,c) = p c .*. LeftLong n n