grammatical-parsers 0.7.1 → 0.7.2
raw patch · 9 files changed
+63/−36 lines, 9 filesdep ~containersdep ~witherablePVP ok
version bump matches the API change (PVP)
Dependency ranges changed: containers, witherable
API changes (from Hackage documentation)
+ Text.Grampa.Combinators: takeSomeNonEmpty :: DeterministicParsing p => p a -> p (NonEmpty a)
Files
- CHANGELOG.md +7/−0
- README.md +6/−6
- examples/Combined.hs +18/−9
- grammatical-parsers.cabal +9/−9
- src/Text/Grampa.hs +6/−4
- src/Text/Grampa/Class.hs +1/−0
- src/Text/Grampa/Combinators.hs +7/−2
- src/Text/Grampa/Internal.hs +3/−0
- test/README.lhs +6/−6
CHANGELOG.md view
@@ -1,3 +1,10 @@+Version 0.7.2+---------------+* Added `Combinators.takeSomeNonEmpty`+* Updated CI configuration+* Bumped the upper bounds of the `witherable` and `containers` dependencies+* Slightly improved documentation+ Version 0.7.1 --------------- * Added a Show instance for every Show1 to satisfy the new class declaration
README.md view
@@ -22,9 +22,9 @@ import qualified Rank2.TH ~~~ -What puts this library apart from most is that these parsers are *grammatical*, just as the library name says. Instead-of writing the parser definitions as top-level bindings, you can and should group them into a grammar record definition,-like this:+What puts this library apart from most is that the parsers it allows you to construct are *grammatical*, just as the+library name says. Instead of writing the parser definitions as top-level bindings, you can and should group them into+a grammar record definition, like this: ~~~ {.haskell} arithmetic :: Rank2.Apply g => GrammarBuilder Arithmetic g Parser String@@ -41,9 +41,9 @@ number= takeCharsWhile1 isDigit <?> "number"} ~~~ -What on Earth for? One good reason is that these parser definitions can then be left-recursive, which is normally a-death knell for parser libraries. There are other benefits like memoization and grammar composability, and the main-downside is the obligation to declare the grammar record:+What on Earth for? One good reason is that these parser definitions can then be left-recursive, which is usually+deadly for parser combinator libraries. There are other benefits like memoization and grammar composability, and the+main downside is the obligation to declare the grammar record: ~~~ {.haskell} data Arithmetic f = Arithmetic{sum :: f Int,
examples/Combined.hs view
@@ -18,6 +18,8 @@ import qualified Conditionals import qualified Lambda +-- | Grammar that combines arithmetic, boolean, comparison, conditional, and lambda expression grammars. The first+-- three productions are used to bind them all together, see 'expression' below. data Expression f = Expression{ expr :: f Domain,@@ -29,6 +31,7 @@ conditionalGrammar :: Conditionals.Conditionals Domain Domain f, lambdaGrammar :: Lambda.Lambda Domain f} +-- | The combined domain result type tags different component results with their type. data Tagged = IntExpression {intFromExpression :: Int} | BoolExpression {boolFromExpression :: Bool} | FunctionExpression {functionFromExpression :: Tagged -> Tagged}@@ -37,6 +40,7 @@ type Env = Map String Tagged +-- | The semantic domain of the parsed expression type Domain = Env -> Tagged instance Eq (Tagged -> Tagged) where@@ -125,7 +129,8 @@ instance TokenParsing (Parser Expression String) instance LexicalParsing (Parser Expression String) -{-+{- The Rank.TH.deriveAll splice above inserts the following declarations:+ instance Rank2.Functor Expression where f <$> g = g{expr= f (expr g), term= f (term g),@@ -206,12 +211,16 @@ in Expression{expr= combinedExpr, term= combinedTerm, primary= combinedPrimary,- arithmeticGrammar= Arithmetic.arithmetic arithmeticGrammar{Arithmetic.expr= expr,- Arithmetic.primary= primary},+ arithmeticGrammar= Arithmetic.arithmetic arithmeticGrammar{+ Arithmetic.expr= expr,+ Arithmetic.primary= primary}, booleanGrammar= Boolean.boolean (Comparisons.test comparisonGrammar) booleanGrammar,- comparisonGrammar= Comparisons.comparisons comparisonGrammar{Comparisons.term= Arithmetic.expr arithmeticGrammar},- conditionalGrammar= Conditionals.conditionals conditionalGrammar{Conditionals.test= Boolean.expr booleanGrammar,- Conditionals.term= expr},- lambdaGrammar= Lambda.lambdaCalculus lambdaGrammar{Lambda.expr= expr,- Lambda.application= term,- Lambda.primary= primary}}+ comparisonGrammar= Comparisons.comparisons comparisonGrammar{+ Comparisons.term= Arithmetic.expr arithmeticGrammar},+ conditionalGrammar= Conditionals.conditionals conditionalGrammar{+ Conditionals.test= Boolean.expr booleanGrammar,+ Conditionals.term= expr},+ lambdaGrammar= Lambda.lambdaCalculus lambdaGrammar{+ Lambda.expr= expr,+ Lambda.application= term,+ Lambda.primary= primary}}
grammatical-parsers.cabal view
@@ -1,5 +1,5 @@ name: grammatical-parsers-version: 0.7.1+version: 0.7.2 synopsis: parsers that combine into grammars description: /Gram/matical-/pa/rsers, or Grampa for short, is a library of parser types whose values are meant to be assigned@@ -16,7 +16,7 @@ category: Text, Parsing build-type: Custom cabal-version: >=1.10-tested-with: GHC==9.2.2, GHC==9.0.2, GHC==8.10.4, GHC==8.8.4, GHC==8.6.5, GHC==8.4.4, GHC==8.2.2+tested-with: GHC==9.8.2, GHC==9.6.4, GHC==9.4.8, GHC==9.2.8, GHC==9.0.2, GHC==8.10.7 extra-source-files: README.md, CHANGELOG.md source-repository head type: git@@ -49,13 +49,13 @@ default-language: Haskell2010 ghc-options: -Wall build-depends: base >=4.9 && <5,- containers >= 0.4 && < 0.7,+ containers >= 0.4 && < 0.8, transformers >= 0.5 && < 0.7, monoid-subclasses >=1.0 && <1.3, parsers < 0.13, input-parsers < 0.4, attoparsec >= 0.13 && < 0.15,- witherable == 0.4.*,+ witherable >= 0.4 && < 0.6, rank2classes >= 1.4.6 && < 1.6 executable arithmetic@@ -63,7 +63,7 @@ main-is: Main.hs other-modules: Arithmetic, Boolean, Combined, Comparisons, Conditionals, Lambda, Utilities default-language: Haskell2010- build-depends: base >=4.9 && <5, containers >= 0.5.7.0 && < 0.7,+ build-depends: base >=4.9 && <5, containers >= 0.5.7.0 && < 0.8, parsers < 0.13, rank2classes >= 1.0.2 && < 1.6, grammatical-parsers, monoid-subclasses@@ -73,7 +73,7 @@ main-is: BooleanTransformations.hs other-modules: Boolean, Utilities default-language: Haskell2010- build-depends: base >=4.9 && <5, containers >= 0.5.7.0 && < 0.7,+ build-depends: base >=4.9 && <5, containers >= 0.5.7.0 && < 0.8, parsers < 0.13, rank2classes >= 1.0.2 && < 1.6, grammatical-parsers, monoid-subclasses@@ -82,9 +82,9 @@ type: exitcode-stdio-1.0 hs-source-dirs: test, examples x-uses-tf: true- build-depends: base >=4.9 && < 5, containers >= 0.5.7.0 && < 0.7,+ build-depends: base >=4.9 && < 5, containers >= 0.5.7.0 && < 0.8, monoid-subclasses, parsers < 0.13,- witherable == 0.4.*,+ witherable >= 0.4 && < 0.6, rank2classes >= 1.0.2 && < 1.6, grammatical-parsers, QuickCheck >= 2 && < 3, checkers >= 0.4.6 && < 0.6, tasty >= 0.7, tasty-quickcheck >= 0.7@@ -109,7 +109,7 @@ ghc-options: -O2 -Wall -rtsopts -main-is Benchmark.main Build-Depends: base >=4.9 && < 5, rank2classes >= 1.0.2 && < 1.6, grammatical-parsers, monoid-subclasses, parsers < 0.13,- criterion >= 1.0, deepseq >= 1.1, containers >= 0.5.7.0 && < 0.7, text >= 1.1+ criterion >= 1.0, deepseq >= 1.1, containers >= 0.5.7.0 && < 0.8, text >= 1.1 main-is: Benchmark.hs other-modules: Main, Arithmetic, Boolean, Combined, Comparisons, Conditionals, Lambda, Utilities default-language: Haskell2010
src/Text/Grampa.hs view
@@ -50,12 +50,14 @@ import Prelude hiding (drop, null) --- | Fixed grammar record type @g@ with a given parser type @p@ on input streams of type @s@+-- | A grammar is a record type @g@ whose fields are parsers of type @p@ on input streams of type @s@. A value of a+-- @Grammar@ type is typically produced by applying 'fixGrammar' or 'overlay' to a 'GrammarBuilder'. type Grammar (g :: (Type -> Type) -> Type) p s = g (p g s) --- | A @GrammarBuilder g g' p s@ is an endomorphic function on a grammar @g@, whose parsers of type @p@ build grammars--- of type @g'@, parsing input streams of type @s@. The first grammar @g@ may be a building block for the final--- grammar @g'@.+-- | A @GrammarBuilder g g' p s@ is an endomorphic function on a grammar @g@, whose parsers of type @p@ build on+-- grammars of type @g'@ and parse an input stream of type @s@. Grammar parameters @g@ and @g'@ are typically+-- identical in simple monolithic grammars, but when composing complex grammars the first grammar parameter @g@ would+-- be just a building block for the final grammar @g'@. type GrammarBuilder (g :: (Type -> Type) -> Type) (g' :: (Type -> Type) -> Type) (p :: ((Type -> Type) -> Type) -> Type -> Type -> Type)
src/Text/Grampa/Class.hs view
@@ -35,6 +35,7 @@ import Prelude hiding (takeWhile) +-- | A parse results in either a 'ParseFailure' or the result of the appropriate type. type ParseResults s = Either (ParseFailure Pos s) -- | A 'ParseFailure' contains the offset of the parse failure and the list of things expected at that offset.
src/Text/Grampa/Combinators.hs view
@@ -1,6 +1,6 @@ {-# LANGUAGE TypeFamilies, TypeOperators #-} -- | A collection of useful parsing combinators not found in dependent libraries.-module Text.Grampa.Combinators (moptional, concatMany, concatSome, someNonEmpty,+module Text.Grampa.Combinators (moptional, concatMany, concatSome, someNonEmpty, takeSomeNonEmpty, flag, count, upto, delimiter, operator, keyword) where @@ -11,7 +11,8 @@ import Data.Semigroup (Semigroup(sconcat)) import Data.Semigroup.Cancellative (LeftReductive) -import Text.Grampa.Class (InputParsing(ParserInput, string), LexicalParsing(lexicalToken, keyword))+import Text.Grampa.Class (InputParsing(ParserInput, string), LexicalParsing(lexicalToken, keyword),+ DeterministicParsing(takeMany)) import Text.Parser.Combinators (Parsing((<?>)), count) -- | Attempts to parse a monoidal value, if the argument parser fails returns 'mempty'.@@ -29,6 +30,10 @@ -- | One or more argument occurrences like 'some', returned in a 'NonEmpty' list. someNonEmpty :: Alternative p => p a -> p (NonEmpty a) someNonEmpty p = (:|) <$> p <*> many p++-- | The longest sequence of One or more argument occurrences like 'takeSome', returned in a 'NonEmpty' list.+takeSomeNonEmpty :: DeterministicParsing p => p a -> p (NonEmpty a)+takeSomeNonEmpty p = (:|) <$> p <*> takeMany p -- | Returns 'True' if the argument parser succeeds and 'False' otherwise. flag :: Alternative p => p a -> p Bool
src/Text/Grampa/Internal.hs view
@@ -181,8 +181,11 @@ failureOf (ResultList _ failure) = failure failWith = ResultList [] +-- | The class of parsers whose execution can be traced for debugging purposes class InputParsing m => TraceableParsing m where+ -- | Modify the argument parser to log its input whenever invoked. traceInput :: (ParserInput m -> String) -> m a -> m a+ -- | Modify the argument parser to log the given description and its input whenever invoked. traceAs :: Show (ParserInput m) => String -> m a -> m a traceAs description = traceInput (\input-> description <> " @ " <> show input)
test/README.lhs view
@@ -22,9 +22,9 @@ import qualified Rank2.TH ~~~ -What puts this library apart from most is that these parsers are *grammatical*, just as the library name says. Instead-of writing the parser definitions as top-level bindings, you can and should group them into a grammar record definition,-like this:+What puts this library apart from most is that the parsers it allows you to construct are *grammatical*, just as the+library name says. Instead of writing the parser definitions as top-level bindings, you can and should group them into+a grammar record definition, like this: ~~~ {.haskell} arithmetic :: Rank2.Apply g => GrammarBuilder Arithmetic g Parser String@@ -41,9 +41,9 @@ number= takeCharsWhile1 isDigit <?> "number"} ~~~ -What on Earth for? One good reason is that these parser definitions can then be left-recursive, which is normally a-death knell for parser libraries. There are other benefits like memoization and grammar composability, and the main-downside is the obligation to declare the grammar record:+What on Earth for? One good reason is that these parser definitions can then be left-recursive, which is usually+deadly for parser combinator libraries. There are other benefits like memoization and grammar composability, and the+main downside is the obligation to declare the grammar record: ~~~ {.haskell} data Arithmetic f = Arithmetic{sum :: f Int,