module Text.GrammarCombinators.Library.Numeric (
DecimalInteger,
NumericDomain (DecimalInteger),
NumericValue (NVI),
numericGrammar,
procNumericGrammar
) where
import Text.GrammarCombinators.Base
data DecimalDigit
data DecimalNonZeroDigit
data DecimalInteger
data NumericDomain ix where
DecimalDigit :: NumericDomain DecimalDigit
DecimalNonZeroDigit :: NumericDomain DecimalNonZeroDigit
DecimalInteger :: NumericDomain DecimalInteger
instance ShowFam NumericDomain where
showIdx DecimalDigit = "DecimalDigit"
showIdx DecimalNonZeroDigit = "DecimalNonZeroDigit"
showIdx DecimalInteger = "DecimalInteger"
instance FoldFam NumericDomain where
foldFam f n = f DecimalDigit $ f DecimalNonZeroDigit $ f DecimalInteger n
instance MemoFam NumericDomain where
data Memo NumericDomain v = MND (v DecimalDigit) (v DecimalNonZeroDigit) (v DecimalInteger)
toMemo f = MND (f DecimalDigit) (f DecimalNonZeroDigit) (f DecimalInteger)
fromMemo (MND v _ _) DecimalDigit = v
fromMemo (MND _ v _) DecimalNonZeroDigit = v
fromMemo (MND _ _ v) DecimalInteger = v
instance EqFam NumericDomain where
overrideIdx _ DecimalDigit v DecimalDigit = v
overrideIdx _ DecimalNonZeroDigit v DecimalNonZeroDigit = v
overrideIdx _ DecimalInteger v DecimalInteger = v
overrideIdx f _ _ idx = f idx
instance Domain NumericDomain
data PFNum r ix where
DecimalDigitF :: Char -> PFNum r DecimalDigit
DecimalNonZeroDigitF :: Char -> PFNum r DecimalNonZeroDigit
DecimalIntegerF :: r DecimalNonZeroDigit -> [r DecimalDigit] -> PFNum r DecimalInteger
type instance PF NumericDomain = PFNum
numericGrammar :: ExtendedContextFreeGrammar NumericDomain Char
numericGrammar DecimalInteger = DecimalIntegerF $>> ref DecimalNonZeroDigit >>> manyRef DecimalDigit
numericGrammar DecimalDigit = DecimalDigitF $>> tokenRange ['0'..'9']
numericGrammar DecimalNonZeroDigit = DecimalNonZeroDigitF $>> tokenRange ['1'..'9']
data family NumericValue n ix
data instance NumericValue n DecimalInteger = NVI n
data instance NumericValue n DecimalDigit = NVD { unNVD :: Char }
data instance NumericValue n DecimalNonZeroDigit = NVND Char
processNumerics :: (Read n) => Processor NumericDomain (NumericValue n)
processNumerics DecimalDigit (DecimalDigitF c) = NVD c
processNumerics DecimalNonZeroDigit (DecimalNonZeroDigitF c) = NVND c
processNumerics DecimalInteger (DecimalIntegerF (NVND c) wcs) = NVI num
where num = read $ c : cs
cs = map unNVD wcs
procNumericGrammar :: (Read n) => ProcessingExtendedContextFreeGrammar NumericDomain Char (NumericValue n)
procNumericGrammar = applyProcessorE numericGrammar processNumerics