{-# OPTIONS_GHC -fno-warn-orphans #-}{-
Copyright (C) 2010 Dr. Alistair Ward
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
-}{- |
[@AUTHOR@] Dr. Alistair Ward
[@DESCRIPTION@] An 'RegExDot.RegEx.ExtendedRegEx', which has been specialised for 'Char', to create a tradition non-polymorphic /regex/.
-}moduleRegExChar.ExtendedRegExChar(-- * Types-- ** Type-synonymsExtendedRegExChar(..),InputData,-- * Functions-- ** Operators(+~),(=~),(/~))whereimportControl.Applicative((<$>),(<*>))importqualifiedData.ListimportqualifiedRegExChar.MetaCharasMetaCharimportqualifiedRegExDot.AnchorimportqualifiedRegExDot.ConsumerimportRegExDot.DSL((<~>),(-:))importqualifiedRegExDot.RegEximportqualifiedRegExDot.RegExOptsimportqualifiedRegExDot.RepeatableimportqualifiedText.ParserCombinators.ParsecasParsecimportText.ParserCombinators.Parsec((<?>),(<|>))importqualifiedToolShed.Data.PairimportqualifiedToolShed.SelfValidateinfix4+~,=~,/~--Same as (==) & (/=).-- | Specialise a 'RegExDot.RegEx.ExtendedRegEx' for 'Char', & encapsulate it to permit tailored instance-declarations.dataExtendedRegExChar=MkExtendedRegExChar{hasNonCapturingTopLevelAlternatives::Bool,-- ^ The string from which a 'RegExDot.RegEx.ExtendedRegEx' is read, may, if data-capture isn't required, omit explicit delimiters around top-level 'RegExDot.RegEx.Alternatives'.extendedRegEx::RegExDot.RegEx.ExtendedRegExChar}derivingEq-- | Abbreviation.typeInputData=RegExDot.RegEx.InputDataCharinstanceToolShed.SelfValidate.SelfValidatorExtendedRegExCharwheregetErrorsMkExtendedRegExChar{hasNonCapturingTopLevelAlternatives=hasNonCapturingTopLevelAlternatives',extendedRegEx=extendedRegEx'}|not$ToolShed.SelfValidate.isValidextendedRegEx'=ToolShed.SelfValidate.getErrorsextendedRegEx'|otherwise=ToolShed.SelfValidate.extractErrors[(hasNonCapturingTopLevelAlternatives'&&any(not.RegExDot.RegEx.isCaptureGroup.RegExDot.Repeatable.base)(RegExDot.RegEx.concatenationextendedRegEx'),"Invalid NonCapturingTopLevelAlternatives.")]instanceRegExDot.Consumer.ConsumerExtendedRegExCharwhereconsumptionProfile=RegExDot.Consumer.consumptionProfile.extendedRegExstarHeight=RegExDot.Consumer.starHeight.extendedRegExinstanceRegExDot.RegEx.ShortcutExpanderCharwhereexpandc=error$"RegExDot.RegEx.ShortcutExpander.expand RegExChar.ExtendedRegExChar:\tunrecognised shortcut '"++showc++"'."instanceReadExtendedRegExCharwherereadsPrec_s|s==reverseRegExDot.Anchor.tokens=[(MkExtendedRegExChar{hasNonCapturingTopLevelAlternatives=False,extendedRegEx=(JustRegExDot.Anchor.Bow,JustRegExDot.Anchor.Stern)<~>[]},"")]--The order of adjacent zero-width assertions is irrelevant.|otherwise=letextendedRegExCharParser::Parsec.ParserExtendedRegExCharextendedRegExCharParser=reduce{-correct prior assumption-}<$>alternativesParser{-assume non-capturing top-level Alternatives-}wherereduce::RegExDot.RegEx.AlternativesChar->ExtendedRegExCharreducealternatives|RegExDot.RegEx.isSingletonAlternativesalternatives=MkExtendedRegExCharFalse.head$RegExDot.RegEx.deconstructAlternativesalternatives|otherwise=MkExtendedRegExCharTrue$RegExDot.Anchor.unanchored<~>RegExDot.RegEx.CaptureGroupalternatives-:[]--Infer non-capturing top-level 'RegExDot.RegEx.Alternatives' from the presence of 'RegExDot.RegEx.alternativeExtendedRegExSeparatorToken's.alternativesParser::Parsec.Parser(RegExDot.RegEx.AlternativesChar)alternativesParser=RegExDot.RegEx.MkAlternatives<$>extendedRegExParser`Parsec.sepBy1`(Parsec.charRegExDot.RegEx.alternativeExtendedRegExSeparatorToken<?>"RegExDot.RegEx.alternativeExtendedRegExSeparatorToken "++showRegExDot.RegEx.alternativeExtendedRegExSeparatorToken)whereextendedRegExParser::Parsec.Parser(RegExDot.RegEx.ExtendedRegExChar)extendedRegExParser=domaybeBowAnchor<-Parsec.optionNothing{-default-}$(Parsec.charRegExDot.Anchor.bowToken<?>"RegExDot.Anchor.bowToken "++showRegExDot.Anchor.bowToken)>>return{-to ParsecT-monad-}(JustRegExDot.Anchor.Bow)repeatableRequirementList<-repeatableRequirementListParser(dorepeatableCaptureGroup<-RegExDot.Repeatable.repeatableParser.RegExDot.RegEx.CaptureGroup=<<uncurryParsec.between(ToolShed.Data.Pair.mirrorParsec.charRegExDot.RegEx.captureGroupDelimiters)alternativesParser{-recurse-}<?>"RegExDot.RegEx.captureGroupDelimiters "++showRegExDot.RegEx.captureGroupDelimitersextendedRegEx'<-extendedRegExParser--Recurse.return{-to ParsecT-monad-}$RegExDot.RegEx.transformExtendedRegEx((repeatableRequirementList++).(repeatableCaptureGroup:))extendedRegEx'{RegExDot.RegEx.bowAnchor=maybeBowAnchor})<|>(domaybeSternAnchor<-Parsec.optionNothing{-default-}$(Parsec.charRegExDot.Anchor.sternToken<?>"RegExDot.Anchor.sternToken "++showRegExDot.Anchor.sternToken)>>return{-to ParsecT-monad-}(JustRegExDot.Anchor.Stern)return{-to ParsecT-monad-}RegExDot.RegEx.MkExtendedRegEx{RegExDot.RegEx.bowAnchor=maybeBowAnchor,RegExDot.RegEx.concatenation=repeatableRequirementList,RegExDot.RegEx.sternAnchor=maybeSternAnchor})whererepeatableRequirementListParser::Parsec.Parser(RegExDot.RegEx.ConcatenationChar)repeatableRequirementListParser=Parsec.choice[Parsec.try.Parsec.lookAhead$(Parsec.charRegExDot.Anchor.sternToken<?>"RegExDot.Anchor.sternToken "++showRegExDot.Anchor.sternToken)>>((Parsec.eof>>return{-to ParsecT-monad-}[])<|>(Parsec.oneOf[RegExDot.RegEx.alternativeExtendedRegExSeparatorToken,sndRegExDot.RegEx.captureGroupDelimiters]>>return{-to ParsecT-monad-}[])),(:)<$>(MetaChar.metaCharParser>>=RegExDot.Repeatable.repeatableParser.RegExDot.RegEx.Require.MetaChar.deconstruct)<*>repeatableRequirementListParser,{-recurse-}return{-to ParsecT-monad-}[]]in(error.("readsPrec RegExChar.ExtendedRegExChar:\tparse-error; "++).show--Failure to parse.)`either`(\pair@(extendedRegExChar,_)->ifToolShed.SelfValidate.isValidextendedRegExCharthen[pair]elseerror$ToolShed.SelfValidate.getFirstErrorextendedRegExChar--Parsed OK, but invalid.)$Parsec.parse((,)<$>extendedRegExCharParser<*>Parsec.getInput)"ExtendedRegExChar"sinstanceShowExtendedRegExCharwhereshowsPrec_MkExtendedRegExChar{hasNonCapturingTopLevelAlternatives=hasNonCapturingTopLevelAlternatives',extendedRegEx=RegExDot.RegEx.MkExtendedRegEx{RegExDot.RegEx.bowAnchor=maybeBowAnchor,RegExDot.RegEx.concatenation=concatenation',RegExDot.RegEx.sternAnchor=maybeSternAnchor}}=RegExDot.RegEx.showsMaybeAnchormaybeBowAnchor.foldl(.)(showString"")((letshowAlternatives::RegExDot.RegEx.AlternativesChar->[ShowS]showAlternatives=Data.List.intersperse(showCharRegExDot.RegEx.alternativeExtendedRegExSeparatorToken).map(shows.MkExtendedRegExCharFalse).RegExDot.RegEx.deconstructAlternativesinifhasNonCapturingTopLevelAlternatives'thenmap(\repeatablePattern->caseRegExDot.Repeatable.baserepeatablePatternofRegExDot.RegEx.CaptureGroupalternatives->foldr(.)(showString"")$showAlternativesalternatives_->error$"Show RegExChar.ExtendedRegExChar: unexpected "++showrepeatablePattern)elsemap(\repeatablePattern->(caseRegExDot.Repeatable.baserepeatablePatternofRegExDot.RegEx.Requiremeta->shows$MetaChar.MkMetaCharmetaRegExDot.RegEx.CaptureGroupalternatives->showChar(fstRegExDot.RegEx.captureGroupDelimiters).foldr(.)(showChar$sndRegExDot.RegEx.captureGroupDelimiters--Initial value.)(showAlternativesalternatives)).RegExDot.Repeatable.showSuffixrepeatablePattern))concatenation').RegExDot.RegEx.showsMaybeAnchormaybeSternAnchor-- | A veneer over the underlying polymorphic operator, 'RegExDot.RegEx.+~'.(+~)::InputData-- ^ The input-data string.->RegExDot.RegExOpts.RegExOptsExtendedRegExChar-- ^ The match-options, parameterised by the regex-specification.->RegExDot.RegEx.ResultCharinputData+~regExOpts=inputDataRegExDot.RegEx.+~fmapextendedRegExregExOpts--CAVEAT: <http://hackage.haskell.org/trac/haskell-prime/wiki/QualifiedOperators>.-- | A veneer over the underlying polymorphic operator, 'RegExDot.RegEx.=~'.(=~)::InputData-- ^ The input-data string.->RegExDot.RegExOpts.RegExOptsExtendedRegExChar-- ^ The match-options, parameterised by the regex-specification.->BoolinputData=~regExOpts=inputDataRegExDot.RegEx.=~fmapextendedRegExregExOpts--CAVEAT: <http://hackage.haskell.org/trac/haskell-prime/wiki/QualifiedOperators>.-- | Pattern-mismatch operator.(/~)::InputData-- ^ The input-data string.->RegExDot.RegExOpts.RegExOptsExtendedRegExChar-- ^ The match-options, parameterised by the regex-specification.->Bool(/~)inputData=not.(inputData=~)