regexchar 0.9.0.9 → 0.9.0.10
raw patch · 18 files changed
+566/−488 lines, 18 filesdep ~regexdotdep ~toolshed
Dependency ranges changed: regexdot, toolshed
Files
- changelog +5/−0
- makefile +21/−19
- man/man1/grecce.1 +52/−17
- regexchar.cabal +5/−5
- regexchar.spec +39/−19
- src/Grecce/CommandOptions.hs +20/−20
- src/Grecce/Grep.hs +14/−14
- src/Grecce/Test/Assert/RegExOptsChar.hs +4/−4
- src/Grecce/Test/Performance/ExtendedRegEx.hs +19/−19
- src/Grecce/Test/Performance/ExtendedRegExTest.hs +2/−2
- src/Grecce/Test/Performance/ExtendedRegExTestsPositive.hs +50/−50
- src/Grecce/Test/QC/ExtendedRegExChar.hs +67/−69
- src/Grecce/Test/QC/MetaChar.hs +11/−10
- src/Grecce/Test/QC/RepeatableMetaChar.hs +22/−21
- src/Main.hs +58/−42
- src/RegExChar/ExtendedRegExChar.hs +68/−68
- src/RegExChar/MetaChar.hs +65/−65
- src/RegExChar/RegExOptsChar.hs +44/−44
changelog view
@@ -50,3 +50,8 @@ * Replaced use of "Control.Monad" in "RegExChar.MetaChar" and "RegExChar.ExtendedRegExChar", with "Control.Applicative". * Replaced "System" with "System.Environment" and "System.Exit". * Removed dependency on "haskell98".+0.9.0.10+ * Fully qualified symbols imported from package "regexdot".+ * Used new constant 'RegExDot.Anchor.unanchored'.+ * Added details to any failure to parse the command-line arguments.+ * Used new test-modules from 'toolshed-0.14.0.0'.
makefile view
@@ -15,52 +15,54 @@ .PHONY: all build check clean clobber configure copy deb haddock help hlint install lintian prof rpm rpmlint sdist +PACKAGE_NAME=regexchar+ all: install install: build haddock @[ -z "$$CABAL_INSTALL_OPTIONS" ] || echo "INFO: CABAL_INSTALL_OPTIONS='$$CABAL_INSTALL_OPTIONS'"- runhaskell Setup.hs $@ $$CABAL_INSTALL_OPTIONS+ runhaskell Setup $@ $$CABAL_INSTALL_OPTIONS prof: CABAL_CONFIGURE_OPTIONS="--enable-library-profiling --enable-executable-profiling $$CABAL_CONFIGURE_OPTIONS" make build copy: build @[ -z "$$CABAL_COPY_OPTIONS" ] || echo "INFO: CABAL_COPY_OPTIONS='$$CABAL_COPY_OPTIONS'"- runhaskell Setup.hs $@ $$CABAL_COPY_OPTIONS+ runhaskell Setup $@ $$CABAL_COPY_OPTIONS build: configure @[ -z "$$CABAL_BUILD_OPTIONS" ] || echo "INFO: CABAL_BUILD_OPTIONS='$$CABAL_BUILD_OPTIONS'"- runhaskell Setup.hs $@ $$CABAL_BUILD_OPTIONS+ runhaskell Setup $@ $$CABAL_BUILD_OPTIONS -configure: regexchar.cabal Setup.hs+configure: $(PACKAGE_NAME).cabal Setup.hs @[ -z "$$CABAL_CONFIGURE_OPTIONS" ] || echo "INFO: CABAL_CONFIGURE_OPTIONS='$$CABAL_CONFIGURE_OPTIONS'"- runhaskell Setup.hs $@ $$CABAL_CONFIGURE_OPTIONS #--user+ runhaskell Setup $@ $$CABAL_CONFIGURE_OPTIONS #--user haddock: configure- PATH=~/.cabal/bin:$$PATH runhaskell Setup.hs $@ --hyperlink-source --executables #Amend path to find 'HsColour', as required for 'hyperlink-source'.+ PATH=~/.cabal/bin:$$PATH runhaskell Setup $@ --hyperlink-source --executables #Amend path to find 'HsColour', as required for 'hyperlink-source'. hlint: @$@ -i 'Use ||' src/ -sdist: configure- runhaskell Setup.hs $@+sdist:+ runhaskell Setup $@ -check: sdist+check: cabal upload --check --verbose=3 dist/*.tar.gz; -rpm: regexchar.spec- rpmbuild -bb -- $^- mv -- `find /usr/src/packages/ -type f -name 'regexchar*.rpm' -mtime 0 -print` ./+rpm: $(PACKAGE_NAME).spec+ rpmbuild -bb --nodeps -- $^+ mv -- `find /usr/src/packages/ -type f -name '$(PACKAGE_NAME)*.rpm' -mtime 0 -print` ./ -rpmlint: regexchar.spec+rpmlint: $(PACKAGE_NAME).spec @$@ $^ deb: build- mkdir -p 'debian/usr/bin/' && strip --strip-all 'dist/build/grecce/grecce' && mv 'dist/build/grecce/grecce' 'debian/usr/bin/'- mkdir -p 'debian/usr/share/doc/regexchar/' && cp 'changelog' 'changelog.Debian' 'LICENSE' 'debian/usr/share/doc/regexchar/' && gzip --best debian/usr/share/doc/regexchar/*- mkdir -p 'debian/usr/share/regexchar/data/' && cp data/*.txt 'debian/usr/share/regexchar/data/'- cp 'copyright' 'debian/usr/share/doc/regexchar/'- mkdir -p 'debian/usr/share/man/man1/' && cp 'man/man1/grecce.1' 'debian/usr/share/man/man1/' && gzip --best debian/usr/share/man/man1/*.1+ mkdir -p debian/usr/bin/ && strip --strip-all dist/build/grecce/grecce && mv dist/build/grecce/grecce debian/usr/bin/+ mkdir -p 'debian/usr/share/doc/$(PACKAGE_NAME)/' && cp changelog changelog.Debian copyright LICENSE 'debian/usr/share/doc/$(PACKAGE_NAME)/' && cd 'debian/usr/share/doc/$(PACKAGE_NAME)/' && gzip --best -f changelog changelog.Debian LICENSE+ cp 'copyright' 'debian/usr/share/doc/$(PACKAGE_NAME)/'+ mkdir -p 'debian/usr/share/$(PACKAGE_NAME)/' && cp -R data/ 'debian/usr/share/$(PACKAGE_NAME)/'+ mkdir -p debian/usr/share/ && cp -R man/ debian/usr/share/ && gzip --best -f debian/usr/share/man/man1/*.1 cd 'debian' && md5sum `find usr -type f -print` >'DEBIAN/md5sums' fakeroot dpkg-deb --build debian . @@ -68,7 +70,7 @@ lintian -v *.deb clean:- runhaskell Setup.hs $@+ runhaskell Setup $@ rm -rf 'debian/usr/' 'debian/DEBIAN/md5sums' find src -type f \( -name '*.hc' -o -name '*.hcr' -o -name '*.hi' -o -name '*.o' \) -delete
man/man1/grecce.1 view
@@ -17,11 +17,16 @@ .IP \(bu \fICapture-groups\fR, potentially containing alternative \fIsub-expression\fRs. .IP \(bu-\fIBracket-expressions\fR+.I Bracket-expressions .br (including \fBPerl\fR-style \fIshortcuts\fR for; \fB\\d\fR, \fB\\D\fR, \fB\\s\fR, \fB\\S\fR, \fB\\w\fR, \fB\\W\fR) .IP \(bu-Posix \fICharacter-classes\fR; \fB[:alnum:]\fR, \fB[:alpha:]\fR, \fB[:ascii:]\fR, \fB[:blank:]\fR, \fB[:cntrl:]\fR, \fB[:digit:]\fR, \fB[:graph:]\fR, \fB[:lower:]\fR, \fB[:print:]\fR, \fB[:punct:]\fR, \fB[:space:]\fR, \fB[:upper:]\fR, \fB[:word:]\fR, \fB[:xdigit:]\fR+Posix \fICharacter-classes\fR;+.br+.nf+\fB[:alnum:]\fR, \fB[:alpha:]\fR, \fB[:ascii:]\fR, \fB[:blank:]\fR, \fB[:cntrl:]\fR, \fB[:digit:]\fR, \fB[:graph:]\fR,+\fB[:lower:]\fR, \fB[:print:]\fR, \fB[:punct:]\fR, \fB[:space:]\fR, \fB[:upper:]\fR, \fB[:word:]\fR, \fB[:xdigit:]\fR+.fi .SH OPTIONS .SS "General Output Control" .TP@@ -34,7 +39,7 @@ \fB-L\fR, \fB--files-without-match\fR List names of files not containing any matches. .TP-\fB--verbose\fR+.B --verbose .IP \(bu Shows how the input data was captured by \fIregex\fR. .IP \(bu@@ -116,43 +121,67 @@ Prefer solutions employing fewer repetitions of alternatives, to discourage the capture of null lists. .SS "Generic Program-information" .TP-\fB--version\fR+.B --version Output version-information & exit. .TP \fB-?\fR, \fB--help\fR Display help & exit. .TP-\fB--printCurrentSettings\fR+.B --printCurrentSettings Display the currently defined options & then exit.+.SS Test+.TP+\fB--runQuickChecks\fR+Uses \fBQuickCheck\fR to validate invariant properties, using arbitrary data; then exits.+.TP+\fB--assert=\fR\fIfile\fR+Confirms the assertions in the specified file from the \fBdata\fR-directory of the distribution; then exits. .SH EXIT-STATUS \fB0\fR on success, and >\fB0\fR if an error occurs. .SH EXAMPLES-.TP+.PP+.nf \fBecho\fR 'Function Alley' | \fBgrecce\fR 'n\\sA' Function Alley-.TP+.fi+.PP+.nf \fBecho\fR 'Function Alley' | \fBgrecce\fR --verbose '[[:alpha:]]+' (Just (.*?,0,""),Just [([[:alpha:]]+,0,"Function")],Just (.*,8," Alley"))-.SH Pathological-.TP+.fi+.SS Pathological+.PP+.nf \fBecho\fR 'aaa' | \fBgrecce\fR --verbose '^(a?){3}(a){3}$' (Nothing,Just [[[('a'?,0,"")],[('a'?,0,"")],[('a'?,0,"")]],[[('a',0,"a")],[('a',1,"a")],[('a',2,"a")]]],Nothing)-.TP+.fi+.PP+.nf \fBecho\fR 'azazaz' | \fBgrecce\fR --verbose '^(.*z){3}$' (Nothing,Just [[[(.*,0,"a"),('z',1,"z")],[(.*,2,"a"),('z',3,"z")],[(.*,4,"a"),('z',5,"z")]]],Nothing)-.TP+.fi+.PP+.nf \fBecho\fR 'aaaaaa' | \fBgrecce\fR --verbose '^a*a+a{2,}a{3,}$' (Nothing,Just [('a'*,0,""),('a'+,0,"a"),('a'{2,},1,"aa"),('a'{3,},3,"aaa")],Nothing)-.TP+.fi+.PP+.nf \fBecho\fR 'aaaaaaaabc' | \fBgrecce\fR --verbose '(a|a{2})*c' (Just (.*?,0,"aaaaaaaab"),Just [[],('c',9,"c")],Just (.*,10,""))+.fi+.SH FILES+.IP \(bu+.I data/Tests_ATTBasic.txt+.IP \(bu+.I data/Tests_ATTInterpretation.txt+.IP \(bu+.I data/Tests.txt .SH AUTHOR Written by Dr. Alistair Ward. .SH BUGS .SS "REPORTING BUGS" Report bugs to \fBgrecce\fR \fIat\fR \fBfunctionalley\fR \fIdot\fR \fBeu\fR-.PP-Home page: \fBhttp://functionalley.eu\fR .SS Known Bugs There is no support for either \fIBack-references\fR or \fICase-insensitivity\fR. .PP@@ -168,6 +197,12 @@ .PP You should have received a copy of the GNU General Public License along with this program. If not, see \fB<http://www.gnu.org/licenses/>\fR. .SH "SEE ALSO"-The full documentation for \fBgrecce\fR is generated by \fBHaddock\fR, & is available in the distribution.-.PP-Built from \fBRegExChar\fR, a specialisation of the polymorphic regex-engine \fBRegExDot\fR.+.IP \(bu+Home-page: \fBhttp://functionalley.eu\fR+.IP \(bu+Source-documentation is generated by \fBHaddock\fR, & is available in the distribution.+.IP \(bu+.I http://www.haskell.org/haddock/+.IP \(bu+\fBRegExDot\fR, the polymorphic regex-engine from which this is built.+
regexchar.cabal view
@@ -1,6 +1,6 @@ --Package-properties Name: regexchar-Version: 0.9.0.9+Version: 0.9.0.10 Cabal-Version: >= 1.6 Copyright: (C) 2010 Dr. Alistair Ward License: GPL@@ -11,12 +11,12 @@ Build-Type: Simple Description: Provides a POSIX, extended regex-engine, specialised from the underlying /polymorphic/ package /regexdot/, to merely process the traditional character-lists. Category: Regex, Text-Tested-With: GHC == 6.10, GHC == 6.12, GHC == 7.0+Tested-With: GHC == 6.10, GHC == 6.12, GHC == 7.0, GHC == 7.4 Homepage: http://functionalley.eu Maintainer: regexchar <at> functionalley <dot> eu Bug-reports: regexchar <at> functionalley <dot> eu Data-files: data/*.txt-Extra-Source-Files: man/man1/*.1 *.spec changelog copyright makefile+Extra-Source-Files: changelog copyright makefile man/man1/grecce.1 regexchar.spec flag threaded Description: Link with the threaded runtime.@@ -39,8 +39,8 @@ base == 4.*, containers, parsec == 3.*,- regexdot == 0.11.*,- toolshed == 0.13.*+ regexdot >= 0.11.1.0,+ toolshed == 0.14.* GHC-options: -Wall
regexchar.spec view
@@ -1,14 +1,30 @@+# Copyright (C) 2012 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/>.+ %define package %name-%version %define tarBall %package.tar.gz %define _bindir %prefix/bin %define _libdir %prefix/lib/%package-%define _datadir %prefix/share/%package-%define _docdir %prefix/share/doc/%package-%define _mandir %prefix/share/man+%define _sharedir %prefix/share+%define _datadir %_sharedir/%package+%define _docdir %_sharedir/doc/%package+%define _mandir %_sharedir/man -Summary: A re-implementation of egrep, using a specialisation of a polymorphic regex-engine.+Summary: A re-implementation of egrep, using a specialisation of a polymorphic regex-engine Name: regexchar-Version: 0.9.0.9+Version: 0.9.0.10 Release: 1 License: GPLv3 #From '/usr/share/doc/packages/rpm/GROUPS'.@@ -16,35 +32,39 @@ Source0: http://functionalley.eu/Downloads/sdist/%tarBall URL: http://functionalley.eu Prefix: /usr+BuildRequires: ghc %description Provides a POSIX extended regex-engine, specialised from an underlying polymorphic engine, to process merely character-lists, as is typically required. %prep-rm -rf -- '%package/'-CABAL_CONFIGURE_OPTIONS='--user' make --directory="$OLDPWD/" sdist && mv -- "$OLDPWD/dist/%tarBall" '%_sourcedir/' && tar -zxf '%_sourcedir/%tarBall' #Build & copy the tar-ball into the source-directory, then unpack it into the build-directory.+#NB: we've changed directory to %_builddir+(cd $OLDPWD && runhaskell Setup sdist) && tar -zxf $OLDPWD/dist/%tarBall #Make a source-distribution & unpack it into the build-directory.+cd '%package/' && runhaskell Setup configure --user --prefix=%prefix #Configure to use the user's personal package-database & to generate an appropriate Paths module. %build+cd '%package/' && runhaskell Setup build #Descend into the source-distribution and build according to the previously established configuration. %install-rm -rf -- '%buildroot/' #Clean any previous build. CAVEAT: the user might have specified '--buildroot', for which I can't account.-CABAL_CONFIGURE_OPTIONS='--user --prefix=%buildroot%prefix/' make --directory='%package/' install #Which regrettably also builds 'Haddock', which then requires 'HsColour'.-mkdir -p -- '%buildroot%_mandir/' && mv -- '%_builddir/%package/man/man1' '%buildroot%_mandir/'-mkdir -p -- '%buildroot%_docdir/' && mv -- %_builddir/%package/{changelog,copyright,LICENSE} '%buildroot%_docdir/'-rm -- $(find '%buildroot%_libdir/' \( -name '*.o' -o -name '*.hi' \) -print)-rm -rf -- $(find '%buildroot' -type d -name 'html') #We don't need source-code documentation in a binary package.+cd '%package/' #Descend into the build-directory.+runhaskell Setup copy --destdir=%buildroot #Install the package in the target-directory.+rm -rf '%buildroot%_libdir/' #Remove unrequired libraries.+mkdir -p -- '%buildroot%_docdir' && mv -- changelog copyright LICENSE '%buildroot%_docdir/'+mkdir -p -- '%buildroot%_mandir' && mv -- 'man/man1' '%buildroot%_mandir/' %clean-make --directory='%package/' clobber-rm -- '%_sourcedir/%tarBall'-rm -rf -- '%_builddir/%package' '%buildroot'+make --directory='%package' clobber+rm -rf -- '%_builddir/%package/' '%buildroot' %files %attr(0755, root, root) %_bindir/grecce-%attr(0644, root, root) %_libdir/ghc-*/libHS%{package}.a-%attr(0644, root, root) %doc %_mandir/man1/*.1.gz+%attr(0644, root, root) %_datadir/data/*.txt %attr(0644, root, root) %doc %_docdir/changelog %attr(0644, root, root) %doc %_docdir/copyright %attr(0644, root, root) %doc %_docdir/LICENSE-%attr(0644, root, root) %_datadir/data/*.txt+%attr(0644, root, root) %doc %_mandir/man1/grecce.1.gz +%changelog+* Wed May 09 2012 Alistair Ward <regexchar at functionalley dot eu> 0.9.0.10-1+Removed "rm -rf -- '%buildroot'" from build, for security.+Corrected "Paths" modul, even though it's unused.
src/Grecce/CommandOptions.hs view
@@ -46,25 +46,25 @@ ) where import qualified RegExChar.ExtendedRegExChar as ExtendedRegExChar-import qualified RegExDot.CompilationOptions as CompilationOptions-import qualified RegExDot.ExecutionOptions as ExecutionOptions+import qualified RegExDot.CompilationOptions+import qualified RegExDot.ExecutionOptions import qualified ToolShed.Defaultable import qualified ToolShed.Options -- | The set of command-line options; based on those provided by /egrep/. data CommandOptions = MkCommandOptions {- countMatches :: Bool, -- ^ Print only a count of matching lines per file.- extendedRegExChar :: Maybe ExtendedRegExChar.ExtendedRegExChar, -- ^ The /regex/.- invertMatch :: Bool, -- ^ Select non-matching lines.- prependLineNumbers :: Bool, -- ^ Prepend the line-number of the matched input-data, to the output.- listFilesWithMatches :: Bool, -- ^ List the names of any files containing at least one match.- listFilesWithoutMatch :: Bool, -- ^ List the names of any files containing zero matches.- verbose :: Bool, -- ^ Show the captured data.- compilationOptions :: CompilationOptions.CompilationOptions, -- ^ Used to define the regex-request.- executionOptions :: ExecutionOptions.ExecutionOptions -- ^ Used to control the regex-runtime.+ countMatches :: Bool, -- ^ Print only a count of matching lines per file.+ extendedRegExChar :: Maybe ExtendedRegExChar.ExtendedRegExChar, -- ^ The /regex/.+ invertMatch :: Bool, -- ^ Select non-matching lines.+ prependLineNumbers :: Bool, -- ^ Prepend the line-number of the matched input-data, to the output.+ listFilesWithMatches :: Bool, -- ^ List the names of any files containing at least one match.+ listFilesWithoutMatch :: Bool, -- ^ List the names of any files containing zero matches.+ verbose :: Bool, -- ^ Show the captured data.+ compilationOptions :: RegExDot.CompilationOptions.CompilationOptions, -- ^ Used to define the regex-request.+ executionOptions :: RegExDot.ExecutionOptions.ExecutionOptions -- ^ Used to control the regex-runtime. } deriving Show --- | An arbitrary function which transforms the supplied 'ExecutionOptions.ExecutionOptions'.+-- | An arbitrary function which transforms the supplied 'RegExDot.ExecutionOptions.ExecutionOptions'. type Transformer = CommandOptions -> CommandOptions instance ToolShed.Defaultable.Defaultable CommandOptions where@@ -142,7 +142,7 @@ ] = error "Grecce.CommandOptions.setListFilesWithoutMatch:\t'listFilesWithoutMatch' is incompatible with; 'countMatches', 'prependLineNumbers', 'listFilesWithMatches' & 'verbose'." | otherwise = commandOptions { listFilesWithoutMatch = True } --- | Mutator, which additionally sets the corresponding 'ExecutionOptions.ExecutionOptions'.+-- | Mutator, which additionally sets the corresponding 'RegExDot.ExecutionOptions.ExecutionOptions'. setVerbose :: Transformer setVerbose commandOptions | ($ commandOptions) `any` [@@ -153,20 +153,20 @@ ] = error "Grecce.CommandOptions.setVerbose:\t'verbose' is incompatible with; 'countMatches', 'invertMatch', 'listFilesWithoutMatch' & 'listFilesWithMatches'." | otherwise = commandOptions { verbose = True,- executionOptions = ExecutionOptions.setVerbose True $ executionOptions commandOptions+ executionOptions = RegExDot.ExecutionOptions.setVerbose True $ executionOptions commandOptions } --- | A function which accepts a 'String' & the 'CompilationOptions.CompilationOptions' to transform, using its value.-type CompilationOptionsMutator = String -> CompilationOptions.CompilationOptions -> CompilationOptions.CompilationOptions+-- | A function which accepts a 'String' & the 'RegExDot.CompilationOptions.CompilationOptions' to transform, using its value.+type CompilationOptionsMutator = String -> RegExDot.CompilationOptions.CompilationOptions -> RegExDot.CompilationOptions.CompilationOptions --- | Generic mutator, which accepts a function & the parameter-string it requires, to amend an unspecified field of 'CompilationOptions.CompilationOptions'.+-- | Generic mutator, which accepts a function & the parameter-string it requires, to amend an unspecified field of 'RegExDot.CompilationOptions.CompilationOptions'. setCompilationOption :: CompilationOptionsMutator -> String -> Transformer setCompilationOption compilationOptionsMutator s commandOptions = commandOptions { compilationOptions = compilationOptionsMutator s $ compilationOptions commandOptions } --- | A function which accepts a 'String' & the 'ExecutionOptions.ExecutionOptions' to transform, using its value.-type ExecutionOptionsMutator = String -> ExecutionOptions.ExecutionOptions -> ExecutionOptions.ExecutionOptions+-- | A function which accepts a 'String' & the 'RegExDot.ExecutionOptions.ExecutionOptions' to transform, using its value.+type ExecutionOptionsMutator = String -> RegExDot.ExecutionOptions.ExecutionOptions -> RegExDot.ExecutionOptions.ExecutionOptions --- | Generic mutator, which accepts a function & the parameter-string it requires, to amend an unspecified field of 'ExecutionOptions.ExecutionOptions'.+-- | Generic mutator, which accepts a function & the parameter-string it requires, to amend an unspecified field of 'RegExDot.ExecutionOptions.ExecutionOptions'. setExecutionOption :: ExecutionOptionsMutator -> String -> Transformer setExecutionOption executionOptionsMutator s commandOptions = commandOptions { executionOptions = executionOptionsMutator s $ executionOptions commandOptions }
src/Grecce/Grep.hs view
@@ -38,9 +38,9 @@ import qualified Grecce.CommandOptions as CommandOptions import qualified RegExChar.ExtendedRegExChar as ExtendedRegExChar import RegExChar.ExtendedRegExChar((+~), (=~))-import qualified RegExDot.RegEx as RegEx-import qualified RegExDot.RegExOpts as RegExOpts-import qualified RegExDot.Result as Result+import qualified RegExDot.RegEx+import qualified RegExDot.RegExOpts+import qualified RegExDot.Result import qualified System.Exit import qualified System.IO @@ -51,7 +51,7 @@ type LineNumber = Int type Matches = Int --- | Creates a 'RegExOpts.RegExOpts' record from 'CommandOptions.CommandOptions', and uses it to filter the lines read from the list of input-data files, the result of which is then printed.+-- | Creates a 'RegExDot.RegExOpts.RegExOpts' record from 'CommandOptions.CommandOptions', and uses it to filter the lines read from the list of input-data files, the result of which is then printed. grep :: CommandOptions.CommandOptions -- ^ The match-criteria, which may include the name of the file on which to operate. -> [String] -- ^ A supplementary list of files on which to operate@@ -107,9 +107,9 @@ if verbose then let- result :: RegEx.Result Char+ result :: RegExDot.RegEx.Result Char result = line +~ regExOpts- in if Result.isMatch result+ in if RegExDot.Result.isMatch result then if invertMatch then onFailure else onSuccess $ show result@@ -124,7 +124,7 @@ dummyFileName = "<standard input>" in matchFilterStdIn 0 0 >>= System.Exit.exitWith | otherwise {-file-names provided-} = let- findMatch :: String -> RegEx.Result Char+ findMatch :: String -> RegExDot.RegEx.Result Char findMatch = (+~ regExOpts) matchFilter :: [String] -> [String]@@ -142,14 +142,14 @@ then map ( Control.Arrow.second show ) . filter (- Result.isMatch . snd+ RegExDot.Result.isMatch . snd ) . map ( Control.Arrow.second findMatch ) else {-terse-} filter (isMatch . snd) ) . zip [1 :: LineNumber ..] else {-unnumbered-} if verbose- then map show . filter Result.isMatch . map findMatch+ then map show . filter RegExDot.Result.isMatch . map findMatch else {-terse-} filter isMatch ) @@ -199,11 +199,11 @@ | otherwise -> read . head &&& tail $ nonOptions --Combine the regex & options, to create a complete task-description.- regExOpts :: RegExOpts.RegExOpts ExtendedRegExChar.ExtendedRegExChar- regExOpts = RegExOpts.MkRegExOpts {- RegExOpts.compilationOptions = CommandOptions.compilationOptions commandOptions,- RegExOpts.executionOptions = CommandOptions.executionOptions commandOptions,- RegExOpts.regEx = extendedRegExChar+ regExOpts :: RegExDot.RegExOpts.RegExOpts ExtendedRegExChar.ExtendedRegExChar+ regExOpts = RegExDot.RegExOpts.MkRegExOpts {+ RegExDot.RegExOpts.compilationOptions = CommandOptions.compilationOptions commandOptions,+ RegExDot.RegExOpts.executionOptions = CommandOptions.executionOptions commandOptions,+ RegExDot.RegExOpts.regEx = extendedRegExChar } --Define functions used to format the output.
src/Grecce/Test/Assert/RegExOptsChar.hs view
@@ -47,8 +47,8 @@ import qualified Control.Arrow import qualified RegExChar.ExtendedRegExChar as ExtendedRegExChar import qualified RegExChar.RegExOptsChar as RegExOptsChar --CAVEAT: beware of the similar name.-import qualified RegExDot.CompilationOptions as CompilationOptions-import qualified RegExDot.ExecutionOptions as ExecutionOptions+import qualified RegExDot.CompilationOptions+import qualified RegExDot.ExecutionOptions import qualified Text.Regex.Base.RegexLike as RegexLike import qualified Text.Regex.Posix.Wrap import Text.Regex.Posix()@@ -67,7 +67,7 @@ isMatch regex (inputData, matchSpanList) = RegexLike.matchOnce regex inputData == Just (RegExOptsChar.toZeroIndexedArray matchSpanList) -- | Returns those 'Test's, which 'RegExOptsChar.RegExOptsChar' fails.-findFailures :: CompilationOptions.CompilationOptions -> ExecutionOptions.ExecutionOptions -> TestFilter+findFailures :: RegExDot.CompilationOptions.CompilationOptions -> RegExDot.ExecutionOptions.ExecutionOptions -> TestFilter findFailures compilationOptions executionOptions = filter (not . uncurry all . Control.Arrow.first (isMatch . RegexLike.makeRegexOpts compilationOptions executionOptions)) -- | Returns those 'Test's, which 'Text.Regex.Posix.Wrap.Regex' fails.@@ -83,7 +83,7 @@ readTests fileName = map ( \line -> case reads line of [(test, _)] -> test- _ -> error $ "Grecce.Test.Assert.RegExOptsChar.readTests:\tfailed to read 'Test' from '" ++ line ++ "'"+ _ -> error $ "Grecce.Test.Assert.RegExOptsChar.readTests:\tfailed to parse " ++ show fileName ++ "; " ++ show line ++ "." ) . filter ( (/= '#') . head --Remove comments. ) . filter (
src/Grecce/Test/Performance/ExtendedRegEx.hs view
@@ -28,7 +28,7 @@ [@CAVEATS@] * For compatibility with the other regex-engines, uses the specialised instance 'ExtendedRegExChar.ExtendedRegExChar',- rather than the underlying polymorphic 'RegEx.ExtendedRegEx'.+ rather than the underlying polymorphic 'RegExDot.RegEx.ExtendedRegEx'. * "Text.Regex.Posix" stalls forever on 'Performance.ExtendedRegExTestsPositive.OVERLAPPING_ALTERNATIVES', with 'Performance.ExtendedRegExTest.TestComplexity'=3 & data-capture requested.@@ -51,16 +51,16 @@ ) where import Control.Applicative((<$>), (<*>))-import Control.Arrow((&&&)) import qualified Control.Arrow+import Control.Arrow((&&&)) import qualified Data.Maybe import qualified Grecce.Test.Performance.ExtendedRegExTest as Test.Performance.ExtendedRegExTest import qualified Grecce.Test.Performance.ExtendedRegExTestsNegative as Test.Performance.ExtendedRegExTestsNegative import qualified Grecce.Test.Performance.ExtendedRegExTestsPositive as Test.Performance.ExtendedRegExTestsPositive import qualified RegExChar.ExtendedRegExChar as ExtendedRegExChar-import qualified RegExDot.ExecutionOptions as ExecutionOptions-import qualified RegExDot.RegEx as RegEx-import qualified RegExDot.RegExOpts as RegExOpts+import qualified RegExDot.ExecutionOptions+import qualified RegExDot.RegEx+import qualified RegExDot.RegExOpts import qualified Text.Regex.Posix import qualified ToolShed.Defaultable import qualified ToolShed.System.TimePure@@ -76,7 +76,7 @@ * If the specified maximum 'Test.Performance.ExtendedRegExTest.TestComplexity' is set to the special value '0', then it is increased linearly, without limit. -}-run :: ExecutionOptions.ExecutionOptions -> Test.Performance.ExtendedRegExTest.TestComplexity -> Either [Test.Performance.ExtendedRegExTestsNegative.TestName] [Test.Performance.ExtendedRegExTestsPositive.TestName] -> IO ()+run :: RegExDot.ExecutionOptions.ExecutionOptions -> Test.Performance.ExtendedRegExTest.TestComplexity -> Either [Test.Performance.ExtendedRegExTestsNegative.TestName] [Test.Performance.ExtendedRegExTestsPositive.TestName] -> IO () run executionOptions 0 testRange = run executionOptions maxBound testRange --Run the specified test-range, without any upper bound to 'Test.Performance.ExtendedRegExTest.TestComplexity'. run executionOptions maxTestComplexity (Left negativeTestRange) = runNegativeTestRange negativeTestRange where runNegativeTestRange :: GetAndRunTestRange Test.Performance.ExtendedRegExTestsNegative.TestName@@ -97,10 +97,10 @@ ) . Control.Arrow.second ( ( \extendedRegEx -> (- RegEx./~ RegExOpts.MkRegExOpts { --CAVEAT: <http://hackage.haskell.org/trac/haskell-prime/wiki/QualifiedOperators>.- RegExOpts.compilationOptions = ToolShed.Defaultable.defaultValue,- RegExOpts.executionOptions = executionOptions,- RegExOpts.regEx = extendedRegEx+ RegExDot.RegEx./~ RegExDot.RegExOpts.MkRegExOpts { --CAVEAT: <http://hackage.haskell.org/trac/haskell-prime/wiki/QualifiedOperators>.+ RegExDot.RegExOpts.compilationOptions = ToolShed.Defaultable.defaultValue,+ RegExDot.RegExOpts.executionOptions = executionOptions,+ RegExDot.RegExOpts.regEx = extendedRegEx } ) ) &&& show . ExtendedRegExChar.MkExtendedRegExChar False {-hasNonCapturingTopLevelAlternatives-}@@ -117,7 +117,7 @@ \(inputData, (showMatch, extendedRegExCharString)) -> (,) extendedRegExCharString <$> ( (ToolShed.System.TimePure.getCPUSeconds . ($ inputData)) `mapM` [ showMatch,- if ExecutionOptions.requireMatchList executionOptions+ if RegExDot.ExecutionOptions.requireMatchList executionOptions then if solitary then const "<untested>" -- else (Text.Regex.Posix.=~ extendedRegExCharString) :: String -> String --CAVEAT: <http://hackage.haskell.org/trac/haskell-prime/wiki/QualifiedOperators>.@@ -130,15 +130,15 @@ ) . Control.Arrow.second ( ( \extendedRegEx -> let- regExOpts :: RegExOpts.RegExOpts (RegEx.ExtendedRegEx Char)- regExOpts = RegExOpts.MkRegExOpts {- RegExOpts.compilationOptions = ToolShed.Defaultable.defaultValue,- RegExOpts.executionOptions = executionOptions,- RegExOpts.regEx = extendedRegEx+ regExOpts :: RegExDot.RegExOpts.RegExOpts (RegExDot.RegEx.ExtendedRegEx Char)+ regExOpts = RegExDot.RegExOpts.MkRegExOpts {+ RegExDot.RegExOpts.compilationOptions = ToolShed.Defaultable.defaultValue,+ RegExDot.RegExOpts.executionOptions = executionOptions,+ RegExDot.RegExOpts.regEx = extendedRegEx } --Similar to 'RegexLike.makeRegexOpts', but without the requirement to read the regex.- in if ExecutionOptions.requireMatchList executionOptions- then show . (RegEx.+~ regExOpts) --CAVEAT: <http://hackage.haskell.org/trac/haskell-prime/wiki/QualifiedOperators>.- else show . (RegEx.=~ regExOpts) --CAVEAT: <http://hackage.haskell.org/trac/haskell-prime/wiki/QualifiedOperators>.+ in if RegExDot.ExecutionOptions.requireMatchList executionOptions+ then show . (RegExDot.RegEx.+~ regExOpts) --CAVEAT: <http://hackage.haskell.org/trac/haskell-prime/wiki/QualifiedOperators>.+ else show . (RegExDot.RegEx.=~ regExOpts) --CAVEAT: <http://hackage.haskell.org/trac/haskell-prime/wiki/QualifiedOperators>. ) &&& show . ExtendedRegExChar.MkExtendedRegExChar False {-hasNonCapturingTopLevelAlternatives-} ) . testGenerator
src/Grecce/Test/Performance/ExtendedRegExTest.hs view
@@ -34,13 +34,13 @@ TestGenerator ) where -import qualified RegExDot.RegEx as RegEx+import qualified RegExDot.RegEx -- | Used to specify the level of complexity of /regex/ to generate. type TestComplexity = Int -- | A pair defining the data & the /regex/ to which it should be fed.-type Test a = (RegEx.InputData a, RegEx.ExtendedRegEx a)+type Test a = (RegExDot.RegEx.InputData a, RegExDot.RegEx.ExtendedRegEx a) -- | The type of a function, which accepts a 'TestComplexity', & returns a 'Test'. type TestGenerator a = TestComplexity -> Test a
src/Grecce/Test/Performance/ExtendedRegExTestsPositive.hs view
@@ -35,13 +35,13 @@ import Control.Arrow((&&&)) import qualified Data.Char import qualified Grecce.Test.Performance.ExtendedRegExTest as Test.Performance.ExtendedRegExTest-import qualified RegExDot.Anchor as Anchor-import qualified RegExDot.BracketExpressionMember as BracketExpressionMember-import qualified RegExDot.Meta as Meta-import qualified RegExDot.RegEx as RegEx-import qualified RegExDot.Repeatable as Repeatable+import qualified RegExDot.Anchor+import qualified RegExDot.BracketExpressionMember import RegExDot.DSL((-:), (?:), (*:), (<~>))+import qualified RegExDot.Meta+import qualified RegExDot.RegEx import RegExDot.RegEx((.*), (.*?))+import qualified RegExDot.Repeatable import RegExDot.Repeatable((^#->#), (^#->), (^#)) -- | Defines an enumeration of keys, by which to reference 'Test.Performance.ExtendedRegExTest.TestGenerator's.@@ -79,9 +79,9 @@ ( BIPOLAR_GREEDY_OPTIONAL_VS_MANDATORY, (`replicate` testChar) &&& let- exactly :: Test.Performance.ExtendedRegExTest.TestComplexity -> (RegEx.Pattern Char -> RegEx.RepeatablePattern Char) -> RegEx.RepeatablePattern Char- exactly n f = (RegEx.captureGroup . map ((Nothing, Nothing) <~>) . return {-to List-monad-} . return {-to List-monad-} $ f testRequirement) ^# n- in ((Just Anchor.Bow, Just Anchor.Stern) <~>) . (`map` [Repeatable.zeroOrOne, Repeatable.one]) . exactly+ exactly :: Test.Performance.ExtendedRegExTest.TestComplexity -> (RegExDot.RegEx.Pattern Char -> RegExDot.RegEx.RepeatablePattern Char) -> RegExDot.RegEx.RepeatablePattern Char+ exactly n f = (RegExDot.RegEx.captureGroup . map (RegExDot.Anchor.unanchored <~>) . return {-to List-monad-} . return {-to List-monad-} $ f testRequirement) ^# n+ in ((Just RegExDot.Anchor.Bow, Just RegExDot.Anchor.Stern) <~>) . (`map` [RegExDot.Repeatable.zeroOrOne, RegExDot.Repeatable.one]) . exactly ), {- "^(.*z){<complexity>}$".@@ -90,10 +90,10 @@ -} ( INTERLEAVED_GREEDY_STAR_VS_MANDATORY,- concat . (`replicate` (testChar : "z")) &&& RegEx.dock . (- `mkExtendedRegExFromRepeatableSingletonAlternative` ((Nothing, Nothing) <~>) [+ concat . (`replicate` (testChar : "z")) &&& RegExDot.RegEx.dock . (+ `mkExtendedRegExFromRepeatableSingletonAlternative` (RegExDot.Anchor.unanchored <~>) [ (.*),- RegEx.simply $ Meta.Literal 'z'+ RegExDot.RegEx.simply $ RegExDot.Meta.Literal 'z' ] ) . flip (^#) ),@@ -106,7 +106,7 @@ ( TRIANGULAR_CONSUMPTION,- (`replicate` testChar) . triangularSeries &&& ((Just Anchor.Bow, Just Anchor.Stern) <~>) . (`take` map (testRequirement ^#->) [0 ..]) . succ+ (`replicate` testChar) . triangularSeries &&& ((Just RegExDot.Anchor.Bow, Just RegExDot.Anchor.Stern) <~>) . (`take` map (testRequirement ^#->) [0 ..]) . succ ), {- "(<testChar>|<testChar>{2})*c".@@ -116,11 +116,11 @@ ( BINARY_TREE, (++ "bc") . (`replicate` testChar) . (2 ^) &&& const (- (Nothing, Nothing) <~> RegEx.captureGroup (+ RegExDot.Anchor.unanchored <~> RegExDot.RegEx.captureGroup ( map (- ((Nothing, Nothing) <~>) . return {-to List-monad-} . (testRequirement ^#) . (2 ^)+ (RegExDot.Anchor.unanchored <~>) . return {-to List-monad-} . (testRequirement ^#) . (2 ^) ) [0 :: Int .. 1]- ) *: RegEx.Require (Meta.Literal 'c') -: []+ ) *: RegExDot.RegEx.Require (RegExDot.Meta.Literal 'c') -: [] ) ), {-@@ -133,7 +133,7 @@ ( REPEATABLE_ALTERNATIVES, (`replicate` testChar) . pred {-requires several different Alternatives-} . (2 ^) &&& (- \i -> ((Just Anchor.Bow, Just Anchor.Stern) <~>) . return {-to List-monad-} . Repeatable.zeroOrMore . RegEx.captureGroup . map ((Nothing, Nothing) <~>) $ [Repeatable.zeroOrOne testRequirement] : map (+ \i -> ((Just RegExDot.Anchor.Bow, Just RegExDot.Anchor.Stern) <~>) . return {-to List-monad-} . RegExDot.Repeatable.zeroOrMore . RegExDot.RegEx.captureGroup . map (RegExDot.Anchor.unanchored <~>) $ [RegExDot.Repeatable.zeroOrOne testRequirement] : map ( return {-to List-monad-} . (testRequirement ^#) . (2 ^) ) [1 .. i] )@@ -147,7 +147,7 @@ ( REPEATED_ALTERNATIVES, (`replicate` testChar) . pred {-requires several different Alternatives-} . (2 ^) &&& (- \i -> ((Just Anchor.Bow, Just Anchor.Stern) <~>) . replicate i . Repeatable.one . RegEx.captureGroup . map ((Nothing, Nothing) <~>) $ [Repeatable.zeroOrOne testRequirement] : map (+ \i -> ((Just RegExDot.Anchor.Bow, Just RegExDot.Anchor.Stern) <~>) . replicate i . RegExDot.Repeatable.one . RegExDot.RegEx.captureGroup . map (RegExDot.Anchor.unanchored <~>) $ [RegExDot.Repeatable.zeroOrOne testRequirement] : map ( return {-to List-monad-} . (testRequirement ^#) . (2 ^) ) [1 .. i] )@@ -161,49 +161,49 @@ ( LINEAR_FRACTAL_RANGES, let- base :: Repeatable.Repetitions+ base :: RegExDot.Repeatable.Repetitions base = 2 --Arbitrarily. - bounds :: Repeatable.RepetitionBounds+ bounds :: RegExDot.Repeatable.RepetitionBounds bounds = (0, Just base)- in (`replicate` testChar) . (base ^) &&& RegEx.dock . (+ in (`replicate` testChar) . (base ^) &&& RegExDot.RegEx.dock . ( (- mkExtendedRegExFromRepeatableSingletonAlternative (^#-># bounds) `iterate` ((Nothing, Nothing) <~>) [testRequirement ^#-># bounds] {-initial value-}+ mkExtendedRegExFromRepeatableSingletonAlternative (^#-># bounds) `iterate` (RegExDot.Anchor.unanchored <~>) [testRequirement ^#-># bounds] {-initial value-} ) !! ) . pred ), {- "^((((((((((((((<testChar>*?)*?)*?)*?)*?)*?)*?)*?)*?)*?)*?)*?)*?)*?)*? ... $".- Explanation: interesting because all 'RegEx.Alternatives' are expanded before the first comparison against input data, & the number possible repetitions of each expansion is very vague.+ Explanation: interesting because all 'RegExDot.RegEx.Alternatives' are expanded before the first comparison against input data, & the number possible repetitions of each expansion is very vague. Performance: vastly better Boolean-result performance than "Text.Regex.Posix", but inferior data-capture performance. -} ( LINEAR_FRACTAL_NONGREEDY_STAR,- const (replicate 8 {-arbitrary-} testChar) &&& RegEx.dock . (+ const (replicate 8 {-arbitrary-} testChar) &&& RegExDot.RegEx.dock . ( (- mkExtendedRegExFromRepeatableSingletonAlternative Repeatable.zeroOrMore' `iterate` ((Nothing, Nothing) <~>) [Repeatable.zeroOrMore' testRequirement] {-initial value-}+ mkExtendedRegExFromRepeatableSingletonAlternative RegExDot.Repeatable.zeroOrMore' `iterate` (RegExDot.Anchor.unanchored <~>) [RegExDot.Repeatable.zeroOrMore' testRequirement] {-initial value-} ) !! ) ), {- "^((([^<testChar>]|<testChar>)|(<testChar>|[^<testChar>]))|((<testChar>|[^<testChar>])|([^<testChar>]|<testChar>)))$".- Explanation: exhibits symmetry in the left & right branches of the binary tree of RegEx.Alternatives, & so the exponentially expanding set of leaves are equivalent & all match the data.+ Explanation: exhibits symmetry in the left & right branches of the binary tree of RegExDot.RegEx.Alternatives, & so the exponentially expanding set of leaves are equivalent & all match the data. Performance: vastly better Boolean-result & comparable data.capture performance to "Text.Regex.Posix", which exhausts memory at complexity 5 to 6, & to egrep which lasts until complexity==6. -} ( BINARY_TREE_FRACTAL, let- base :: Repeatable.Repetitions+ base :: RegExDot.Repeatable.Repetitions base = 2 --Arbitrarily.- in (`replicate` testChar) . (base ^) &&& RegEx.dock . head . (+ in (`replicate` testChar) . (base ^) &&& RegExDot.RegEx.dock . head . ( ( iterate ( \extendedRegExList -> (- ((Nothing, Nothing) <~>) . return {-to List-monad-} . (^# base) . RegEx.captureGroup+ (RegExDot.Anchor.unanchored <~>) . return {-to List-monad-} . (^# base) . RegExDot.RegEx.captureGroup ) `map` [extendedRegExList, reverse extendedRegExList] ) $ map (- ((Nothing, Nothing) <~>) . return {-to List-monad-} . ($ RegEx.Require $ Meta.Literal testChar)- ) [Repeatable.one, Repeatable.zeroOrOne]+ (RegExDot.Anchor.unanchored <~>) . return {-to List-monad-} . ($ RegExDot.RegEx.Require $ RegExDot.Meta.Literal testChar)+ ) [RegExDot.Repeatable.one, RegExDot.Repeatable.zeroOrOne] ) !! ) ),@@ -216,11 +216,11 @@ FUTILE_REPEATABLE_ALTERNATIVES, \alternatives -> ( replicate 1024 {-arbitrarily-} testChar,- ((Just Anchor.Bow, Just Anchor.Stern) <~>) $ map Repeatable.zeroOrMore [- RegEx.captureGroup . map ((Nothing, Nothing) <~>) $ (+ ((Just RegExDot.Anchor.Bow, Just RegExDot.Anchor.Stern) <~>) $ map RegExDot.Repeatable.zeroOrMore [+ RegExDot.RegEx.captureGroup . map (RegExDot.Anchor.unanchored <~>) $ ( \i -> ($ i) `map` [ (testRequirement ^#),- RegEx.simply . Meta.Literal . Data.Char.chr . (Data.Char.ord '0' +) . (`mod` 10)+ RegExDot.RegEx.simply . RegExDot.Meta.Literal . Data.Char.chr . (Data.Char.ord '0' +) . (`mod` 10) ] ) `map` [1 .. alternatives], testRequirement@@ -243,16 +243,16 @@ bracket :: a -> [a] -> [a] bracket terminal = (terminal :) . (++ [terminal]) - zeroOrMoreAlternatives :: [RegEx.Concatenation Char] -> RegEx.Concatenation Char- zeroOrMoreAlternatives = return {-to List-monad-} . Repeatable.zeroOrMore . RegEx.captureGroup . map ((Nothing, Nothing) <~>)+ zeroOrMoreAlternatives :: [RegExDot.RegEx.Concatenation Char] -> RegExDot.RegEx.Concatenation Char+ zeroOrMoreAlternatives = return {-to List-monad-} . RegExDot.Repeatable.zeroOrMore . RegExDot.RegEx.captureGroup . map (RegExDot.Anchor.unanchored <~>) in ( id &&& (- ((Just Anchor.Bow, Just Anchor.Stern) <~>) . (RegEx.Require (Meta.Literal testChar) ?:) . zeroOrMoreAlternatives . map (+ ((Just RegExDot.Anchor.Bow, Just RegExDot.Anchor.Stern) <~>) . (RegExDot.RegEx.Require (RegExDot.Meta.Literal testChar) ?:) . zeroOrMoreAlternatives . map ( \(a, b) -> zeroOrMoreAlternatives $ return {-to List-monad-} [a, b] ) . init . tail . uncurry zip . (- map Repeatable.one . init &&& map Repeatable.zeroOrOne . tail+ map RegExDot.Repeatable.one . init &&& map RegExDot.Repeatable.zeroOrOne . tail ) . bracket undefined . map (- RegEx.Require . Meta.Literal+ RegExDot.RegEx.Require . RegExDot.Meta.Literal ) ) ) . (`take` (filter Data.Char.isAlphaNum $ filter Data.Char.isAscii [minBound .. maxBound])) . succ@@ -274,13 +274,13 @@ testSet = take complexity' . filter Data.Char.isAlphaNum $ filter Data.Char.isAscii [minBound .. maxBound] in ( concat $ replicate complexity' testSet,- ((Just Anchor.Bow, Just Anchor.Stern) <~>) $ (- RegEx.captureGroup . map ((Nothing, Nothing) <~>) $ map (- return {-to List-monad-} . RegEx.simply . Meta.Literal+ ((Just RegExDot.Anchor.Bow, Just RegExDot.Anchor.Stern) <~>) $ (+ RegExDot.RegEx.captureGroup . map (RegExDot.Anchor.unanchored <~>) $ map (+ return {-to List-monad-} . RegExDot.RegEx.simply . RegExDot.Meta.Literal ) testSet ) *: [ (- RegEx.captureGroup . map ((Nothing, Nothing) <~>) . return {-to List-monad-} $ RegEx.Require (Meta.Literal $ head testSet) -: (.*?) : RegEx.Require (Meta.Literal $ last testSet) -: []+ RegExDot.RegEx.captureGroup . map (RegExDot.Anchor.unanchored <~>) . return {-to List-monad-} $ RegExDot.RegEx.Require (RegExDot.Meta.Literal $ head testSet) -: (.*?) : RegExDot.RegEx.Require (RegExDot.Meta.Literal $ last testSet) -: [] ) ^# complexity' ] )@@ -295,13 +295,13 @@ ( MULTIPLE_CHOICE, const (replicate 8 {-arbitrary-} testChar) &&& (- ((Just Anchor.Bow, Just Anchor.Stern) <~>) . return {-to List-monad-} . Repeatable.zeroOrMore . RegEx.captureGroup . map ((Nothing, Nothing) <~>) . (+ ((Just RegExDot.Anchor.Bow, Just RegExDot.Anchor.Stern) <~>) . return {-to List-monad-} . RegExDot.Repeatable.zeroOrMore . RegExDot.RegEx.captureGroup . map (RegExDot.Anchor.unanchored <~>) . ( [- Repeatable.zeroOrMore testRequirement,- RegEx.simply . Meta.NoneOf $ map BracketExpressionMember.Literal [testChar]+ RegExDot.Repeatable.zeroOrMore testRequirement,+ RegExDot.RegEx.simply . RegExDot.Meta.NoneOf $ map RegExDot.BracketExpressionMember.Literal [testChar] ] : ) . map (- return {-to List-monad-} . RegEx.simply . Meta.NoneOf . return {-to List-monad-} . BracketExpressionMember.Literal+ return {-to List-monad-} . RegExDot.RegEx.simply . RegExDot.Meta.NoneOf . return {-to List-monad-} . RegExDot.BracketExpressionMember.Literal ) . ( `take` tail [testChar ..] )@@ -312,11 +312,11 @@ testChar :: Char testChar = 'a' - testRequirement :: RegEx.Pattern Char- testRequirement = RegEx.Require $ Meta.Literal testChar+ testRequirement :: RegExDot.RegEx.Pattern Char+ testRequirement = RegExDot.RegEx.Require $ RegExDot.Meta.Literal testChar - mkExtendedRegExFromRepeatableSingletonAlternative :: (RegEx.Pattern Char -> RegEx.RepeatablePattern Char) -> RegEx.ExtendedRegEx Char -> RegEx.ExtendedRegEx Char- mkExtendedRegExFromRepeatableSingletonAlternative makeRepetitions = ((Nothing, Nothing) <~>) . return {-to List-monad-} . makeRepetitions . RegEx.captureGroup . return {-to List-monad-}+ mkExtendedRegExFromRepeatableSingletonAlternative :: (RegExDot.RegEx.Pattern Char -> RegExDot.RegEx.RepeatablePattern Char) -> RegExDot.RegEx.ExtendedRegEx Char -> RegExDot.RegEx.ExtendedRegEx Char+ mkExtendedRegExFromRepeatableSingletonAlternative makeRepetitions = (RegExDot.Anchor.unanchored <~>) . return {-to List-monad-} . makeRepetitions . RegExDot.RegEx.captureGroup . return {-to List-monad-} {- | * The sum of the sequence descending from the specified integer; @n + (n - 1) + (n - 2) + ... + 2 + 1 + 0@.
src/Grecce/Test/QC/ExtendedRegExChar.hs view
@@ -38,41 +38,43 @@ ) where import Control.Applicative((<$>))+import qualified Data.Maybe import Grecce.Test.QC.MetaChar()-import qualified RegExChar.ExtendedRegExChar as ExtendedRegExChar --CAVEAT: beware of the similar name.-import qualified RegExChar.MetaChar as MetaChar-import qualified RegExDot.Anchor as Anchor-import qualified RegExDot.BracketExpressionMember as BracketExpressionMember-import qualified RegExDot.Consumer as Consumer-import qualified RegExDot.ConsumptionBounds as ConsumptionBounds-import qualified RegExDot.ConsumptionProfile as ConsumptionProfile-import qualified RegExDot.Meta as Meta-import qualified RegExDot.RegEx as RegEx-import qualified RegExDot.RegExOpts as RegExOpts-import qualified RegExDot.Repeatable as Repeatable-import qualified RegExDot.Result as Result+import qualified RegExChar.ExtendedRegExChar as ExtendedRegExChar --CAVEAT: beware of the similar name.+import qualified RegExChar.MetaChar as MetaChar+import qualified RegExDot.Anchor+import qualified RegExDot.BracketExpressionMember+import qualified RegExDot.Consumer+import qualified RegExDot.ConsumptionBounds+import qualified RegExDot.ConsumptionProfile import RegExDot.DSL((-:), (?:), (+:), (<~>))+import qualified RegExDot.Meta+import qualified RegExDot.RegEx import RegExDot.RegEx((+~))+import qualified RegExDot.RegExOpts+import qualified RegExDot.Repeatable+import qualified RegExDot.Result import qualified Test.QuickCheck import Test.QuickCheck((==>)) import qualified ToolShed.SelfValidate+import qualified ToolShed.Test.ReversibleIO -- | A specialised instance, required to instantiate 'Test.QuickCheck.Arbitrary'.-newtype AlternativesChar = MkAlternativesChar (RegEx.Alternatives Char) deriving (Eq, Read, Show)+newtype AlternativesChar = MkAlternativesChar (RegExDot.RegEx.Alternatives Char) deriving (Eq, Read, Show) -- | Accessor.-deconstructAlternativesChar :: AlternativesChar -> RegEx.Alternatives Char+deconstructAlternativesChar :: AlternativesChar -> RegExDot.RegEx.Alternatives Char deconstructAlternativesChar (MkAlternativesChar a) = a instance ToolShed.SelfValidate.SelfValidator AlternativesChar where getErrors = ToolShed.SelfValidate.getErrors . deconstructAlternativesChar -instance Consumer.Consumer AlternativesChar where- consumptionProfile = Consumer.consumptionProfile . deconstructAlternativesChar- starHeight = Consumer.starHeight . deconstructAlternativesChar+instance RegExDot.Consumer.Consumer AlternativesChar where+ consumptionProfile = RegExDot.Consumer.consumptionProfile . deconstructAlternativesChar+ starHeight = RegExDot.Consumer.starHeight . deconstructAlternativesChar instance Test.QuickCheck.Arbitrary AlternativesChar where- arbitrary = MkAlternativesChar . RegEx.MkAlternatives . map ExtendedRegExChar.extendedRegEx <$> (+ arbitrary = MkAlternativesChar . RegExDot.RegEx.MkAlternatives . map ExtendedRegExChar.extendedRegEx <$> ( Test.QuickCheck.elements [1, 2] >>= Test.QuickCheck.vector {-[ExtendedRegExChar]-} ) --TODO: permit zero alternatives. #if !(MIN_VERSION_QuickCheck(2,1,0))@@ -80,41 +82,41 @@ #endif -- | A specialised instance, required to instantiate 'Test.QuickCheck.Arbitrary'.-newtype PatternChar = MkPatternChar (RegEx.Pattern Char) deriving (Eq, Read, Show)+newtype PatternChar = MkPatternChar (RegExDot.RegEx.Pattern Char) deriving (Eq, Read, Show) -- | Accessor.-deconstructPatternChar :: PatternChar -> RegEx.Pattern Char+deconstructPatternChar :: PatternChar -> RegExDot.RegEx.Pattern Char deconstructPatternChar (MkPatternChar pattern) = pattern instance ToolShed.SelfValidate.SelfValidator PatternChar where getErrors = ToolShed.SelfValidate.getErrors . deconstructPatternChar -instance Consumer.Consumer PatternChar where- consumptionProfile = Consumer.consumptionProfile . deconstructPatternChar- starHeight = Consumer.starHeight . deconstructPatternChar+instance RegExDot.Consumer.Consumer PatternChar where+ consumptionProfile = RegExDot.Consumer.consumptionProfile . deconstructPatternChar+ starHeight = RegExDot.Consumer.starHeight . deconstructPatternChar instance Test.QuickCheck.Arbitrary PatternChar where arbitrary = MkPatternChar <$> Test.QuickCheck.frequency [- (4, RegEx.Require . MetaChar.deconstruct <$> Test.QuickCheck.arbitrary {-MetaChar-}),- (1, RegEx.CaptureGroup . deconstructAlternativesChar <$> Test.QuickCheck.arbitrary {-AlternativesChar-})- ] --CAVEAT: may recurse forever if 'RegEx.CaptureGroup / RegEx.Require' is too high.+ (4, RegExDot.RegEx.Require . MetaChar.deconstruct <$> Test.QuickCheck.arbitrary {-MetaChar-}),+ (1, RegExDot.RegEx.CaptureGroup . deconstructAlternativesChar <$> Test.QuickCheck.arbitrary {-AlternativesChar-})+ ] --CAVEAT: may recurse forever if 'RegExDot.RegEx.CaptureGroup / RegExDot.RegEx.Require' is too high. #if ! (MIN_VERSION_QuickCheck(2,1,0)) coarbitrary = undefined --CAVEAT: stops warnings from ghc. #endif -- | A specialised instance, required to instantiate 'Test.QuickCheck.Arbitrary'.-newtype RepeatablePatternChar = MkRepeatablePatternChar (Repeatable.Repeatable PatternChar) deriving (Eq, Read, Show)+newtype RepeatablePatternChar = MkRepeatablePatternChar (RegExDot.Repeatable.Repeatable PatternChar) deriving (Eq, Read, Show) -- | Accessor.-deconstructRepeatablePatternChar :: RepeatablePatternChar -> Repeatable.Repeatable PatternChar+deconstructRepeatablePatternChar :: RepeatablePatternChar -> RegExDot.Repeatable.Repeatable PatternChar deconstructRepeatablePatternChar (MkRepeatablePatternChar repeatable) = repeatable instance ToolShed.SelfValidate.SelfValidator RepeatablePatternChar where getErrors = ToolShed.SelfValidate.getErrors . deconstructRepeatablePatternChar -instance Consumer.Consumer RepeatablePatternChar where- consumptionProfile = Consumer.consumptionProfile . deconstructRepeatablePatternChar- starHeight = Consumer.starHeight . deconstructRepeatablePatternChar+instance RegExDot.Consumer.Consumer RepeatablePatternChar where+ consumptionProfile = RegExDot.Consumer.consumptionProfile . deconstructRepeatablePatternChar+ starHeight = RegExDot.Consumer.starHeight . deconstructRepeatablePatternChar instance Test.QuickCheck.Arbitrary RepeatablePatternChar where arbitrary = do@@ -124,13 +126,13 @@ isGreedy <- Test.QuickCheck.arbitrary {-Bool-} let- repetitionBounds :: Repeatable.RepetitionBounds+ repetitionBounds :: RegExDot.Repeatable.RepetitionBounds repetitionBounds = (fewest, most) - return {-to Gen-monad-} $ MkRepeatablePatternChar Repeatable.MkRepeatable {- Repeatable.base = patternChar,- Repeatable.repetitionBounds = repetitionBounds,- Repeatable.isGreedy = Repeatable.hasPreciseBounds repetitionBounds || isGreedy --Only specify non-greedy where space exists.+ return {-to Gen-monad-} $ MkRepeatablePatternChar RegExDot.Repeatable.MkRepeatable {+ RegExDot.Repeatable.base = patternChar,+ RegExDot.Repeatable.repetitionBounds = repetitionBounds,+ RegExDot.Repeatable.isGreedy = RegExDot.Repeatable.hasPreciseBounds repetitionBounds || isGreedy --Only specify non-greedy where space exists. } #if ! (MIN_VERSION_QuickCheck(2,1,0)) coarbitrary = undefined --CAVEAT: stops warnings from ghc.@@ -139,13 +141,13 @@ instance Test.QuickCheck.Arbitrary ExtendedRegExChar.ExtendedRegExChar where arbitrary = do hasBowAnchor <- Test.QuickCheck.arbitrary {-Bool-}- concatenation <- map ((deconstructPatternChar <$> {-replace base-}) . deconstructRepeatablePatternChar {-Repeatable.Repeatable PatternChar-}) <$> Test.QuickCheck.vector 2 {-[RepeatablePatternChar]-}+ concatenation <- map ((deconstructPatternChar <$> {-replace base-}) . deconstructRepeatablePatternChar {-RegExDot.Repeatable.Repeatable PatternChar-}) <$> Test.QuickCheck.vector 2 {-[RepeatablePatternChar]-} hasSternAnchor <- Test.QuickCheck.arbitrary {-Bool-} - return {-to Gen-monad-} $ ExtendedRegExChar.MkExtendedRegExChar False RegEx.MkExtendedRegEx {- RegEx.bowAnchor = if hasBowAnchor then Just Anchor.Bow else Nothing,- RegEx.concatenation = concatenation,- RegEx.sternAnchor = if hasSternAnchor then Just Anchor.Stern else Nothing+ return {-to Gen-monad-} $ ExtendedRegExChar.MkExtendedRegExChar False RegExDot.RegEx.MkExtendedRegEx {+ RegExDot.RegEx.bowAnchor = if hasBowAnchor then Just RegExDot.Anchor.Bow else Nothing,+ RegExDot.RegEx.concatenation = concatenation,+ RegExDot.RegEx.sternAnchor = if hasSternAnchor then Just RegExDot.Anchor.Stern else Nothing } #if ! (MIN_VERSION_QuickCheck(2,1,0))@@ -159,47 +161,43 @@ quickChecks checker = quickChecks1 >> quickChecks2 where quickChecks1 = checker `mapM_` [prop_consumptionProfile, prop_consumptionProfile2, prop_io, prop_io', prop_isValid, prop_starHeight] where prop_consumptionProfile, prop_consumptionProfile2, prop_io, prop_io', prop_isValid, prop_starHeight :: Testable- prop_consumptionProfile r = Test.QuickCheck.label "prop_consumptionProfile" $ (- case maybeMaxData of- Nothing -> True- Just m -> m >= minData- ) && (- not b == all (not . Consumer.getHasSpecificRequirement) (RegEx.concatenation $ ExtendedRegExChar.extendedRegEx r)+ prop_consumptionProfile r = Test.QuickCheck.label "prop_consumptionProfile" $ Data.Maybe.maybe True (>= minData) maybeMaxData && (+ not b == all (not . RegExDot.Consumer.getHasSpecificRequirement) (RegExDot.RegEx.concatenation $ ExtendedRegExChar.extendedRegEx r) ) where- ConsumptionProfile.MkConsumptionProfile {- ConsumptionProfile.consumptionBounds = (minData, maybeMaxData),- ConsumptionProfile.hasSpecificRequirement = b- } = Consumer.consumptionProfile r+ RegExDot.ConsumptionProfile.MkConsumptionProfile {+ RegExDot.ConsumptionProfile.consumptionBounds = (minData, maybeMaxData),+ RegExDot.ConsumptionProfile.hasSpecificRequirement = b+ } = RegExDot.Consumer.consumptionProfile r - prop_consumptionProfile2 r = RegEx.isDefined (ExtendedRegExChar.extendedRegEx r) ==> Test.QuickCheck.label "prop_consumptionProfile2" $ or [hasSpecificRequirement, canConsumeAnything] --There's either; a requirement for at least one specific, or we can consume at least one arbitrary; input datum.+ prop_consumptionProfile2 r = RegExDot.RegEx.isDefined (ExtendedRegExChar.extendedRegEx r) ==> Test.QuickCheck.label "prop_consumptionProfile2" $ or [hasSpecificRequirement, canConsumeAnything] --There's either; a requirement for at least one specific, or we can consume at least one arbitrary; input datum. where- ConsumptionProfile.MkConsumptionProfile {- ConsumptionProfile.hasSpecificRequirement = hasSpecificRequirement,- ConsumptionProfile.canConsumeAnything = canConsumeAnything- } = Consumer.consumptionProfile r+ RegExDot.ConsumptionProfile.MkConsumptionProfile {+ RegExDot.ConsumptionProfile.hasSpecificRequirement = hasSpecificRequirement,+ RegExDot.ConsumptionProfile.canConsumeAnything = canConsumeAnything+ } = RegExDot.Consumer.consumptionProfile r - prop_io r = Test.QuickCheck.label "prop_io" $ read (show r) == r- prop_io' r = Test.QuickCheck.label "prop_io'" $ read (show r') == r' where r' = ExtendedRegExChar.extendedRegEx r --Check "RegEx.ExtendedRegEx Char" too.+ prop_io = Test.QuickCheck.label "prop_io" . ToolShed.Test.ReversibleIO.isReversible+ prop_io' r = Test.QuickCheck.label "prop_io'" $ ToolShed.Test.ReversibleIO.isReversible r' where r' = ExtendedRegExChar.extendedRegEx r --Check "RegExDot.RegEx.ExtendedRegEx Char" too. prop_isValid r = Test.QuickCheck.label "prop_isValid" $ ToolShed.SelfValidate.isValid r- prop_starHeight r = Test.QuickCheck.label "prop_starHeight" $ (Consumer.starHeight r == 0) == ConsumptionBounds.isPrecise (Consumer.getConsumptionBounds r)+ prop_starHeight r = Test.QuickCheck.label "prop_starHeight" $ (RegExDot.Consumer.starHeight r == 0) == RegExDot.ConsumptionBounds.isPrecise (RegExDot.Consumer.getConsumptionBounds r) quickChecks2 = Test.QuickCheck.quickCheck {-'checker' is technically the wrong type-} `mapM_` [prop_double] where prop_double :: Double -> Test.QuickCheck.Property- prop_double d = Test.QuickCheck.label "prop_double" $ RegEx.extractDataFromMatchList `fmap` Result.getMatchList result == Just s where+ prop_double d = Test.QuickCheck.label "prop_double" $ RegExDot.RegEx.extractDataFromMatchList `fmap` RegExDot.Result.getMatchList result == Just s where s :: String s = show $ d * 1e6 --Implementation of show, uses exponential notation, when the number is large. - result :: RegEx.Result Char- result = s +~ RegExOpts.mkRegEx (- (Just Anchor.Bow, Just Anchor.Stern) <~> sign ?: digits +: map (- Repeatable.zeroOrOne . RegEx.captureGroup . map ((Nothing, Nothing) <~>) . return {-to List-monad-}+ result :: RegExDot.RegEx.Result Char+ result = s +~ RegExDot.RegExOpts.mkRegEx (+ (Just RegExDot.Anchor.Bow, Just RegExDot.Anchor.Stern) <~> sign ?: digits +: map (+ RegExDot.Repeatable.zeroOrOne . RegExDot.RegEx.captureGroup . map (RegExDot.Anchor.unanchored <~>) . return {-to List-monad-} ) [- RegEx.Require (Meta.Literal '.') -: digits +: [],- RegEx.Require (Meta.AnyOf $ map BracketExpressionMember.Literal "eE") -: sign ?: digits +: []+ RegExDot.RegEx.Require (RegExDot.Meta.Literal '.') -: digits +: [],+ RegExDot.RegEx.Require (RegExDot.Meta.AnyOf $ map RegExDot.BracketExpressionMember.Literal "eE") -: sign ?: digits +: [] ] ) where- sign, digits :: RegEx.Pattern Char- sign = RegEx.Require . Meta.AnyOf $ map BracketExpressionMember.Literal "+-"- digits = RegEx.Require . Meta.AnyOf $ map BracketExpressionMember.Literal ['0' .. '9']+ sign, digits :: RegExDot.RegEx.Pattern Char+ sign = RegExDot.RegEx.Require . RegExDot.Meta.AnyOf $ map RegExDot.BracketExpressionMember.Literal "+-"+ digits = RegExDot.RegEx.Require . RegExDot.Meta.AnyOf $ map RegExDot.BracketExpressionMember.Literal ['0' .. '9']
src/Grecce/Test/QC/MetaChar.hs view
@@ -36,11 +36,12 @@ import Control.Applicative((<$>)) import qualified Data.List-import qualified RegExChar.MetaChar as MetaChar --CAVEAT: beware of the similar name.-import qualified RegExDot.BracketExpression as BracketExpression-import qualified RegExDot.BracketExpressionMember as BracketExpressionMember-import qualified RegExDot.Meta as Meta+import qualified RegExChar.MetaChar as MetaChar --CAVEAT: beware of the similar name.+import qualified RegExDot.BracketExpression+import qualified RegExDot.BracketExpressionMember+import qualified RegExDot.Meta import qualified Test.QuickCheck+import qualified ToolShed.Test.ReversibleIO -- CAVEAT: module "Test.QuickCheck.Arbitrary" defines an instance of this from package "Quickcheck-2.1.0.1". #if !(MIN_VERSION_QuickCheck(2,1,0))@@ -50,14 +51,14 @@ #endif testCharacters :: String-testCharacters = filter (`notElem` [Meta.shortcutToken, BracketExpression.negationToken]) [' ' .. '~'] --TODO: permit all characters.+testCharacters = filter (`notElem` [RegExDot.Meta.shortcutToken, RegExDot.BracketExpression.negationToken]) [' ' .. '~'] --TODO: permit all characters. instance Test.QuickCheck.Arbitrary MetaChar.MetaChar where arbitrary = Test.QuickCheck.oneof $ map (MetaChar.MkMetaChar <$>) [- return {-to Gen-monad-} Meta.Any,- Meta.Literal <$> Test.QuickCheck.elements testCharacters,- Meta.AnyOf . map BracketExpressionMember.Literal . Data.List.nub <$> arbitraryCharList 1 16, --Test.QuickCheck.vector 16 {-Char-},- Meta.NoneOf . map BracketExpressionMember.Literal . Data.List.nub <$> arbitraryCharList 1 4+ return {-to Gen-monad-} RegExDot.Meta.Any,+ RegExDot.Meta.Literal <$> Test.QuickCheck.elements testCharacters,+ RegExDot.Meta.AnyOf . map RegExDot.BracketExpressionMember.Literal . Data.List.nub <$> arbitraryCharList 1 16, --Test.QuickCheck.vector 16 {-Char-},+ RegExDot.Meta.NoneOf . map RegExDot.BracketExpressionMember.Literal . Data.List.nub <$> arbitraryCharList 1 4 ] where arbitraryCharList :: Int -> Int -> Test.QuickCheck.Gen String arbitraryCharList i j = do@@ -74,5 +75,5 @@ quickChecks :: (Testable -> IO ()) -> IO () quickChecks checker = checker `mapM_` [prop_io] where prop_io :: Testable- prop_io m = Test.QuickCheck.label "prop_io" $ read (show m) == m+ prop_io = Test.QuickCheck.label "prop_io" . ToolShed.Test.ReversibleIO.isReversible
src/Grecce/Test/QC/RepeatableMetaChar.hs view
@@ -35,27 +35,28 @@ import qualified Data.Maybe import Control.Applicative((<$>)) import Grecce.Test.QC.MetaChar()-import qualified RegExChar.MetaChar as MetaChar-import qualified RegExDot.Consumer as Consumer-import qualified RegExDot.ConsumptionBounds as ConsumptionBounds-import qualified RegExDot.ConsumptionProfile as ConsumptionProfile-import qualified RegExDot.Repeatable as Repeatable+import qualified RegExChar.MetaChar as MetaChar+import qualified RegExDot.Consumer+import qualified RegExDot.ConsumptionBounds+import qualified RegExDot.ConsumptionProfile+import qualified RegExDot.Repeatable import qualified Test.QuickCheck import qualified ToolShed.SelfValidate+import qualified ToolShed.Test.ReversibleIO -- | A specialised instance, required to instantiate 'Test.QuickCheck.Arbitrary'.-newtype RepeatableMetaChar = MkRepeatableMetaChar (Repeatable.Repeatable MetaChar.MetaChar) deriving (Eq, Read, Show)+newtype RepeatableMetaChar = MkRepeatableMetaChar (RegExDot.Repeatable.Repeatable MetaChar.MetaChar) deriving (Eq, Read, Show) -- | Accessor.-deconstruct :: RepeatableMetaChar -> Repeatable.Repeatable MetaChar.MetaChar+deconstruct :: RepeatableMetaChar -> RegExDot.Repeatable.Repeatable MetaChar.MetaChar deconstruct (MkRepeatableMetaChar repeatableMetaChar) = repeatableMetaChar instance ToolShed.SelfValidate.SelfValidator RepeatableMetaChar where getErrors = ToolShed.SelfValidate.getErrors . deconstruct -instance Consumer.Consumer RepeatableMetaChar where- consumptionProfile = Consumer.consumptionProfile . deconstruct- starHeight = Consumer.starHeight . deconstruct+instance RegExDot.Consumer.Consumer RepeatableMetaChar where+ consumptionProfile = RegExDot.Consumer.consumptionProfile . deconstruct+ starHeight = RegExDot.Consumer.starHeight . deconstruct instance Test.QuickCheck.Arbitrary RepeatableMetaChar where arbitrary = do@@ -65,13 +66,13 @@ isGreedy <- Test.QuickCheck.arbitrary let- repetitionBounds :: Repeatable.RepetitionBounds+ repetitionBounds :: RegExDot.Repeatable.RepetitionBounds repetitionBounds = (fewest, most) - return {-to Gen-monad-} . MkRepeatableMetaChar $ Repeatable.MkRepeatable {- Repeatable.base = metaChar,- Repeatable.repetitionBounds = repetitionBounds,- Repeatable.isGreedy = Repeatable.hasPreciseBounds repetitionBounds || isGreedy --Only specify 'non-greedy' where space exists.+ return {-to Gen-monad-} . MkRepeatableMetaChar $ RegExDot.Repeatable.MkRepeatable {+ RegExDot.Repeatable.base = metaChar,+ RegExDot.Repeatable.repetitionBounds = repetitionBounds,+ RegExDot.Repeatable.isGreedy = RegExDot.Repeatable.hasPreciseBounds repetitionBounds || isGreedy --Only specify 'non-greedy' where space exists. } #if !(MIN_VERSION_QuickCheck(2,1,0)) coarbitrary = undefined --CAVEAT: stops warnings from ghc.@@ -83,14 +84,14 @@ quickChecks :: (Testable -> IO ()) -> IO () quickChecks checker = checker `mapM_` [prop_consumptionProfile, prop_io, prop_isValid, prop_starHeight] where prop_consumptionProfile, prop_io, prop_isValid, prop_starHeight :: Testable- prop_consumptionProfile r = Test.QuickCheck.label "prop_consumptionProfile" $ Data.Maybe.maybe True (>= minData) maybeMaxData && b == Consumer.getHasSpecificRequirement (Repeatable.base $ deconstruct r) where ConsumptionProfile.MkConsumptionProfile {- ConsumptionProfile.consumptionBounds = (minData, maybeMaxData),- ConsumptionProfile.hasSpecificRequirement = b- } = Consumer.consumptionProfile r+ prop_consumptionProfile r = Test.QuickCheck.label "prop_consumptionProfile" $ Data.Maybe.maybe True (>= minData) maybeMaxData && b == RegExDot.Consumer.getHasSpecificRequirement (RegExDot.Repeatable.base $ deconstruct r) where RegExDot.ConsumptionProfile.MkConsumptionProfile {+ RegExDot.ConsumptionProfile.consumptionBounds = (minData, maybeMaxData),+ RegExDot.ConsumptionProfile.hasSpecificRequirement = b+ } = RegExDot.Consumer.consumptionProfile r - prop_io (MkRepeatableMetaChar r) = Test.QuickCheck.label "prop_io" $ read (show r) == r+ prop_io (MkRepeatableMetaChar r) = Test.QuickCheck.label "prop_io" $ ToolShed.Test.ReversibleIO.isReversible r prop_isValid r = Test.QuickCheck.label "prop_isValid" $ ToolShed.SelfValidate.isValid r - prop_starHeight (MkRepeatableMetaChar r) = Test.QuickCheck.label "prop_starHeight" $ Consumer.starHeight r == if ConsumptionBounds.isPrecise (Consumer.getConsumptionBounds r) then 0 else 1+ prop_starHeight (MkRepeatableMetaChar r) = Test.QuickCheck.label "prop_starHeight" $ RegExDot.Consumer.starHeight r == if RegExDot.ConsumptionBounds.isPrecise (RegExDot.Consumer.getConsumptionBounds r) then 0 else 1
src/Main.hs view
@@ -33,7 +33,9 @@ -- ** Type-synonyms -- CommandLineAction, -- * Functions- main --Added for Haskell style scanner, 'scan-0.1.0.5'.+-- read',+-- readCommandArg,+ main ) where import Control.Applicative((<$>))@@ -50,8 +52,8 @@ import qualified Grecce.Test.Performance.ExtendedRegExTestsPositive as Test.Performance.ExtendedRegExTestsPositive import qualified Grecce.Test.QC.QuickChecks as Test.QC.QuickChecks import qualified Paths_regexchar as Paths --Either local stub, or package-instance autogenerated by 'Setup.hs build'.-import qualified RegExDot.CompilationOptions as CompilationOptions-import qualified RegExDot.ExecutionOptions as ExecutionOptions+import qualified RegExDot.CompilationOptions+import qualified RegExDot.ExecutionOptions import qualified System.Console.GetOpt as G import qualified System.Environment import qualified System.Exit@@ -62,6 +64,16 @@ -- | Used to thread user-defined command-line options, though the list of functions which implement them. type CommandLineAction = CommandOptions.CommandOptions -> IO CommandOptions.CommandOptions --Supplied as the type-argument to 'G.OptDescr'. +-- | On failure to parse the specified string, returns an explanatory error.+read' :: Read a => String -> String -> a+read' errorMessage s = case reads s of+ [(x, _)] -> x+ _ -> error $ errorMessage ++ show s++-- | On failure to parse a command-line argument, returns an explanatory error.+readCommandArg :: Read a => String -> a+readCommandArg = read' "Failed to parse command-line argument "+ {- | * Parses the command-line arguments, to determine 'CommandOptions.CommandOptions'. @@ -70,11 +82,10 @@ main :: IO () main = do progName <- System.Environment.getProgName- args <- System.Environment.getArgs let- usage :: String- usage = "Usage:\t" ++ G.usageInfo progName optDescrList ++ " <regex> [<file-name>, ...]"+ usageMessage :: String+ usageMessage = "Usage:\t" ++ G.usageInfo progName optDescrList ++ " <regex> [<file-name>, ...]" --Define the command-line options, & the 'CommandLineAction's used to handle them. optDescrList :: [G.OptDescr CommandLineAction]@@ -103,33 +114,36 @@ G.Option "" ["runQuickChecks"] (G.NoArg runQuickChecks) "Test:\trun Quick-checks using arbitrary data & then exit. Specify 'verbose' before this option, for detailed output.", G.Option "" ["assert"] (assertFromFile `G.ReqArg` "<file-name>") "Test:\trun the assertions, defined in the specified file, & then exit. NB: specify this option last.", G.Option "" ["assertPosix"] (assertPosixFromFile `G.ReqArg` "<file-name>") "Test:\trun the assertions, defined in the specified file, against Text.Regex.Posix, & then exit. NB: specify this option last.",- G.Option "" ["abortTrialRepetitionsOnInherentFailure"] (setExecutionOption abortTrialRepetitionsOnInherentFailure `G.ReqArg` "Bool") ("Performance:\tif an alternative can't match, irrespective of the subsequent concatenation, then terminate futile trial repetitions; default '" ++ show (ExecutionOptions.abortTrialRepetitionsOnInherentFailure ToolShed.Defaultable.defaultValue) ++ "'."),--- G.Option "" ["abortTrialRepetitionsOnZeroConsumption"] (setExecutionOption abortTrialRepetitionsOnZeroConsumption `G.ReqArg` "Bool") ("Performance:\tcheck for zero data-consumption by the n-th repetition of an alternative, before considering (n + 1); default '" ++ show (ExecutionOptions.abortTrialRepetitionsOnZeroConsumption ToolShed.Defaultable.defaultValue) ++ "'."),--- G.Option "" ["bypassInputDataForLiberalConsumer"] (setExecutionOption bypassInputDataForLiberalConsumer `G.ReqArg` "Bool") ("Performance:\tbypass reading of the unconsumed input data, if the remaining RegEx can consume a sufficient quantity of anything; default '" ++ show (ExecutionOptions.bypassInputDataForLiberalConsumer ToolShed.Defaultable.defaultValue) ++ "'."),- G.Option "" ["catchIncompatibleAnchors"] (setExecutionOption catchIncompatibleAnchors `G.ReqArg` "Bool") ("Performance:\tavoid futile trial solutions, involving repetitions of anchored alternatives, which must consume data; default '" ++ show (ExecutionOptions.catchIncompatibleAnchors ToolShed.Defaultable.defaultValue) ++ "'."),- G.Option "" ["checkExistenceOfInelasticTail"] (setExecutionOption checkExistenceOfInelasticTail `G.ReqArg` "Bool") ("Performance:\tif the regex ends in one or more Meta-data, whose repetition-range is precisely defined, check that this sequence exists at the end of the input data; default '" ++ show (ExecutionOptions.checkExistenceOfInelasticTail ToolShed.Defaultable.defaultValue) ++ "'."),- G.Option "" ["checkForUnconsumableData"] (setExecutionOption checkForUnconsumableData `G.ReqArg` "Bool") ("Performance:\tcheck whether there's no possibility of consuming some of the input data; default '" ++ show (ExecutionOptions.checkForUnconsumableData ToolShed.Defaultable.defaultValue) ++ "'."),- G.Option "" ["moderateGreed"] (setExecutionOption moderateGreed `G.ReqArg` "Bool") ("Performance:\tgreedily consume data, only up to the limit beyond which, future requirements would be compromised; default '" ++ show (ExecutionOptions.moderateGreed ToolShed.Defaultable.defaultValue) ++ "'."),- G.Option "" ["permitReorderingOfAlternatives"] (setExecutionOption permitReorderingOfAlternatives `G.ReqArg` "Bool") ("Performance:\tpermit alternatives to be re-ordered, in an attempt to process the cheapest first; default '" ++ show (ExecutionOptions.permitReorderingOfAlternatives ToolShed.Defaultable.defaultValue) ++ "'."),- G.Option "" ["preferAlternativesWhichFeedTheGreedy"] (setExecutionOption preferAlternativesWhichFeedTheGreedy `G.ReqArg` "Bool") ("Preference:\tprefer solutions in which the choice of alternatives directs data from non-greedy to greedy consumers; default '" ++ show (ExecutionOptions.preferAlternativesWhichFeedTheGreedy ToolShed.Defaultable.defaultValue) ++ "'."),- G.Option "" ["preferAlternativesWhichMimickUnrolling"] (setExecutionOption preferAlternativesWhichMimickUnrolling `G.ReqArg` "Bool") ("Preference:\tprefer solutions in which the choice of alternatives consumes data like the unrolled repeatable group; default '" ++ show (ExecutionOptions.preferAlternativesWhichMimickUnrolling ToolShed.Defaultable.defaultValue) ++ "'."),- G.Option "" ["preferFewerRepeatedAlternatives"] (setExecutionOption preferFewerRepeatedAlternatives `G.ReqArg` "Bool") ("Preference:\tprefer solutions employing fewer repetitions of alternatives, to discourage the capture of null lists; default '" ++ show (ExecutionOptions.preferFewerRepeatedAlternatives ToolShed.Defaultable.defaultValue) ++ "'."),- G.Option "" ["unrollRepeatedSingletonAlternative"] (setExecutionOption unrollRepeatedSingletonAlternative `G.ReqArg` "Bool") ("Performance:\tunroll repetitions of singleton alternatives; this doesn't affect the result; default '" ++ show (ExecutionOptions.unrollRepeatedSingletonAlternative ToolShed.Defaultable.defaultValue) ++ "'."),- G.Option "" ["useFirstMatchAmongAlternatives"] (setExecutionOption useFirstMatchAmongAlternatives `G.ReqArg` "Bool") ("Performance:\trather than performing an exhaustive search for the optimal choice amongst alternatives, merely select the first that matches; conform to Perl rather than Posix; default '" ++ show (ExecutionOptions.useFirstMatchAmongAlternatives ToolShed.Defaultable.defaultValue) ++ "'."),- G.Option "" ["validateMinConsumptionOfAlternatives"] (setExecutionOption validateMinConsumptionOfAlternatives `G.ReqArg` "Bool") ("Performance:\twhen the number of repetitions of a group of alternatives is precisely specified, check the availability of the resulting minimum data-requirement; default '" ++ show (ExecutionOptions.validateMinConsumptionOfAlternatives ToolShed.Defaultable.defaultValue) ++ "'."),- G.Option "" ["complyStrictlyWithPosix"] (setCompilationOption complyStrictlyWithPosix `G.ReqArg` "Bool") ("Output:\tdefine the offset of captured data, corresponding to a sub-expression which matched zero times, as the artificial value -1 specified by Posix; currently only affects results of 'assert'; default '" ++ show (CompilationOptions.complyStrictlyWithPosix ToolShed.Defaultable.defaultValue) ++ "'.")+ G.Option "" ["abortTrialRepetitionsOnInherentFailure"] (setExecutionOption abortTrialRepetitionsOnInherentFailure `G.ReqArg` "Bool") ("Performance:\tif an alternative can't match, irrespective of the subsequent concatenation, then terminate futile trial repetitions; default '" ++ show (RegExDot.ExecutionOptions.abortTrialRepetitionsOnInherentFailure ToolShed.Defaultable.defaultValue) ++ "'."),+-- G.Option "" ["abortTrialRepetitionsOnZeroConsumption"] (setExecutionOption abortTrialRepetitionsOnZeroConsumption `G.ReqArg` "Bool") ("Performance:\tcheck for zero data-consumption by the n-th repetition of an alternative, before considering (n + 1); default '" ++ show (RegExDot.ExecutionOptions.abortTrialRepetitionsOnZeroConsumption ToolShed.Defaultable.defaultValue) ++ "'."),+-- G.Option "" ["bypassInputDataForLiberalConsumer"] (setExecutionOption bypassInputDataForLiberalConsumer `G.ReqArg` "Bool") ("Performance:\tbypass reading of the unconsumed input data, if the remaining RegEx can consume a sufficient quantity of anything; default '" ++ show (RegExDot.ExecutionOptions.bypassInputDataForLiberalConsumer ToolShed.Defaultable.defaultValue) ++ "'."),+ G.Option "" ["catchIncompatibleAnchors"] (setExecutionOption catchIncompatibleAnchors `G.ReqArg` "Bool") ("Performance:\tavoid futile trial solutions, involving repetitions of anchored alternatives, which must consume data; default '" ++ show (RegExDot.ExecutionOptions.catchIncompatibleAnchors ToolShed.Defaultable.defaultValue) ++ "'."),+ G.Option "" ["checkExistenceOfInelasticTail"] (setExecutionOption checkExistenceOfInelasticTail `G.ReqArg` "Bool") ("Performance:\tif the regex ends in one or more Meta-data, whose repetition-range is precisely defined, check that this sequence exists at the end of the input data; default '" ++ show (RegExDot.ExecutionOptions.checkExistenceOfInelasticTail ToolShed.Defaultable.defaultValue) ++ "'."),+ G.Option "" ["checkForUnconsumableData"] (setExecutionOption checkForUnconsumableData `G.ReqArg` "Bool") ("Performance:\tcheck whether there's no possibility of consuming some of the input data; default '" ++ show (RegExDot.ExecutionOptions.checkForUnconsumableData ToolShed.Defaultable.defaultValue) ++ "'."),+ G.Option "" ["moderateGreed"] (setExecutionOption moderateGreed `G.ReqArg` "Bool") ("Performance:\tgreedily consume data, only up to the limit beyond which, future requirements would be compromised; default '" ++ show (RegExDot.ExecutionOptions.moderateGreed ToolShed.Defaultable.defaultValue) ++ "'."),+ G.Option "" ["permitReorderingOfAlternatives"] (setExecutionOption permitReorderingOfAlternatives `G.ReqArg` "Bool") ("Performance:\tpermit alternatives to be re-ordered, in an attempt to process the cheapest first; default '" ++ show (RegExDot.ExecutionOptions.permitReorderingOfAlternatives ToolShed.Defaultable.defaultValue) ++ "'."),+ G.Option "" ["preferAlternativesWhichFeedTheGreedy"] (setExecutionOption preferAlternativesWhichFeedTheGreedy `G.ReqArg` "Bool") ("Preference:\tprefer solutions in which the choice of alternatives directs data from non-greedy to greedy consumers; default '" ++ show (RegExDot.ExecutionOptions.preferAlternativesWhichFeedTheGreedy ToolShed.Defaultable.defaultValue) ++ "'."),+ G.Option "" ["preferAlternativesWhichMimickUnrolling"] (setExecutionOption preferAlternativesWhichMimickUnrolling `G.ReqArg` "Bool") ("Preference:\tprefer solutions in which the choice of alternatives consumes data like the unrolled repeatable group; default '" ++ show (RegExDot.ExecutionOptions.preferAlternativesWhichMimickUnrolling ToolShed.Defaultable.defaultValue) ++ "'."),+ G.Option "" ["preferFewerRepeatedAlternatives"] (setExecutionOption preferFewerRepeatedAlternatives `G.ReqArg` "Bool") ("Preference:\tprefer solutions employing fewer repetitions of alternatives, to discourage the capture of null lists; default '" ++ show (RegExDot.ExecutionOptions.preferFewerRepeatedAlternatives ToolShed.Defaultable.defaultValue) ++ "'."),+ G.Option "" ["unrollRepeatedSingletonAlternative"] (setExecutionOption unrollRepeatedSingletonAlternative `G.ReqArg` "Bool") ("Performance:\tunroll repetitions of singleton alternatives; this doesn't affect the result; default '" ++ show (RegExDot.ExecutionOptions.unrollRepeatedSingletonAlternative ToolShed.Defaultable.defaultValue) ++ "'."),+ G.Option "" ["useFirstMatchAmongAlternatives"] (setExecutionOption useFirstMatchAmongAlternatives `G.ReqArg` "Bool") ("Performance:\trather than performing an exhaustive search for the optimal choice amongst alternatives, merely select the first that matches; conform to Perl rather than Posix; default '" ++ show (RegExDot.ExecutionOptions.useFirstMatchAmongAlternatives ToolShed.Defaultable.defaultValue) ++ "'."),+ G.Option "" ["validateMinConsumptionOfAlternatives"] (setExecutionOption validateMinConsumptionOfAlternatives `G.ReqArg` "Bool") ("Performance:\twhen the number of repetitions of a group of alternatives is precisely specified, check the availability of the resulting minimum data-requirement; default '" ++ show (RegExDot.ExecutionOptions.validateMinConsumptionOfAlternatives ToolShed.Defaultable.defaultValue) ++ "'."),+ G.Option "" ["complyStrictlyWithPosix"] (setCompilationOption complyStrictlyWithPosix `G.ReqArg` "Bool") ("Output:\tdefine the offset of captured data, corresponding to a sub-expression which matched zero times, as the artificial value -1 specified by Posix; currently only affects results of 'assert'; default '" ++ show (RegExDot.CompilationOptions.complyStrictlyWithPosix ToolShed.Defaultable.defaultValue) ++ "'.") ] where printVersion, printUsage :: IO CommandOptions.CommandOptions - printVersion = System.IO.hPutStrLn System.IO.stderr (Distribution.Text.display packageIdentifier ++ "\n\nCopyright (C) 2010 Dr. Alistair Ward.\nThis program comes with ABSOLUTELY NO WARRANTY.\nThis is free software, and you are welcome to redistribute it under certain conditions.\n\nWritten by Dr. Alistair Ward.") >> System.Exit.exitWith System.Exit.ExitSuccess where+ printVersion = System.IO.hPutStrLn System.IO.stderr (Distribution.Text.display packageIdentifier ++ "\n\nCopyright (C) 2010 " ++ author ++ ".\nThis program comes with ABSOLUTELY NO WARRANTY.\nThis is free software, and you are welcome to redistribute it under certain conditions.\n\nWritten by " ++ author ++ ".") >> System.Exit.exitWith System.Exit.ExitSuccess where packageIdentifier :: Distribution.Package.PackageIdentifier packageIdentifier = Distribution.Package.PackageIdentifier { Distribution.Package.pkgName = Distribution.Package.PackageName "grecce", Distribution.Package.pkgVersion = Distribution.Version.Version (Data.Version.versionBranch Paths.version) [] } - printUsage = System.IO.hPutStrLn System.IO.stderr usage >> System.Exit.exitWith System.Exit.ExitSuccess+ author :: String+ author = "Dr. Alistair Ward" + printUsage = System.IO.hPutStrLn System.IO.stderr usageMessage >> System.Exit.exitWith System.Exit.ExitSuccess+ printCurrentSettings, runQuickChecks :: CommandLineAction printCurrentSettings commandOptions = print commandOptions >> System.Exit.exitWith System.Exit.ExitSuccess runQuickChecks commandOptions = Test.QC.QuickChecks.run (CommandOptions.verbose commandOptions) >> System.Exit.exitWith System.Exit.ExitSuccess@@ -137,7 +151,7 @@ extendedRegExCharPerformance, readExtendedRegExCharFromFile, assertFromFile, assertPosixFromFile, setExtendedRegExChar :: String -> CommandLineAction extendedRegExCharPerformance s commandOptions = ( uncurry $ Test.Performance.ExtendedRegEx.run (CommandOptions.executionOptions commandOptions)- ) (read s) >> System.Exit.exitWith System.Exit.ExitSuccess+ ) (readCommandArg s) >> System.Exit.exitWith System.Exit.ExitSuccess readExtendedRegExCharFromFile s commandOptions = (head . dropWhile null . lines <$> readFile s) >>= (`setExtendedRegExChar` commandOptions) @@ -162,27 +176,27 @@ System.Exit.exitWith $ System.Exit.ExitFailure 2 setExtendedRegExChar s commandOptions = case CommandOptions.extendedRegExChar commandOptions of- Just e -> error $ "'" ++ show e ++ "' has already been defined"- _ -> return {-to IO-monad-} commandOptions { CommandOptions.extendedRegExChar = Just $ read s }+ Just extendedRegExChar -> error $ "The regex has already been defined as /" ++ show extendedRegExChar ++ "/"+ _ -> return {-to IO-monad-} commandOptions { CommandOptions.extendedRegExChar = Just $ readCommandArg s } abortTrialRepetitionsOnInherentFailure, {-abortTrialRepetitionsOnZeroConsumption, bypassInputDataForLiberalConsumer,-} catchIncompatibleAnchors, checkExistenceOfInelasticTail, checkForUnconsumableData, moderateGreed, permitReorderingOfAlternatives, preferAlternativesWhichFeedTheGreedy, preferAlternativesWhichMimickUnrolling, preferFewerRepeatedAlternatives, unrollRepeatedSingletonAlternative, useFirstMatchAmongAlternatives, validateMinConsumptionOfAlternatives :: CommandOptions.ExecutionOptionsMutator- abortTrialRepetitionsOnInherentFailure s e = e { ExecutionOptions.abortTrialRepetitionsOnInherentFailure = read s }--- abortTrialRepetitionsOnZeroConsumption s e = e { ExecutionOptions.abortTrialRepetitionsOnZeroConsumption = read s }--- bypassInputDataForLiberalConsumer s e = e { ExecutionOptions.bypassInputDataForLiberalConsumer = read s }- catchIncompatibleAnchors s e = e { ExecutionOptions.catchIncompatibleAnchors = read s }- checkExistenceOfInelasticTail s e = e { ExecutionOptions.checkExistenceOfInelasticTail = read s }- checkForUnconsumableData s e = e { ExecutionOptions.checkForUnconsumableData = read s }- moderateGreed s e = e { ExecutionOptions.moderateGreed = read s }- permitReorderingOfAlternatives s e = e { ExecutionOptions.permitReorderingOfAlternatives = read s }- preferAlternativesWhichFeedTheGreedy s e = e { ExecutionOptions.preferAlternativesWhichFeedTheGreedy = read s }- preferAlternativesWhichMimickUnrolling s e = e { ExecutionOptions.preferAlternativesWhichMimickUnrolling = read s }- preferFewerRepeatedAlternatives s e = e { ExecutionOptions.preferFewerRepeatedAlternatives = read s }- unrollRepeatedSingletonAlternative s e = e { ExecutionOptions.unrollRepeatedSingletonAlternative = read s }- useFirstMatchAmongAlternatives s e = e { ExecutionOptions.useFirstMatchAmongAlternatives = read s }- validateMinConsumptionOfAlternatives s e = e { ExecutionOptions.validateMinConsumptionOfAlternatives = read s }+ abortTrialRepetitionsOnInherentFailure s e = e { RegExDot.ExecutionOptions.abortTrialRepetitionsOnInherentFailure = readCommandArg s }+-- abortTrialRepetitionsOnZeroConsumption s e = e { RegExDot.ExecutionOptions.abortTrialRepetitionsOnZeroConsumption = readCommandArg s }+-- bypassInputDataForLiberalConsumer s e = e { RegExDot.ExecutionOptions.bypassInputDataForLiberalConsumer = readCommandArg s }+ catchIncompatibleAnchors s e = e { RegExDot.ExecutionOptions.catchIncompatibleAnchors = readCommandArg s }+ checkExistenceOfInelasticTail s e = e { RegExDot.ExecutionOptions.checkExistenceOfInelasticTail = readCommandArg s }+ checkForUnconsumableData s e = e { RegExDot.ExecutionOptions.checkForUnconsumableData = readCommandArg s }+ moderateGreed s e = e { RegExDot.ExecutionOptions.moderateGreed = readCommandArg s }+ permitReorderingOfAlternatives s e = e { RegExDot.ExecutionOptions.permitReorderingOfAlternatives = readCommandArg s }+ preferAlternativesWhichFeedTheGreedy s e = e { RegExDot.ExecutionOptions.preferAlternativesWhichFeedTheGreedy = readCommandArg s }+ preferAlternativesWhichMimickUnrolling s e = e { RegExDot.ExecutionOptions.preferAlternativesWhichMimickUnrolling = readCommandArg s }+ preferFewerRepeatedAlternatives s e = e { RegExDot.ExecutionOptions.preferFewerRepeatedAlternatives = readCommandArg s }+ unrollRepeatedSingletonAlternative s e = e { RegExDot.ExecutionOptions.unrollRepeatedSingletonAlternative = readCommandArg s }+ useFirstMatchAmongAlternatives s e = e { RegExDot.ExecutionOptions.useFirstMatchAmongAlternatives = readCommandArg s }+ validateMinConsumptionOfAlternatives s e = e { RegExDot.ExecutionOptions.validateMinConsumptionOfAlternatives = readCommandArg s } complyStrictlyWithPosix :: CommandOptions.CompilationOptionsMutator- complyStrictlyWithPosix s e = e { CompilationOptions.complyStrictlyWithPosix = read s }+ complyStrictlyWithPosix s e = e { RegExDot.CompilationOptions.complyStrictlyWithPosix = readCommandArg s } setCompilationOption :: CommandOptions.CompilationOptionsMutator -> String -> CommandLineAction setCompilationOption compilationOptionsMutator s = return {-to IO-monad-} . CommandOptions.setCompilationOption compilationOptionsMutator s@@ -190,11 +204,13 @@ setExecutionOption :: CommandOptions.ExecutionOptionsMutator -> String -> CommandLineAction setExecutionOption executionOptionsMutator s = return {-to IO-monad-} . CommandOptions.setExecutionOption executionOptionsMutator s + args <- System.Environment.getArgs+ -- G.getOpt :: G.ArgOrder CommandLineAction -> [G.OptDescr Action] -> [String] -> ([Action], [String], [String]) case G.getOpt G.RequireOrder optDescrList args of (commandLineActions, nonOptions, []) -> do commandOptions <- Data.List.foldl' (>>=) (return {-to IO-monad-} ToolShed.Defaultable.defaultValue) commandLineActions --Sequentially transform the 'CommandOptions', using 'CommandLineAction's corresponding to the specified command-line flags. Grep.grep commandOptions nonOptions --Perform the requested match, against the list of input-data files.- (_, _, errors) -> System.IO.Error.ioError . System.IO.Error.userError $ concat errors ++ usage --Throw.+ (_, _, errors) -> System.IO.Error.ioError . System.IO.Error.userError $ concat errors ++ usageMessage --Throw.
src/RegExChar/ExtendedRegExChar.hs view
@@ -18,7 +18,7 @@ {- | [@AUTHOR@] Dr. Alistair Ward - [@DESCRIPTION@] An 'RegEx.ExtendedRegEx', which has been specialised for 'Char', to create a tradition non-polymorphic /regex/.+ [@DESCRIPTION@] An 'RegExDot.RegEx.ExtendedRegEx', which has been specialised for 'Char', to create a tradition non-polymorphic /regex/. -} module RegExChar.ExtendedRegExChar(@@ -36,12 +36,12 @@ import Control.Applicative((<$>), (<*>)) import qualified Data.List import qualified RegExChar.MetaChar as MetaChar-import qualified RegExDot.Anchor as Anchor-import qualified RegExDot.Consumer as Consumer+import qualified RegExDot.Anchor+import qualified RegExDot.Consumer import RegExDot.DSL((<~>), (-:))-import qualified RegExDot.RegEx as RegEx-import qualified RegExDot.RegExOpts as RegExOpts-import qualified RegExDot.Repeatable as Repeatable+import qualified RegExDot.RegEx+import qualified RegExDot.RegExOpts+import qualified RegExDot.Repeatable import qualified Text.ParserCombinators.Parsec as Parsec import Text.ParserCombinators.Parsec((<?>), (<|>)) import qualified ToolShed.Data.Pair@@ -49,14 +49,14 @@ infix 4 +~, =~, /~ --Same as (==) & (/=). --- | Specialise a 'RegEx.ExtendedRegEx' for 'Char', & encapsulate it to permit tailored instance-declarations.+-- | Specialise a 'RegExDot.RegEx.ExtendedRegEx' for 'Char', & encapsulate it to permit tailored instance-declarations. data ExtendedRegExChar = MkExtendedRegExChar {- hasNonCapturingTopLevelAlternatives :: Bool, -- ^ The string from which a 'RegEx.ExtendedRegEx' is read, may, if data-capture isn't required, omit explicit delimiters around top-level 'RegEx.Alternatives'.- extendedRegEx :: RegEx.ExtendedRegEx Char+ 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.ExtendedRegEx Char } deriving Eq -- | Abbreviation.-type InputData = RegEx.InputData Char+type InputData = RegExDot.RegEx.InputData Char instance ToolShed.SelfValidate.SelfValidator ExtendedRegExChar where getErrors MkExtendedRegExChar {@@ -65,23 +65,23 @@ } | not $ ToolShed.SelfValidate.isValid extendedRegEx' = ToolShed.SelfValidate.getErrors extendedRegEx' | otherwise = ToolShed.SelfValidate.extractErrors [- (hasNonCapturingTopLevelAlternatives' && any (not . RegEx.isCaptureGroup . Repeatable.base) (RegEx.concatenation extendedRegEx'), "Invalid NonCapturingTopLevelAlternatives.")+ (hasNonCapturingTopLevelAlternatives' && any (not . RegExDot.RegEx.isCaptureGroup . RegExDot.Repeatable.base) (RegExDot.RegEx.concatenation extendedRegEx'), "Invalid NonCapturingTopLevelAlternatives.") ] -instance Consumer.Consumer ExtendedRegExChar where- consumptionProfile = Consumer.consumptionProfile . extendedRegEx- starHeight = Consumer.starHeight . extendedRegEx+instance RegExDot.Consumer.Consumer ExtendedRegExChar where+ consumptionProfile = RegExDot.Consumer.consumptionProfile . extendedRegEx+ starHeight = RegExDot.Consumer.starHeight . extendedRegEx -instance RegEx.ShortcutExpander Char where+instance RegExDot.RegEx.ShortcutExpander Char where expand c = error $ "RegExDot.RegEx.ShortcutExpander.expand RegExChar.ExtendedRegExChar:\tunrecognised shortcut '" ++ show c ++ "'." instance Read ExtendedRegExChar where readsPrec _ s- | s == reverse Anchor.tokens = [+ | s == reverse RegExDot.Anchor.tokens = [ ( MkExtendedRegExChar { hasNonCapturingTopLevelAlternatives = False,- extendedRegEx = (Just Anchor.Bow, Just Anchor.Stern) <~> []+ extendedRegEx = (Just RegExDot.Anchor.Bow, Just RegExDot.Anchor.Stern) <~> [] }, "" )@@ -89,53 +89,53 @@ | otherwise = let extendedRegExCharParser :: Parsec.Parser ExtendedRegExChar extendedRegExCharParser = reduce {-correct prior assumption-} <$> alternativesParser {-assume non-capturing top-level Alternatives-} where- reduce :: RegEx.Alternatives Char -> ExtendedRegExChar+ reduce :: RegExDot.RegEx.Alternatives Char -> ExtendedRegExChar reduce alternatives- | RegEx.isSingletonAlternatives alternatives = MkExtendedRegExChar False . head $ RegEx.deconstructAlternatives alternatives- | otherwise = MkExtendedRegExChar True $ (Nothing, Nothing) <~> RegEx.CaptureGroup alternatives -: [] --Infer non-capturing top-level 'RegEx.Alternatives' from the presence of 'RegEx.alternativeExtendedRegExSeparatorToken's.+ | RegExDot.RegEx.isSingletonAlternatives alternatives = MkExtendedRegExChar False . head $ RegExDot.RegEx.deconstructAlternatives alternatives+ | otherwise = MkExtendedRegExChar True $ RegExDot.Anchor.unanchored <~> RegExDot.RegEx.CaptureGroup alternatives -: [] --Infer non-capturing top-level 'RegExDot.RegEx.Alternatives' from the presence of 'RegExDot.RegEx.alternativeExtendedRegExSeparatorToken's. - alternativesParser :: Parsec.Parser (RegEx.Alternatives Char)- alternativesParser = RegEx.MkAlternatives <$> extendedRegExParser `Parsec.sepBy1` (Parsec.char RegEx.alternativeExtendedRegExSeparatorToken <?> "RegEx.alternativeExtendedRegExSeparatorToken " ++ show RegEx.alternativeExtendedRegExSeparatorToken) where- extendedRegExParser :: Parsec.Parser (RegEx.ExtendedRegEx Char)+ alternativesParser :: Parsec.Parser (RegExDot.RegEx.Alternatives Char)+ alternativesParser = RegExDot.RegEx.MkAlternatives <$> extendedRegExParser `Parsec.sepBy1` (Parsec.char RegExDot.RegEx.alternativeExtendedRegExSeparatorToken <?> "RegExDot.RegEx.alternativeExtendedRegExSeparatorToken " ++ show RegExDot.RegEx.alternativeExtendedRegExSeparatorToken) where+ extendedRegExParser :: Parsec.Parser (RegExDot.RegEx.ExtendedRegEx Char) extendedRegExParser = do- maybeBowAnchor <- Parsec.option Nothing {-default-} $ (Parsec.char Anchor.bowToken <?> "Anchor.bowToken " ++ show Anchor.bowToken) >> return {-to GenParser-monad-} (Just Anchor.Bow)+ maybeBowAnchor <- Parsec.option Nothing {-default-} $ (Parsec.char RegExDot.Anchor.bowToken <?> "RegExDot.Anchor.bowToken " ++ show RegExDot.Anchor.bowToken) >> return {-to ParsecT-monad-} (Just RegExDot.Anchor.Bow) repeatableRequirementList <- repeatableRequirementListParser ( do- repeatableCaptureGroup <- Repeatable.repeatableParser . RegEx.CaptureGroup =<< uncurry Parsec.between (- ToolShed.Data.Pair.mirror Parsec.char RegEx.captureGroupDelimiters- ) alternativesParser {-recurse-} <?> "RegEx.captureGroupDelimiters " ++ show RegEx.captureGroupDelimiters+ repeatableCaptureGroup <- RegExDot.Repeatable.repeatableParser . RegExDot.RegEx.CaptureGroup =<< uncurry Parsec.between (+ ToolShed.Data.Pair.mirror Parsec.char RegExDot.RegEx.captureGroupDelimiters+ ) alternativesParser {-recurse-} <?> "RegExDot.RegEx.captureGroupDelimiters " ++ show RegExDot.RegEx.captureGroupDelimiters - extendedRegEx' <- extendedRegExParser --Recurse.+ extendedRegEx' <- extendedRegExParser --Recurse. - return {-to GenParser-monad-} $ RegEx.transformExtendedRegEx ((repeatableRequirementList ++) . (repeatableCaptureGroup :)) extendedRegEx' { RegEx.bowAnchor = maybeBowAnchor }+ return {-to ParsecT-monad-} $ RegExDot.RegEx.transformExtendedRegEx ((repeatableRequirementList ++) . (repeatableCaptureGroup :)) extendedRegEx' { RegExDot.RegEx.bowAnchor = maybeBowAnchor } ) <|> ( do- maybeSternAnchor <- Parsec.option Nothing {-default-} $ (Parsec.char Anchor.sternToken <?> "Anchor.sternToken " ++ show Anchor.sternToken) >> return {-to GenParser-monad-} (Just Anchor.Stern)+ maybeSternAnchor <- Parsec.option Nothing {-default-} $ (Parsec.char RegExDot.Anchor.sternToken <?> "RegExDot.Anchor.sternToken " ++ show RegExDot.Anchor.sternToken) >> return {-to ParsecT-monad-} (Just RegExDot.Anchor.Stern) - return {-to GenParser-monad-} RegEx.MkExtendedRegEx {- RegEx.bowAnchor = maybeBowAnchor,- RegEx.concatenation = repeatableRequirementList,- RegEx.sternAnchor = maybeSternAnchor+ return {-to ParsecT-monad-} RegExDot.RegEx.MkExtendedRegEx {+ RegExDot.RegEx.bowAnchor = maybeBowAnchor,+ RegExDot.RegEx.concatenation = repeatableRequirementList,+ RegExDot.RegEx.sternAnchor = maybeSternAnchor } ) where- repeatableRequirementListParser :: Parsec.Parser (RegEx.Concatenation Char)+ repeatableRequirementListParser :: Parsec.Parser (RegExDot.RegEx.Concatenation Char) repeatableRequirementListParser = Parsec.choice [ Parsec.try . Parsec.lookAhead $ (- Parsec.char Anchor.sternToken <?> "Anchor.sternToken " ++ show Anchor.sternToken+ Parsec.char RegExDot.Anchor.sternToken <?> "RegExDot.Anchor.sternToken " ++ show RegExDot.Anchor.sternToken ) >> ( (- Parsec.eof >> return {-to GenParser-monad-} []+ Parsec.eof >> return {-to ParsecT-monad-} [] ) <|> (- Parsec.oneOf [RegEx.alternativeExtendedRegExSeparatorToken, snd RegEx.captureGroupDelimiters] >> return {-to GenParser-monad-} []+ Parsec.oneOf [RegExDot.RegEx.alternativeExtendedRegExSeparatorToken, snd RegExDot.RegEx.captureGroupDelimiters] >> return {-to ParsecT-monad-} [] ) ), (:) <$> (- MetaChar.metaCharParser >>= Repeatable.repeatableParser . RegEx.Require . MetaChar.deconstruct+ MetaChar.metaCharParser >>= RegExDot.Repeatable.repeatableParser . RegExDot.RegEx.Require . MetaChar.deconstruct ) <*> repeatableRequirementListParser, {-recurse-}- return {-to GenParser-monad-} []+ return {-to ParsecT-monad-} [] ] in (@@ -151,56 +151,56 @@ instance Show ExtendedRegExChar where showsPrec _ MkExtendedRegExChar { hasNonCapturingTopLevelAlternatives = hasNonCapturingTopLevelAlternatives',- extendedRegEx = RegEx.MkExtendedRegEx {- RegEx.bowAnchor = maybeBowAnchor,- RegEx.concatenation = concatenation',- RegEx.sternAnchor = maybeSternAnchor+ extendedRegEx = RegExDot.RegEx.MkExtendedRegEx {+ RegExDot.RegEx.bowAnchor = maybeBowAnchor,+ RegExDot.RegEx.concatenation = concatenation',+ RegExDot.RegEx.sternAnchor = maybeSternAnchor }- } = RegEx.showsMaybeAnchor maybeBowAnchor . foldl (.) (showString "") (+ } = RegExDot.RegEx.showsMaybeAnchor maybeBowAnchor . foldl (.) (showString "") ( ( let- showAlternatives :: RegEx.Alternatives Char -> [ShowS]- showAlternatives = Data.List.intersperse (showChar RegEx.alternativeExtendedRegExSeparatorToken) . map (shows . MkExtendedRegExChar False) . RegEx.deconstructAlternatives+ showAlternatives :: RegExDot.RegEx.Alternatives Char -> [ShowS]+ showAlternatives = Data.List.intersperse (showChar RegExDot.RegEx.alternativeExtendedRegExSeparatorToken) . map (shows . MkExtendedRegExChar False) . RegExDot.RegEx.deconstructAlternatives in if hasNonCapturingTopLevelAlternatives' then map (- \repeatablePattern -> case Repeatable.base repeatablePattern of- RegEx.CaptureGroup alternatives -> foldr (.) (showString "") $ showAlternatives alternatives- _ -> error $ "Show RegExChar.ExtendedRegExChar: unexpected " ++ show repeatablePattern+ \repeatablePattern -> case RegExDot.Repeatable.base repeatablePattern of+ RegExDot.RegEx.CaptureGroup alternatives -> foldr (.) (showString "") $ showAlternatives alternatives+ _ -> error $ "Show RegExChar.ExtendedRegExChar: unexpected " ++ show repeatablePattern ) else map ( \repeatablePattern -> (- case Repeatable.base repeatablePattern of- RegEx.Require meta -> shows $ MetaChar.MkMetaChar meta- RegEx.CaptureGroup alternatives -> showChar (- fst RegEx.captureGroupDelimiters+ case RegExDot.Repeatable.base repeatablePattern of+ RegExDot.RegEx.Require meta -> shows $ MetaChar.MkMetaChar meta+ RegExDot.RegEx.CaptureGroup alternatives -> showChar (+ fst RegExDot.RegEx.captureGroupDelimiters ) . foldr (.) (- showChar $ snd RegEx.captureGroupDelimiters --Initial value.+ showChar $ snd RegExDot.RegEx.captureGroupDelimiters --Initial value. ) ( showAlternatives alternatives )- ) . Repeatable.showSuffix repeatablePattern+ ) . RegExDot.Repeatable.showSuffix repeatablePattern ) ) concatenation'- ) . RegEx.showsMaybeAnchor maybeSternAnchor+ ) . RegExDot.RegEx.showsMaybeAnchor maybeSternAnchor --- | A veneer over the underlying polymorphic operator, 'RegEx.+~'.+-- | A veneer over the underlying polymorphic operator, 'RegExDot.RegEx.+~'. (+~)- :: InputData -- ^ The input-data string.- -> RegExOpts.RegExOpts ExtendedRegExChar -- ^ The match-options, parameterised by the regex-specification.- -> RegEx.Result Char-inputData +~ regExOpts = inputData RegEx.+~ fmap extendedRegEx regExOpts --CAVEAT: <http://hackage.haskell.org/trac/haskell-prime/wiki/QualifiedOperators>.+ :: InputData -- ^ The input-data string.+ -> RegExDot.RegExOpts.RegExOpts ExtendedRegExChar -- ^ The match-options, parameterised by the regex-specification.+ -> RegExDot.RegEx.Result Char+inputData +~ regExOpts = inputData RegExDot.RegEx.+~ fmap extendedRegEx regExOpts --CAVEAT: <http://hackage.haskell.org/trac/haskell-prime/wiki/QualifiedOperators>. --- | A veneer over the underlying polymorphic operator, 'RegEx.=~'.+-- | A veneer over the underlying polymorphic operator, 'RegExDot.RegEx.=~'. (=~)- :: InputData -- ^ The input-data string.- -> RegExOpts.RegExOpts ExtendedRegExChar -- ^ The match-options, parameterised by the regex-specification.+ :: InputData -- ^ The input-data string.+ -> RegExDot.RegExOpts.RegExOpts ExtendedRegExChar -- ^ The match-options, parameterised by the regex-specification. -> Bool-inputData =~ regExOpts = inputData RegEx.=~ fmap extendedRegEx regExOpts --CAVEAT: <http://hackage.haskell.org/trac/haskell-prime/wiki/QualifiedOperators>.+inputData =~ regExOpts = inputData RegExDot.RegEx.=~ fmap extendedRegEx regExOpts --CAVEAT: <http://hackage.haskell.org/trac/haskell-prime/wiki/QualifiedOperators>. -- | Pattern-mismatch operator. (/~)- :: InputData -- ^ The input-data string.- -> RegExOpts.RegExOpts ExtendedRegExChar -- ^ The match-options, parameterised by the regex-specification.+ :: InputData -- ^ The input-data string.+ -> RegExDot.RegExOpts.RegExOpts ExtendedRegExChar -- ^ The match-options, parameterised by the regex-specification. -> Bool (/~) inputData = not . (inputData =~)
src/RegExChar/MetaChar.hs view
@@ -20,7 +20,7 @@ [@DESCRIPTION@] - * Implements 'Meta.ShortcutExpander' 'Char', to implement some of the traditional /Perl-style shortcuts/:+ * Implements 'RegExDot.Meta.ShortcutExpander' 'Char', to implement some of the traditional /Perl-style shortcuts/: [@\\d@] => Any 'Data.Char.isDigit'-character. @@ -36,7 +36,7 @@ * Enables one to compose concise regexen, containing any 'Char' that's a member of one of these predefined sets. - * Though 'Meta.Meta' is polymorphic, & the type-parameter can't be assumed to implement either 'Enum' or 'Ord',+ * Though 'RegExDot.Meta.Meta' is polymorphic, & the type-parameter can't be assumed to implement either 'Enum' or 'Ord', 'Char' actually does, so this module is able to implement ranges within a /Bracket-expression/. * Defines specialised instances of 'Read' & 'Show', to cope with /Perl-style shortcuts/, /Posix Character-classes/ & /Bracket-expression/ range-specifications.@@ -64,26 +64,26 @@ import Control.Arrow((***)) import qualified Data.Char import qualified Data.Map-import qualified RegExDot.BracketExpression as BracketExpression-import qualified RegExDot.BracketExpressionMember as BracketExpressionMember-import qualified RegExDot.Consumer as Consumer-import qualified RegExDot.Meta as Meta-import qualified RegExDot.RegEx as RegEx-import qualified RegExDot.Repeatable as Repeatable-import qualified RegExDot.ShowablePredicate as ShowablePredicate-import qualified Text.ParserCombinators.Parsec as Parsec+import qualified RegExDot.BracketExpression+import qualified RegExDot.BracketExpressionMember+import qualified RegExDot.Consumer+import qualified RegExDot.Meta+import qualified RegExDot.RegEx+import qualified RegExDot.Repeatable+import qualified RegExDot.ShowablePredicate+import qualified Text.ParserCombinators.Parsec as Parsec import Text.ParserCombinators.Parsec((<?>)) import qualified ToolShed.Data.Pair import qualified ToolShed.SelfValidate -- | Holds a mapping from an escape-sequence & the predicate via which it is implemented.-type AssociationList key = [(key, ShowablePredicate.Predicate Char)]+type AssociationList key = [(key, RegExDot.ShowablePredicate.Predicate Char)] -- | Holds a mapping from an escape-sequence & the predicate via which it is implemented.-type Dictionary key = Data.Map.Map key (ShowablePredicate.Predicate Char)+type Dictionary key = Data.Map.Map key (RegExDot.ShowablePredicate.Predicate Char) -instance BracketExpressionMember.ShortcutExpander Char where- findPredicate shortcut = ShowablePredicate.MkShowablePredicate [Meta.shortcutToken, shortcut] <$> shortcut `Data.Map.lookup` dictionary where+instance RegExDot.BracketExpressionMember.ShortcutExpander Char where+ findPredicate shortcut = RegExDot.ShowablePredicate.MkShowablePredicate [RegExDot.Meta.shortcutToken, shortcut] <$> shortcut `Data.Map.lookup` dictionary where dictionary :: Dictionary Char dictionary = Data.Map.fromList $ perlShortcuts ++ invert perlShortcuts where perlShortcuts :: AssociationList Char@@ -96,35 +96,35 @@ invert :: AssociationList Char -> AssociationList Char invert = map (Data.Char.toUpper *** (not .)) -instance Meta.ShortcutExpander Char where- expand c = case BracketExpressionMember.findPredicate c of- Just showablePredicate -> Meta.Predicate showablePredicate- _ -> Meta.Literal c+instance RegExDot.Meta.ShortcutExpander Char where+ expand c = case RegExDot.BracketExpressionMember.findPredicate c of+ Just showablePredicate -> RegExDot.Meta.Predicate showablePredicate+ _ -> RegExDot.Meta.Literal c -- | A specialised instance, encapsulated to permit tailored instance-declarations.-newtype MetaChar = MkMetaChar (Meta.Meta Char) deriving Eq+newtype MetaChar = MkMetaChar (RegExDot.Meta.Meta Char) deriving Eq -- | Accessor.-deconstruct :: MetaChar -> Meta.Meta Char+deconstruct :: MetaChar -> RegExDot.Meta.Meta Char deconstruct (MkMetaChar metaChar) = metaChar instance ToolShed.SelfValidate.SelfValidator MetaChar where getErrors = ToolShed.SelfValidate.getErrors . deconstruct -instance Consumer.Consumer MetaChar where- consumptionProfile = Consumer.consumptionProfile . deconstruct- starHeight = Consumer.starHeight . deconstruct+instance RegExDot.Consumer.Consumer MetaChar where+ consumptionProfile = RegExDot.Consumer.consumptionProfile . deconstruct+ starHeight = RegExDot.Consumer.starHeight . deconstruct -- | Builds a parser of traditional regex-syntax, which understands 'Char'-specific concepts like /Perl-style shortcuts/ & /Posix Character-classes/. metaCharParser :: Parsec.Parser MetaChar metaCharParser = MkMetaChar <$> Parsec.choice [- (Parsec.char Meta.anyToken <?> "Meta.anyToken " ++ show Meta.anyToken) >> return {-to GenParser-monad-} Meta.Any,- (Parsec.char Meta.shortcutToken <?> "Meta.shortcutToken " ++ show Meta.shortcutToken) >> Meta.expand <$> Parsec.anyChar,- uncurry Parsec.between (ToolShed.Data.Pair.mirror Parsec.char BracketExpression.delimiterTokens) (+ (Parsec.char RegExDot.Meta.anyToken <?> "RegExDot.Meta.anyToken " ++ show RegExDot.Meta.anyToken) >> return {-to ParsecT-monad-} RegExDot.Meta.Any,+ (Parsec.char RegExDot.Meta.shortcutToken <?> "RegExDot.Meta.shortcutToken " ++ show RegExDot.Meta.shortcutToken) >> RegExDot.Meta.expand <$> Parsec.anyChar,+ uncurry Parsec.between (ToolShed.Data.Pair.mirror Parsec.char RegExDot.BracketExpression.delimiterTokens) ( do let- implementPosixCharacterClass :: String -> Maybe (ShowablePredicate.ShowablePredicate Char)- implementPosixCharacterClass identifier = ShowablePredicate.MkShowablePredicate (+ implementPosixCharacterClass :: String -> Maybe (RegExDot.ShowablePredicate.ShowablePredicate Char)+ implementPosixCharacterClass identifier = RegExDot.ShowablePredicate.MkShowablePredicate ( fst posixCharacterClassDelimiters ++ identifier ++ snd posixCharacterClassDelimiters ) <$> identifier `Data.Map.lookup` dictionary where dictionary :: Dictionary String@@ -148,24 +148,24 @@ ] invert :: AssociationList String -> AssociationList String- invert = map $ (BracketExpression.negationToken :) *** (not .)+ invert = map $ (RegExDot.BracketExpression.negationToken :) *** (not .) - cTor <- Parsec.option Meta.AnyOf {-default-} $ (Parsec.char BracketExpression.negationToken <?> "BracketExpression.negationToken " ++ show BracketExpression.negationToken) >> return {-to GenParser-monad-} Meta.NoneOf+ cTor <- Parsec.option RegExDot.Meta.AnyOf {-default-} $ (Parsec.char RegExDot.BracketExpression.negationToken <?> "RegExDot.BracketExpression.negationToken " ++ show RegExDot.BracketExpression.negationToken) >> return {-to ParsecT-monad-} RegExDot.Meta.NoneOf - literalBracketExpressionTerminator <- Parsec.option [] {-default-} $ return {-to List-monad-} . BracketExpressionMember.Literal <$> (- Parsec.char (snd BracketExpression.delimiterTokens) <?> "Literal Bracket-expression terminator " ++ show (snd BracketExpression.delimiterTokens)- ) --If the first item in a BracketExpression (or negated BracketExpression) is the terminator-token, then it is treated as a 'BracketExpressionMember.Literal'.+ literalBracketExpressionTerminator <- Parsec.option [] {-default-} $ return {-to List-monad-} . RegExDot.BracketExpressionMember.Literal <$> (+ Parsec.char (snd RegExDot.BracketExpression.delimiterTokens) <?> "Literal Bracket-expression terminator " ++ show (snd RegExDot.BracketExpression.delimiterTokens)+ ) --If the first item in a BracketExpression (or negated BracketExpression) is the terminator-token, then it is treated as a 'RegExDot.BracketExpressionMember.Literal'. cTor . (literalBracketExpressionTerminator ++) <$> Parsec.many {-potentially zero-} ( Parsec.choice [ ( do- _ <- Parsec.char Meta.shortcutToken <?> "Meta.shortcutToken " ++ show Meta.shortcutToken+ _ <- Parsec.char RegExDot.Meta.shortcutToken <?> "RegExDot.Meta.shortcutToken " ++ show RegExDot.Meta.shortcutToken c <- Parsec.anyChar - return {-to GenParser-monad-} $ case BracketExpressionMember.findPredicate c of- Just showablePredicate -> BracketExpressionMember.Predicate showablePredicate- _ -> BracketExpressionMember.Literal c --Escaped literal.+ return {-to ParsecT-monad-} $ case RegExDot.BracketExpressionMember.findPredicate c of+ Just showablePredicate -> RegExDot.BracketExpressionMember.Predicate showablePredicate+ _ -> RegExDot.BracketExpressionMember.Literal c --Escaped literal. ) <?> "Perl-style shortcut", Parsec.try ( uncurry Parsec.between (ToolShed.Data.Pair.mirror Parsec.string posixCharacterClassDelimiters) (@@ -173,29 +173,29 @@ identifier <- Parsec.many1 $ Parsec.noneOf [head $ snd posixCharacterClassDelimiters] case implementPosixCharacterClass identifier of- Just showablePredicate -> return {-to GenParser-monad-} $ BracketExpressionMember.Predicate showablePredicate+ Just showablePredicate -> return {-to ParsecT-monad-} $ RegExDot.BracketExpressionMember.Predicate showablePredicate _ -> Parsec.unexpected $ "MetaChar.metaCharParser:\tunrecognised Posix Character-class; " ++ show identifier ) <?> "Posix Character-class " ++ show posixCharacterClassDelimiters ), --Regurgitate erroneously consumed input. Parsec.try ( ( do- rangeStart <- Parsec.noneOf [snd BracketExpression.delimiterTokens]+ rangeStart <- Parsec.noneOf [snd RegExDot.BracketExpression.delimiterTokens] _ <- Parsec.char bracketExpressionRangeToken <?> "bracketExpressionRangeToken " ++ show bracketExpressionRangeToken- rangeEnd <- Parsec.noneOf [snd BracketExpression.delimiterTokens]+ rangeEnd <- Parsec.noneOf [snd RegExDot.BracketExpression.delimiterTokens] - return {-to GenParser-monad-} . BracketExpressionMember.Predicate . ShowablePredicate.MkShowablePredicate [+ return {-to ParsecT-monad-} . RegExDot.BracketExpressionMember.Predicate . RegExDot.ShowablePredicate.MkShowablePredicate [ rangeStart, bracketExpressionRangeToken, rangeEnd ] $ \c -> rangeStart <= c && c <= rangeEnd --Create custom predicate, utilising "Ord Char". ) <?> "Bracket-expression range" ), --Regurgitate erroneously consumed input.- BracketExpressionMember.Literal <$> Parsec.noneOf [snd BracketExpression.delimiterTokens] <?> "BracketExpressionMember.Literal" --TODO: the first Char-member can be a literal ']'.+ RegExDot.BracketExpressionMember.Literal <$> Parsec.noneOf [snd RegExDot.BracketExpression.delimiterTokens] <?> "RegExDot.BracketExpressionMember.Literal" --TODO: the first Char-member can be a literal ']'. ] <?> "Bracket-expression member" ) <?> "Bracket-expression member-list"- ) <?> "BracketExpression.delimiterTokens " ++ show BracketExpression.delimiterTokens,- Meta.Literal <$> Parsec.noneOf RegEx.tokens+ ) <?> "RegExDot.BracketExpression.delimiterTokens " ++ show RegExDot.BracketExpression.delimiterTokens,+ RegExDot.Meta.Literal <$> Parsec.noneOf RegExDot.RegEx.tokens ] instance Read MetaChar where@@ -214,39 +214,39 @@ posixCharacterClassDelimiters = ("[:", ":]") instance Show MetaChar where- showsPrec _ (MkMetaChar Meta.Any) = showChar Meta.anyToken- showsPrec _ (MkMetaChar (Meta.Literal c)) = (+ showsPrec _ (MkMetaChar RegExDot.Meta.Any) = showChar RegExDot.Meta.anyToken+ showsPrec _ (MkMetaChar (RegExDot.Meta.Literal c)) = ( if c `elem` [- fst BracketExpression.delimiterTokens,- fst Repeatable.rangeDelimiters,- Repeatable.oneOrMoreToken,- Repeatable.zeroOrMoreToken,- Repeatable.zeroOrOneToken,- Meta.anyToken,- Meta.shortcutToken- ] ++ RegEx.tokens- then showChar Meta.shortcutToken+ fst RegExDot.BracketExpression.delimiterTokens,+ fst RegExDot.Repeatable.rangeDelimiters,+ RegExDot.Repeatable.oneOrMoreToken,+ RegExDot.Repeatable.zeroOrMoreToken,+ RegExDot.Repeatable.zeroOrOneToken,+ RegExDot.Meta.anyToken,+ RegExDot.Meta.shortcutToken+ ] ++ RegExDot.RegEx.tokens+ then showChar RegExDot.Meta.shortcutToken else id ) . showChar c- showsPrec _ (MkMetaChar (Meta.AnyOf bracketExpression)) = showChar (- fst BracketExpression.delimiterTokens+ showsPrec _ (MkMetaChar (RegExDot.Meta.AnyOf bracketExpression)) = showChar (+ fst RegExDot.BracketExpression.delimiterTokens ) . showString ( foldr ( \e -> case e of- BracketExpressionMember.Predicate showablePredicate -> shows showablePredicate- BracketExpressionMember.Literal literal -> (+ RegExDot.BracketExpressionMember.Predicate showablePredicate -> shows showablePredicate+ RegExDot.BracketExpressionMember.Literal literal -> ( if literal `elem` [ bracketExpressionRangeToken, --CAVEAT: only unambiguously literal when at the start or end of a "BracketExpression".- Meta.shortcutToken,- snd BracketExpression.delimiterTokens --CAVEAT: only unambiguously literal when at the start of a "BracketExpression".+ RegExDot.Meta.shortcutToken,+ snd RegExDot.BracketExpression.delimiterTokens --CAVEAT: only unambiguously literal when at the start of a "BracketExpression". ]- then showChar Meta.shortcutToken+ then showChar RegExDot.Meta.shortcutToken else id ) . showChar literal ) (- showChar (snd BracketExpression.delimiterTokens) "" --Initial value.+ showChar (snd RegExDot.BracketExpression.delimiterTokens) "" --Initial value. ) bracketExpression )- showsPrec _ (MkMetaChar (Meta.NoneOf bracketExpression)) = showChar x . showChar BracketExpression.negationToken . showString xs where (x : xs) = show . MkMetaChar $ Meta.AnyOf bracketExpression- showsPrec _ (MkMetaChar m) = shows m+ showsPrec _ (MkMetaChar (RegExDot.Meta.NoneOf bracketExpression)) = showChar x . showChar RegExDot.BracketExpression.negationToken . showString xs where (x : xs) = show . MkMetaChar $ RegExDot.Meta.AnyOf bracketExpression+ showsPrec _ (MkMetaChar m) = shows m
src/RegExChar/RegExOptsChar.hs view
@@ -24,10 +24,10 @@ [@CAVEATS@] - * The underlying polymorphic (in terms of the base-type of the list of input data) 'RegEx.ExtendedRegEx'-engine is never going to be a drop-in replacement for other /regex/-engines,+ * The underlying polymorphic (in terms of the base-type of the list of input data) 'RegExDot.RegEx.ExtendedRegEx'-engine is never going to be a drop-in replacement for other /regex/-engines, so this standard interface has only been implemented for traditional input data-type ['Char']. - * The standard interface requires many Haskell-extensions, but since this implementation is just a thin layer over the underlying portable polymorphic 'RegEx.ExtendedRegEx'-engine,+ * The standard interface requires many Haskell-extensions, but since this implementation is just a thin layer over the underlying portable polymorphic 'RegExDot.RegEx.ExtendedRegEx'-engine, the latter can still be used directly, where any of these extensions are unavailable. -} @@ -52,15 +52,15 @@ import Control.Applicative((<$>)) import qualified Data.Array.IArray import qualified RegExChar.ExtendedRegExChar as ExtendedRegExChar-import qualified RegExDot.CompilationOptions as CompilationOptions-import qualified RegExDot.ConsumptionBounds as ConsumptionBounds-import qualified RegExDot.DataSpan as DataSpan-import qualified RegExDot.DataSpanTree as DataSpanTree-import qualified RegExDot.ExecutionOptions as ExecutionOptions-import qualified RegExDot.RegEx as RegEx-import qualified RegExDot.RegExOpts as RegExOpts-import qualified RegExDot.Result as Result-import qualified RegExDot.Tree as Tree+import qualified RegExDot.CompilationOptions+import qualified RegExDot.ConsumptionBounds+import qualified RegExDot.DataSpan+import qualified RegExDot.DataSpanTree+import qualified RegExDot.ExecutionOptions+import qualified RegExDot.RegEx+import qualified RegExDot.RegExOpts+import qualified RegExDot.Result+import qualified RegExDot.Tree import qualified Text.Regex.Base.RegexLike as RegexLike import Text.Regex.Base.Context() --Instance-declarations. import qualified ToolShed.Data.List@@ -70,56 +70,56 @@ infix 4 =~ --Same as (==). -- | Defines a specific instance of the polymorphic base-type.-type RegExOptsChar = RegExOpts.RegExOpts ExtendedRegExChar.ExtendedRegExChar+type RegExOptsChar = RegExDot.RegExOpts.RegExOpts ExtendedRegExChar.ExtendedRegExChar -- | Convenience accessor-function. hasNonCapturingTopLevelAlternatives :: RegExOptsChar -> Bool-hasNonCapturingTopLevelAlternatives = ExtendedRegExChar.hasNonCapturingTopLevelAlternatives . RegExOpts.regEx+hasNonCapturingTopLevelAlternatives = ExtendedRegExChar.hasNonCapturingTopLevelAlternatives . RegExDot.RegExOpts.regEx -- | Convenience accessor-function. complyStrictlyWithPosix :: RegExOptsChar -> Bool-complyStrictlyWithPosix = CompilationOptions.complyStrictlyWithPosix . RegExOpts.compilationOptions+complyStrictlyWithPosix = RegExDot.CompilationOptions.complyStrictlyWithPosix . RegExDot.RegExOpts.compilationOptions -instance RegexLike.RegexOptions RegExOptsChar CompilationOptions.CompilationOptions ExecutionOptions.ExecutionOptions where+instance RegexLike.RegexOptions RegExOptsChar RegExDot.CompilationOptions.CompilationOptions RegExDot.ExecutionOptions.ExecutionOptions where blankCompOpt = ToolShed.Options.blankValue blankExecOpt = ToolShed.Options.blankValue defaultCompOpt = ToolShed.Defaultable.defaultValue defaultExecOpt = ToolShed.Defaultable.defaultValue- setExecOpts e r = r { RegExOpts.executionOptions = e }- getExecOpts = RegExOpts.executionOptions+ setExecOpts e r = r { RegExDot.RegExOpts.executionOptions = e }+ getExecOpts = RegExDot.RegExOpts.executionOptions --Newer versions of this 'Text.Regex.Base.RegexLike.RegexMaker' have additional monadic methods, which can fail on parse-errors.-instance RegexLike.RegexMaker RegExOptsChar CompilationOptions.CompilationOptions ExecutionOptions.ExecutionOptions String where- makeRegexOpts c e source = RegExOpts.MkRegExOpts {- RegExOpts.compilationOptions = c,- RegExOpts.executionOptions = e,- RegExOpts.regEx = read source+instance RegexLike.RegexMaker RegExOptsChar RegExDot.CompilationOptions.CompilationOptions RegExDot.ExecutionOptions.ExecutionOptions String where+ makeRegexOpts c e source = RegExDot.RegExOpts.MkRegExOpts {+ RegExDot.RegExOpts.compilationOptions = c,+ RegExDot.RegExOpts.executionOptions = e,+ RegExDot.RegExOpts.regEx = read source } --- | The offset and length of the 'RegEx.InputData' consumed in one 'RegEx.Match'.+-- | The offset and length of the 'RegExDot.RegEx.InputData' consumed in one 'RegExDot.RegEx.Match'. type MatchSpan = (RegexLike.MatchOffset, RegexLike.MatchLength) {- | * The 'MatchSpan' augmented by the consumed 'ExtendedRegExChar.InputData' to which it refers. - * Similar to 'DataSpan.DataSpan'.+ * Similar to 'RegExDot.DataSpan.DataSpan'. -} type MatchDataSpan = (ExtendedRegExChar.InputData, MatchSpan) {- |- * Convert the 'RegEx.MatchList', into the 'MatchDataSpan's required by "Text.Regex.Base.RegexLike".+ * Convert the 'RegExDot.RegEx.MatchList', into the 'MatchDataSpan's required by "Text.Regex.Base.RegexLike". * Treat the whole 'ExtendedRegExChar.ExtendedRegExChar' as an additional implicit capture-group. - * CAVEAT: @DataSpanTree.extractCaptureGroups True@ may return some 'DataSpan.DataSpan's containing the artificial offset @-1@ specified by Posix => don't use this as the basis for any arithmetic.+ * CAVEAT: @RegExDot.DataSpanTree.extractCaptureGroups True@ may return some 'RegExDot.DataSpan.DataSpan's containing the artificial offset @-1@ specified by Posix => don't use this as the basis for any arithmetic. -} toMatchDataSpanList :: Bool- -> ConsumptionBounds.DataLength -- ^ The offset to use for zero-length match.- -> RegEx.MatchList Char -- ^ The list of matches.+ -> RegExDot.ConsumptionBounds.DataLength -- ^ The offset to use for zero-length match.+ -> RegExDot.RegEx.MatchList Char -- ^ The list of matches. -> [MatchDataSpan]-toMatchDataSpanList _ offset [] = [DataSpan.empty offset] --The whole regex matched, but consumed nothing.-toMatchDataSpanList strictPosixCompliance _ matchList = DataSpanTree.extractCaptureGroups strictPosixCompliance . return {-to List-monad-} . Tree.Node . return {-to List-monad-} $ DataSpanTree.toTreeList matchList+toMatchDataSpanList _ offset [] = [RegExDot.DataSpan.empty offset] --The whole regex matched, but consumed nothing.+toMatchDataSpanList strictPosixCompliance _ matchList = RegExDot.DataSpanTree.extractCaptureGroups strictPosixCompliance . return {-to List-monad-} . RegExDot.Tree.Node . return {-to List-monad-} $ RegExDot.DataSpanTree.toTreeList matchList -- | Optionally remove the 2nd element from the list, where it represents the data captured by a groups of top-level 'Alternatives', which weren't explicitly delimited & therefore are non-capturing. exciseNonCapturingTopLevelAlternatives :: RegExOptsChar -> [MatchDataSpan] -> [MatchDataSpan]@@ -139,18 +139,18 @@ matchUntilFailure :: RegExOptsChar -- ^ The match-criteria. -> ExtendedRegExChar.InputData -- ^ The input-data, to be consumed by repeated matching.- -> [RegEx.MatchList Char]+ -> [RegExDot.RegEx.MatchList Char] matchUntilFailure regExOptsChar inputData = shiftOffsets 0 $ matchUntilFailure' inputData where- matchUntilFailure' :: ExtendedRegExChar.InputData -> [RegEx.MatchList Char]+ matchUntilFailure' :: ExtendedRegExChar.InputData -> [RegExDot.RegEx.MatchList Char] matchUntilFailure' unmatchedInputData = case unmatchedInputData ExtendedRegExChar.+~ regExOptsChar of --CAVEAT: <http://hackage.haskell.org/trac/haskell-prime/wiki/QualifiedOperators>.- (_, Just matchList, maybeSternAnchorResult) -> matchList : if null (RegEx.extractDataFromMatchList matchList) then [] else matchUntilFailure' (RegEx.extractDataFromMatch' maybeSternAnchorResult)+ (_, Just matchList, maybeSternAnchorResult) -> matchList : if null (RegExDot.RegEx.extractDataFromMatchList matchList) then [] else matchUntilFailure' (RegExDot.RegEx.extractDataFromMatch' maybeSternAnchorResult) _ -> [] - shiftOffsets :: ConsumptionBounds.DataLength -> [RegEx.MatchList Char] -> [RegEx.MatchList Char]+ shiftOffsets :: RegExDot.ConsumptionBounds.DataLength -> [RegExDot.RegEx.MatchList Char] -> [RegExDot.RegEx.MatchList Char] shiftOffsets offset (matchList : matchLists) = let- shiftedMatchList :: RegEx.MatchList Char- shiftedMatchList = RegEx.shiftMatchList offset matchList- in shiftedMatchList : shiftOffsets (DataSpan.after . last . DataSpanTree.flattenTreeList 0 $ DataSpanTree.toTreeList shiftedMatchList) matchLists {-recurse-}+ shiftedMatchList :: RegExDot.RegEx.MatchList Char+ shiftedMatchList = RegExDot.RegEx.shiftMatchList offset matchList+ in shiftedMatchList : shiftOffsets (RegExDot.DataSpan.after . last . RegExDot.DataSpanTree.flattenTreeList 0 $ RegExDot.DataSpanTree.toTreeList shiftedMatchList) matchLists {-recurse-} shiftOffsets _ _ = [] instance RegexLike.RegexLike RegExOptsChar ExtendedRegExChar.InputData where@@ -176,9 +176,9 @@ matchOnce regExOptsChar inputData = toZeroIndexedArray . map snd {-span-} . exciseNonCapturingTopLevelAlternatives regExOptsChar . toMatchDataSpanList ( complyStrictlyWithPosix regExOptsChar ) (- RegEx.externalMatchLength $ Result.getPreMatch extendedRegExResult- ) <$> Result.getMatchList extendedRegExResult where- extendedRegExResult :: RegEx.Result Char+ RegExDot.RegEx.externalMatchLength $ RegExDot.Result.getPreMatch extendedRegExResult+ ) <$> RegExDot.Result.getMatchList extendedRegExResult where+ extendedRegExResult :: RegExDot.RegEx.Result Char extendedRegExResult = inputData ExtendedRegExChar.+~ regExOptsChar --CAVEAT: <http://hackage.haskell.org/trac/haskell-prime/wiki/QualifiedOperators>. {- E.g.:@@ -188,15 +188,15 @@ -- matchOnceText :: RegExOptsChar -> ExtendedRegExChar.InputData -> Maybe (ExtendedRegExChar.InputData, MatchText ExtendedRegExChar.InputData, ExtendedRegExChar.InputData) matchOnceText regExOptsChar inputData = case inputData ExtendedRegExChar.+~ regExOptsChar of --CAVEAT: <http://hackage.haskell.org/trac/haskell-prime/wiki/QualifiedOperators>. (maybeBowAnchorResult, Just matchList, maybeSternAnchorResult) -> Just (- RegEx.extractDataFromMatch' maybeBowAnchorResult,+ RegExDot.RegEx.extractDataFromMatch' maybeBowAnchorResult, toZeroIndexedArray . exciseNonCapturingTopLevelAlternatives regExOptsChar $ toMatchDataSpanList ( complyStrictlyWithPosix regExOptsChar ) (- RegEx.externalMatchLength maybeBowAnchorResult+ RegExDot.RegEx.externalMatchLength maybeBowAnchorResult ) matchList,- RegEx.extractDataFromMatch' maybeSternAnchorResult+ RegExDot.RegEx.extractDataFromMatch' maybeSternAnchorResult )- _ -> Nothing+ _ -> Nothing {- E.g.: ("xabcdx" RegExOptsChar.=~ "a(b(c?))*d") :: Bool