config-value 0.5.1 → 0.6
raw patch · 9 files changed
+275/−208 lines, 9 filesdep ~basePVP ok
version bump matches the API change (PVP)
Dependency ranges changed: base
API changes (from Hackage documentation)
+ Config: ParseError :: Position -> String -> ParseError
+ Config: Position :: {-# UNPACK #-} !Int -> Position
+ Config: [posIndex, posLine, posColumn] :: Position -> {-# UNPACK #-} !Int
+ Config: [sectionAnn] :: Section a -> a
+ Config: data ParseError
+ Config: data Position
+ Config: instance GHC.Classes.Eq Config.ParseError
+ Config: instance GHC.Classes.Ord Config.ParseError
+ Config: instance GHC.Exception.Exception Config.ParseError
+ Config: instance GHC.Read.Read Config.ParseError
+ Config: instance GHC.Show.Show Config.ParseError
+ Config: valueAnn :: Value a -> a
+ Config.Lens: ann :: Functor f => (a -> f a) -> Value a -> f (Value a)
- Config: Atom :: Atom -> Value
+ Config: Atom :: a -> Atom -> Value a
- Config: Floating :: Integer -> Integer -> Value
+ Config: Floating :: a -> Integer -> Integer -> Value a
- Config: List :: [Value] -> Value
+ Config: List :: a -> [Value a] -> Value a
- Config: Number :: Int -> Integer -> Value
+ Config: Number :: a -> Int -> Integer -> Value a
- Config: Section :: Text -> Value -> Section
+ Config: Section :: a -> Text -> Value a -> Section a
- Config: Sections :: [Section] -> Value
+ Config: Sections :: a -> [Section a] -> Value a
- Config: Text :: Text -> Value
+ Config: Text :: a -> Text -> Value a
- Config: [sectionName] :: Section -> Text
+ Config: [sectionName] :: Section a -> Text
- Config: [sectionValue] :: Section -> Value
+ Config: [sectionValue] :: Section a -> Value a
- Config: data Section
+ Config: data Section a
- Config: data Value
+ Config: data Value a
- Config: parse :: Text -> Either String Value
+ Config: parse :: Text -> Either ParseError (Value Position)
- Config: pretty :: Value -> Doc
+ Config: pretty :: Value a -> Doc
- Config.Lens: atom :: Applicative f => (Atom -> f Atom) -> Value -> f Value
+ Config.Lens: atom :: Applicative f => (Atom -> f Atom) -> Value a -> f (Value a)
- Config.Lens: key :: Applicative f => Text -> (Value -> f Value) -> Value -> f Value
+ Config.Lens: key :: Applicative f => Text -> (Value a -> f (Value a)) -> Value a -> f (Value a)
- Config.Lens: list :: Applicative f => ([Value] -> f [Value]) -> Value -> f Value
+ Config.Lens: list :: Applicative f => ([Value a] -> f [Value a]) -> Value a -> f (Value a)
- Config.Lens: number :: Applicative f => (Integer -> f Integer) -> Value -> f Value
+ Config.Lens: number :: Applicative f => (Integer -> f Integer) -> Value a -> f (Value a)
- Config.Lens: sections :: Applicative f => ([Section] -> f [Section]) -> Value -> f Value
+ Config.Lens: sections :: Applicative f => ([Section a] -> f [Section a]) -> Value a -> f (Value a)
- Config.Lens: text :: Applicative f => (Text -> f Text) -> Value -> f Value
+ Config.Lens: text :: Applicative f => (Text -> f Text) -> Value a -> f (Value a)
- Config.Lens: values :: Applicative f => (Value -> f Value) -> Value -> f Value
+ Config.Lens: values :: Applicative f => (Value a -> f (Value a)) -> Value a -> f (Value a)
Files
- CHANGELOG.md +5/−0
- config-value.cabal +2/−2
- dist/build/Config/Parser.hs +83/−67
- src/Config.hs +51/−33
- src/Config/Lens.hs +34/−22
- src/Config/Parser.y +47/−34
- src/Config/Pretty.hs +17/−17
- src/Config/Tokens.hs +1/−1
- src/Config/Value.hs +35/−32
CHANGELOG.md view
@@ -1,3 +1,8 @@+0.6+---+* Annotate `Value` with file positions+* Derive `Generic1` instances for `Value`+ 0.5.1 --- * Allow trailing commas in lists and section lists
config-value.cabal view
@@ -1,5 +1,5 @@ name: config-value-version: 0.5.1+version: 0.6 synopsis: Simple, layout-based value language similar to YAML or JSON license: MIT license-file: LICENSE@@ -32,7 +32,7 @@ Config.Pretty, Config.Value - build-depends: base >= 4.5 && < 4.11,+ build-depends: base >= 4.8 && < 4.11, array >= 0.4 && < 0.6, pretty >= 1.1.1.0 && < 1.2, text >= 1.2.0.4 && < 1.3
dist/build/Config/Parser.hs view
@@ -5,7 +5,7 @@ module Config.Parser (parseValue) where import Config.Value (Section(..), Value(..), Atom(..))-import Config.Tokens (Located(..), Token)+import Config.Tokens (Located(..), Token, Position) import qualified Config.Tokens as T import qualified Data.Array as Happy_Data_Array import qualified Data.Bits as Bits@@ -21,64 +21,64 @@ #else type HappyAny = forall a . a #endif-happyIn4 :: (Value) -> (HappyAbsSyn )+happyIn4 :: (Value Position) -> (HappyAbsSyn ) happyIn4 x = Happy_GHC_Exts.unsafeCoerce# x {-# INLINE happyIn4 #-}-happyOut4 :: (HappyAbsSyn ) -> (Value)+happyOut4 :: (HappyAbsSyn ) -> (Value Position) happyOut4 x = Happy_GHC_Exts.unsafeCoerce# x {-# INLINE happyOut4 #-}-happyIn5 :: (Value) -> (HappyAbsSyn )+happyIn5 :: (Value Position) -> (HappyAbsSyn ) happyIn5 x = Happy_GHC_Exts.unsafeCoerce# x {-# INLINE happyIn5 #-}-happyOut5 :: (HappyAbsSyn ) -> (Value)+happyOut5 :: (HappyAbsSyn ) -> (Value Position) happyOut5 x = Happy_GHC_Exts.unsafeCoerce# x {-# INLINE happyOut5 #-}-happyIn6 :: (Value) -> (HappyAbsSyn )+happyIn6 :: (Value Position) -> (HappyAbsSyn ) happyIn6 x = Happy_GHC_Exts.unsafeCoerce# x {-# INLINE happyIn6 #-}-happyOut6 :: (HappyAbsSyn ) -> (Value)+happyOut6 :: (HappyAbsSyn ) -> (Value Position) happyOut6 x = Happy_GHC_Exts.unsafeCoerce# x {-# INLINE happyOut6 #-}-happyIn7 :: ([Section]) -> (HappyAbsSyn )+happyIn7 :: ([Section Position]) -> (HappyAbsSyn ) happyIn7 x = Happy_GHC_Exts.unsafeCoerce# x {-# INLINE happyIn7 #-}-happyOut7 :: (HappyAbsSyn ) -> ([Section])+happyOut7 :: (HappyAbsSyn ) -> ([Section Position]) happyOut7 x = Happy_GHC_Exts.unsafeCoerce# x {-# INLINE happyOut7 #-}-happyIn8 :: ([Section]) -> (HappyAbsSyn )+happyIn8 :: ([Section Position]) -> (HappyAbsSyn ) happyIn8 x = Happy_GHC_Exts.unsafeCoerce# x {-# INLINE happyIn8 #-}-happyOut8 :: (HappyAbsSyn ) -> ([Section])+happyOut8 :: (HappyAbsSyn ) -> ([Section Position]) happyOut8 x = Happy_GHC_Exts.unsafeCoerce# x {-# INLINE happyOut8 #-}-happyIn9 :: ([Section]) -> (HappyAbsSyn )+happyIn9 :: ([Section Position]) -> (HappyAbsSyn ) happyIn9 x = Happy_GHC_Exts.unsafeCoerce# x {-# INLINE happyIn9 #-}-happyOut9 :: (HappyAbsSyn ) -> ([Section])+happyOut9 :: (HappyAbsSyn ) -> ([Section Position]) happyOut9 x = Happy_GHC_Exts.unsafeCoerce# x {-# INLINE happyOut9 #-}-happyIn10 :: (Section) -> (HappyAbsSyn )+happyIn10 :: (Section Position) -> (HappyAbsSyn ) happyIn10 x = Happy_GHC_Exts.unsafeCoerce# x {-# INLINE happyIn10 #-}-happyOut10 :: (HappyAbsSyn ) -> (Section)+happyOut10 :: (HappyAbsSyn ) -> (Section Position) happyOut10 x = Happy_GHC_Exts.unsafeCoerce# x {-# INLINE happyOut10 #-}-happyIn11 :: ([Value]) -> (HappyAbsSyn )+happyIn11 :: ([Value Position]) -> (HappyAbsSyn ) happyIn11 x = Happy_GHC_Exts.unsafeCoerce# x {-# INLINE happyIn11 #-}-happyOut11 :: (HappyAbsSyn ) -> ([Value])+happyOut11 :: (HappyAbsSyn ) -> ([Value Position]) happyOut11 x = Happy_GHC_Exts.unsafeCoerce# x {-# INLINE happyOut11 #-}-happyIn12 :: ([Value]) -> (HappyAbsSyn )+happyIn12 :: ([Value Position]) -> (HappyAbsSyn ) happyIn12 x = Happy_GHC_Exts.unsafeCoerce# x {-# INLINE happyIn12 #-}-happyOut12 :: (HappyAbsSyn ) -> ([Value])+happyOut12 :: (HappyAbsSyn ) -> ([Value Position]) happyOut12 x = Happy_GHC_Exts.unsafeCoerce# x {-# INLINE happyOut12 #-}-happyIn13 :: ([Value]) -> (HappyAbsSyn )+happyIn13 :: ([Value Position]) -> (HappyAbsSyn ) happyIn13 x = Happy_GHC_Exts.unsafeCoerce# x {-# INLINE happyIn13 #-}-happyOut13 :: (HappyAbsSyn ) -> ([Value])+happyOut13 :: (HappyAbsSyn ) -> ([Value Position]) happyOut13 x = Happy_GHC_Exts.unsafeCoerce# x {-# INLINE happyOut13 #-} happyInTok :: (Located Token) -> (HappyAbsSyn )@@ -90,7 +90,7 @@ happyExpList :: HappyAddr-happyExpList = HappyA# "\x00\xe0\x4f\x00\x00\xfe\x04\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x03\x00\xfe\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe0\x4f\x00\x00\xbc\x04\x00\x20\x00\x00\x00\x00\x00\x00\x00\x80\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe0\x4f\x00\x00\xbc\x04\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"#+happyExpList = HappyA# "\x00\xe0\x4f\x00\x00\xfe\x04\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\xe0\x4f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfe\x04\x00\xc0\x4b\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\xc0\x4b\x00\x00\x00\x00\x00\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe0\x4f\x00\x00\x00\x00\x00\x00\x00"# {-# NOINLINE happyExpListPerState #-} happyExpListPerState st =@@ -106,19 +106,19 @@ f (True, nr) = [token_strs !! nr] happyActOffsets :: HappyAddr-happyActOffsets = HappyA# "\x01\x00\x01\x00\x30\x00\x00\x00\x14\x00\x00\x00\xfd\xff\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x0a\x00\x3b\x00\x2e\x00\x2b\x00\x2d\x00\x00\x00\x00\x00\x25\x00\x27\x00\x00\x00\x00\x00\x22\x00\x00\x00\x26\x00\x00\x00\x00\x00\x00\x00\x01\x00\x0a\x00\x00\x00\x26\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"#+happyActOffsets = HappyA# "\x01\x00\x01\x00\x2d\x00\x00\x00\x06\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x0a\x00\x2f\x00\x27\x00\x2a\x00\x22\x00\x00\x00\x00\x00\x26\x00\x21\x00\x00\x00\xfd\xff\x00\x00\x23\x00\x00\x00\x00\x00\x00\x00\x1d\x00\x00\x00\x0a\x00\x00\x00\x1b\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00"# happyGotoOffsets :: HappyAddr-happyGotoOffsets = HappyA# "\x15\x00\x31\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x2a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x23\x00\x11\x00\x35\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x1c\x00\x0e\x00\x00\x00\xfb\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"#+happyGotoOffsets = HappyA# "\x1f\x00\x31\x00\x00\x00\x00\x00\x00\x00\x00\x00\x2b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17\x00\x0e\x00\x34\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x15\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x13\x00\x00\x00\xfb\xff\x00\x00\x00\x00\x00\x00\x25\x00\x00\x00\x00\x00"# happyDefActions :: HappyAddr-happyDefActions = HappyA# "\x00\x00\x00\x00\x00\x00\xfb\xff\x00\x00\xf4\xff\x00\x00\x00\x00\xf8\xff\xf7\xff\xfa\xff\xf9\xff\x00\x00\xea\xff\xf2\xff\x00\x00\x00\x00\xf1\xff\xef\xff\xe7\xff\x00\x00\xe9\xff\xec\xff\xed\xff\x00\x00\xfc\xff\x00\x00\xfd\xff\xfe\xff\xf3\xff\x00\x00\xe8\xff\xf5\xff\xf0\xff\xf6\xff\xee\xff\xe6\xff\xeb\xff"#+happyDefActions = HappyA# "\x00\x00\x00\x00\x00\x00\xfb\xff\x00\x00\xf4\xff\x00\x00\xf8\xff\xf7\xff\xfa\xff\xf9\xff\x00\x00\xea\xff\xf2\xff\x00\x00\x00\x00\xf1\xff\xef\xff\xe7\xff\x00\x00\xe9\xff\xec\xff\x00\x00\xed\xff\x00\x00\xfd\xff\xfe\xff\xf3\xff\x00\x00\xfc\xff\xe8\xff\xf5\xff\xf0\xff\xf6\xff\xee\xff\xe6\xff\x00\x00\xeb\xff"# happyCheck :: HappyAddr-happyCheck = HappyA# "\xff\xff\x06\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x0c\x00\x0d\x00\x0a\x00\x02\x00\x03\x00\x04\x00\x05\x00\x02\x00\x07\x00\x06\x00\x02\x00\x0a\x00\x00\x00\x01\x00\x02\x00\x03\x00\x08\x00\x09\x00\x06\x00\x07\x00\x01\x00\x02\x00\x03\x00\x0c\x00\x0d\x00\x06\x00\x07\x00\x01\x00\x02\x00\x03\x00\x01\x00\x06\x00\x06\x00\x07\x00\x01\x00\x02\x00\x03\x00\x09\x00\x08\x00\x06\x00\x07\x00\x01\x00\x02\x00\x03\x00\x08\x00\x0b\x00\x06\x00\x07\x00\x04\x00\x05\x00\x06\x00\x01\x00\x0f\x00\x0e\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"#+happyCheck = HappyA# "\xff\xff\x06\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x0c\x00\x0d\x00\x0a\x00\x02\x00\x03\x00\x04\x00\x05\x00\x02\x00\x07\x00\x0c\x00\x0d\x00\x0a\x00\x02\x00\x08\x00\x09\x00\x01\x00\x02\x00\x03\x00\x06\x00\x01\x00\x06\x00\x07\x00\x00\x00\x01\x00\x02\x00\x03\x00\x06\x00\x01\x00\x06\x00\x01\x00\x02\x00\x03\x00\x08\x00\x08\x00\x06\x00\x01\x00\x02\x00\x03\x00\x09\x00\x01\x00\x06\x00\x01\x00\x02\x00\x03\x00\x0b\x00\x0f\x00\x06\x00\x04\x00\x05\x00\x06\x00\x0e\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"# happyTable :: HappyAddr-happyTable = HappyA# "\x00\x00\x23\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x19\x00\x1a\x00\x0f\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x24\x00\x0e\x00\x1d\x00\x13\x00\x0f\x00\x0f\x00\x02\x00\x03\x00\x04\x00\x14\x00\x15\x00\x05\x00\x06\x00\x25\x00\x03\x00\x04\x00\x1b\x00\x1c\x00\x05\x00\x06\x00\x16\x00\x03\x00\x04\x00\x08\x00\x1f\x00\x05\x00\x06\x00\x17\x00\x03\x00\x04\x00\x21\x00\x20\x00\x05\x00\x06\x00\x02\x00\x03\x00\x04\x00\x22\x00\x23\x00\x05\x00\x06\x00\x10\x00\x11\x00\x12\x00\x08\x00\xff\xff\x1d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"#+happyTable = HappyA# "\x00\x00\x22\x00\x07\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x1d\x00\x1e\x00\x0e\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x12\x00\x0d\x00\x19\x00\x1a\x00\x0e\x00\x23\x00\x13\x00\x14\x00\x15\x00\x03\x00\x04\x00\x1b\x00\x07\x00\x05\x00\x16\x00\x0e\x00\x02\x00\x03\x00\x04\x00\x25\x00\x07\x00\x05\x00\x25\x00\x03\x00\x04\x00\x1f\x00\x21\x00\x05\x00\x17\x00\x03\x00\x04\x00\x20\x00\x07\x00\x05\x00\x02\x00\x03\x00\x04\x00\x22\x00\xff\xff\x05\x00\x0f\x00\x10\x00\x11\x00\x1b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"# happyReduceArr = Happy_Data_Array.array (1, 25) [ (1 , happyReduce_1),@@ -164,16 +164,18 @@ happy_x_1 = case happyOut7 happy_x_1 of { happy_var_1 -> happyIn5- (Sections (reverse happy_var_1)+ (sections happy_var_1 )} -happyReduce_3 = happySpecReduce_2 1# happyReduction_3-happyReduction_3 happy_x_2+happyReduce_3 = happySpecReduce_3 1# happyReduction_3+happyReduction_3 happy_x_3+ happy_x_2 happy_x_1- = case happyOut11 happy_x_1 of { happy_var_1 -> + = case happyOutTok happy_x_1 of { (Located happy_var_1 T.Bullet) -> + case happyOut11 happy_x_2 of { happy_var_2 -> happyIn5- (List (reverse happy_var_1)- )}+ (List happy_var_1 (reverse happy_var_2)+ )}} happyReduce_4 = happySpecReduce_1 1# happyReduction_4 happyReduction_4 happy_x_1@@ -184,49 +186,51 @@ happyReduce_5 = happySpecReduce_1 2# happyReduction_5 happyReduction_5 happy_x_1- = case happyOutTok happy_x_1 of { (Located _ happy_var_1@T.Number{}) -> + = case happyOutTok happy_x_1 of { happy_var_1 -> happyIn6- (number happy_var_1+ (number happy_var_1 )} happyReduce_6 = happySpecReduce_1 2# happyReduction_6 happyReduction_6 happy_x_1- = case happyOutTok happy_x_1 of { (Located _ happy_var_1@T.Floating{}) -> + = case happyOutTok happy_x_1 of { happy_var_1 -> happyIn6 (floating happy_var_1 )} happyReduce_7 = happySpecReduce_1 2# happyReduction_7 happyReduction_7 happy_x_1- = case happyOutTok happy_x_1 of { (Located _ (T.String happy_var_1)) -> + = case happyOutTok happy_x_1 of { happy_var_1 -> happyIn6- (Text happy_var_1+ (text happy_var_1 )} happyReduce_8 = happySpecReduce_1 2# happyReduction_8 happyReduction_8 happy_x_1- = case happyOutTok happy_x_1 of { (Located _ (T.Atom happy_var_1)) -> + = case happyOutTok happy_x_1 of { happy_var_1 -> happyIn6- (Atom (MkAtom happy_var_1)+ (atom happy_var_1 )} happyReduce_9 = happySpecReduce_3 2# happyReduction_9 happyReduction_9 happy_x_3 happy_x_2 happy_x_1- = case happyOut8 happy_x_2 of { happy_var_2 -> + = case happyOutTok happy_x_1 of { (Located happy_var_1 T.OpenMap) -> + case happyOut8 happy_x_2 of { happy_var_2 -> happyIn6- (Sections (reverse happy_var_2)- )}+ (Sections happy_var_1 (reverse happy_var_2)+ )}} happyReduce_10 = happySpecReduce_3 2# happyReduction_10 happyReduction_10 happy_x_3 happy_x_2 happy_x_1- = case happyOut12 happy_x_2 of { happy_var_2 -> + = case happyOutTok happy_x_1 of { (Located happy_var_1 T.OpenList) -> + case happyOut12 happy_x_2 of { happy_var_2 -> happyIn6- (List (reverse happy_var_2)- )}+ (List happy_var_1 (reverse happy_var_2)+ )}} happyReduce_11 = happySpecReduce_1 3# happyReduction_11 happyReduction_11 happy_x_1@@ -285,18 +289,17 @@ happyReduce_18 = happySpecReduce_2 6# happyReduction_18 happyReduction_18 happy_x_2 happy_x_1- = case happyOutTok happy_x_1 of { (Located _ (T.Section happy_var_1)) -> + = case happyOutTok happy_x_1 of { happy_var_1 -> case happyOut5 happy_x_2 of { happy_var_2 -> happyIn10- (Section happy_var_1 happy_var_2+ (section happy_var_1 happy_var_2 )}} -happyReduce_19 = happySpecReduce_2 7# happyReduction_19-happyReduction_19 happy_x_2- happy_x_1- = case happyOut5 happy_x_2 of { happy_var_2 -> +happyReduce_19 = happySpecReduce_1 7# happyReduction_19+happyReduction_19 happy_x_1+ = case happyOut5 happy_x_1 of { happy_var_1 -> happyIn11- ([happy_var_2]+ ([happy_var_1] )} happyReduce_20 = happyReduce 4# 7# happyReduction_20@@ -354,16 +357,16 @@ happyNewToken action sts stk (tk:tks) = let cont i = happyDoAction i tk action sts stk tks in case tk of {- Located _ (T.Section happy_dollar_dollar) -> cont 1#;- Located _ (T.String happy_dollar_dollar) -> cont 2#;- Located _ (T.Atom happy_dollar_dollar) -> cont 3#;- Located _ happy_dollar_dollar@T.Number{} -> cont 4#;- Located _ happy_dollar_dollar@T.Floating{} -> cont 5#;- Located _ T.Bullet -> cont 6#;- Located _ T.OpenList -> cont 7#;+ Located _ T.Section{} -> cont 1#;+ Located _ T.String{} -> cont 2#;+ Located _ T.Atom{} -> cont 3#;+ Located _ T.Number{} -> cont 4#;+ Located _ T.Floating{} -> cont 5#;+ Located happy_dollar_dollar T.Bullet -> cont 6#;+ Located happy_dollar_dollar T.OpenList -> cont 7#; Located _ T.Comma -> cont 8#; Located _ T.CloseList -> cont 9#;- Located _ T.OpenMap -> cont 10#;+ Located happy_dollar_dollar T.OpenMap -> cont 10#; Located _ T.CloseMap -> cont 11#; Located _ T.LayoutSep -> cont 12#; Located _ T.LayoutEnd -> cont 13#;@@ -392,23 +395,36 @@ -- | Convert number token to number value. This needs a custom -- function like this because there are two value matched from -- the constructor.-number :: Token -> Value-number = \(T.Number base val) -> Number base val+number :: Located Token -> Value Position+number = \(Located a (T.Number base val)) -> Number a base val -- | Convert floating token to floating value. This needs a custom -- function like this because there are two value matched from -- the constructor.-floating :: Token -> Value-floating = \(T.Floating coef expo) -> Floating coef expo+floating :: Located Token -> Value Position+floating = \(Located a (T.Floating coef expo)) -> Floating a coef expo +section :: Located Token -> Value Position -> Section Position+section = \(Located a (T.Section k)) v -> Section a k v++sections :: [Section Position] -> Value Position+sections xxs = Sections (sectionAnn x) (x:xs)+ where x:xs = reverse xxs++text :: Located Token -> Value Position+text = \(Located a (T.String x)) -> Text a x++atom :: Located Token -> Value Position+atom = \(Located a (T.Atom x)) -> Atom a (MkAtom x)+ errorP :: [Located Token] -> Either (Located Token) a errorP xs = Left (head xs) -- | Attempt to parse a layout annotated token stream or -- the token that caused the parse to fail. parseValue ::- [Located Token] {- ^ layout annotated token stream -} ->- Either (Located Token) Value {- ^ token at failure or result -}+ [Located Token] {- ^ layout annotated token stream -} ->+ Either (Located Token) (Value Position) {- ^ token at failure or result -} parseValue = config {-# LINE 1 "templates/GenericTemplate.hs" #-} {-# LINE 1 "templates/GenericTemplate.hs" #-}
src/Config.hs view
@@ -239,6 +239,7 @@ ( -- * Parsing parse+ , Position(..) -- * Pretty-printing , pretty@@ -247,53 +248,70 @@ , Section(..) , Value(..) , Atom(..)+ , valueAnn++ -- * Errors+ , ParseError(..) ) where -import Config.Value (Atom(..), Value(..), Section(..))-import Config.Parser (parseValue)-import Config.Pretty (pretty)-import Config.Lexer (scanTokens)-import Config.Tokens (Error(..), Position(..), Located(..), layoutPass, Token)+import Config.Value (Atom(..), Value(..), Section(..), valueAnn)+import Config.Parser (parseValue)+import Config.Pretty (pretty)+import Config.Lexer (scanTokens)+import Config.Tokens (Error(..), Position(..), Located(..), layoutPass, Token) import qualified Config.Tokens as T -import Numeric (showIntAtBase)-import Data.Char (intToDigit)-import Data.Text (Text)+import Control.Exception (Exception(..))+import Numeric (showIntAtBase)+import Data.Char (intToDigit)+import Data.Text (Text) import qualified Data.Text as Text -- | Parse a configuration file and return the result on the -- right, or the position of an error on the left.+--+-- The resulting value is annotated with source file locations.+-- -- Note: Text file lines are terminated by new-lines. parse ::- Text {- ^ source text -} ->- Either String Value {- ^ error message or parsed value -}+ Text {- ^ source text -} ->+ Either ParseError (Value Position) {- ^ error message or parsed value -} parse txt = case parseValue (layoutPass (scanTokens txt)) of Right x -> Right x- Left (Located posn token) -> Left (explain posn token)+ Left (Located posn token) -> Left (ParseError posn (explainToken token)) -explain :: Position -> Token -> String-explain posn token- = show (posLine posn) ++ ":"- ++ show (posColumn posn) ++ ": "- ++ case token of- T.Error e -> explainError e- T.Atom atom -> "parse error: unexpected atom: " ++ Text.unpack atom- T.String str -> "parse error: unexpected string: " ++ show (Text.unpack str)- T.Bullet -> "parse error: unexpected bullet '*'"- T.Comma -> "parse error: unexpected comma ','"- T.Section s -> "parse error: unexpected section: " ++ Text.unpack s- T.Number 2 n -> "parse error: unexpected number: 0b" ++ showIntAtBase 2 intToDigit n ""- T.Number 8 n -> "parse error: unexpected number: 0o" ++ showIntAtBase 8 intToDigit n ""- T.Number 16 n -> "parse error: unexpected number: 0x" ++ showIntAtBase 16 intToDigit n ""- T.Number _ n -> "parse error: unexpected number: " ++ showIntAtBase 10 intToDigit n ""- T.OpenList -> "parse error: unexpected start of list '['"- T.CloseList -> "parse error: unexpected end of list ']'"- T.OpenMap -> "parse error: unexpected start of section '{'"- T.CloseMap -> "parse error: unexpected end of section '}'"- T.LayoutSep -> "parse error: unexpected end of block"- T.LayoutEnd -> "parse error: unexpected end of block"- T.EOF -> "parse error: unexpected end of file"+-- | Error messages that can occur during parsing annotated with a file position.+data ParseError = ParseError Position String+ deriving (Read, Show, Eq, Ord)++-- | 'displayException' implements a pretty format+instance Exception ParseError where+ displayException (ParseError posn msg) =+ "line " ++ show (posLine posn) +++ " column " ++ show (posColumn posn) +++ ": " ++ msg++explainToken :: Token -> String+explainToken token =+ case token of+ T.Error e -> explainError e+ T.Atom atom -> "parse error: unexpected atom: `" ++ Text.unpack atom ++ "`"+ T.String str -> "parse error: unexpected string: " ++ show (Text.unpack str)+ T.Bullet -> "parse error: unexpected bullet '*'"+ T.Comma -> "parse error: unexpected comma ','"+ T.Section s -> "parse error: unexpected section: `" ++ Text.unpack s ++ "`"+ T.Number 2 n -> "parse error: unexpected number: 0b" ++ showIntAtBase 2 intToDigit n ""+ T.Number 8 n -> "parse error: unexpected number: 0o" ++ showIntAtBase 8 intToDigit n ""+ T.Number 16 n -> "parse error: unexpected number: 0x" ++ showIntAtBase 16 intToDigit n ""+ T.Number _ n -> "parse error: unexpected number: " ++ showIntAtBase 10 intToDigit n ""+ T.OpenList -> "parse error: unexpected start of list '['"+ T.CloseList -> "parse error: unexpected end of list ']'"+ T.OpenMap -> "parse error: unexpected start of section '{'"+ T.CloseMap -> "parse error: unexpected end of section '}'"+ T.LayoutSep -> "parse error: unexpected end of block"+ T.LayoutEnd -> "parse error: unexpected end of block"+ T.EOF -> "parse error: unexpected end of file" explainError :: Error -> String explainError e =
src/Config/Lens.hs view
@@ -9,6 +9,7 @@ , list , values , sections+ , ann ) where import Config.Value@@ -26,53 +27,64 @@ key :: Applicative f => Text {- ^ section name -} ->- (Value -> f Value) -> Value -> f Value-key i f (Sections xs) = Sections <$> traverse (section i f) xs-key _ _ v = pure v+ (Value a -> f (Value a)) -> Value a -> f (Value a)+key i f (Sections a xs) = Sections a <$> traverse (section i f) xs+key _ _ v = pure v -- | Apply a function to the 'Value' contained inside the given -- 'Value' when it is a section name matches the given name. section :: Applicative f => Text {- ^ section name -} ->- (Value -> f Value) -> Section -> f Section-section i f s@(Section j v) | i == j = Section j <$> f v- | otherwise = pure s+ (Value a -> f (Value a)) -> Section a -> f (Section a)+section i f s@(Section a j v) | i == j = Section a j <$> f v+ | otherwise = pure s -- | Apply a function to the ['Section'] contained inside the given -- 'Value' when it is a @Sections@.-sections :: Applicative f => ([Section] -> f [Section]) -> Value -> f Value-sections f (Sections xs) = Sections <$> f xs-sections _ v = pure v+sections :: Applicative f => ([Section a] -> f [Section a]) -> Value a -> f (Value a)+sections f (Sections a xs) = Sections a <$> f xs+sections _ v = pure v -- | Apply a function to the 'Text' contained inside the given -- 'Value' when it is a @Text@.-text :: Applicative f => (Text -> f Text) -> Value -> f Value-text f (Text t) = Text <$> f t-text _ v = pure v+text :: Applicative f => (Text -> f Text) -> Value a -> f (Value a)+text f (Text a t) = Text a <$> f t+text _ v = pure v -- | Apply a function to the 'Text' contained inside the given -- 'Value' when it is a @Text@. This traversal is only valid -- if the output atom is a valid atom!-atom :: Applicative f => (Atom -> f Atom) -> Value -> f Value-atom f (Atom t) = Atom <$> f t-atom _ v = pure v+atom :: Applicative f => (Atom -> f Atom) -> Value a -> f (Value a)+atom f (Atom a t) = Atom a <$> f t+atom _ v = pure v -- | Apply a function to the 'Integer' contained inside the given -- 'Value' when it is a @Number@.-number :: Applicative f => (Integer -> f Integer) -> Value -> f Value-number f (Number b n) = Number b <$> f n-number _ v = pure v+number :: Applicative f => (Integer -> f Integer) -> Value a -> f (Value a)+number f (Number a b n) = Number a b <$> f n+number _ v = pure v -- | Apply a function to the ['Value'] contained inside the given -- 'Value' when it is a @List@.-list :: Applicative f => ([Value] -> f [Value]) -> Value -> f Value-list f (List xs) = List <$> f xs-list _ v = pure v+list :: Applicative f => ([Value a] -> f [Value a]) -> Value a -> f (Value a)+list f (List a xs) = List a <$> f xs+list _ v = pure v -- | Apply a function to the 'Value' elements inside the given -- 'Value' when it is a @List@. -- -- > values = list . traverse-values :: Applicative f => (Value -> f Value) -> Value -> f Value+values :: Applicative f => (Value a -> f (Value a)) -> Value a -> f (Value a) values = list . traverse+++ann :: Functor f => (a -> f a) -> Value a -> f (Value a)+ann f v =+ case v of+ Sections a x -> (\a' -> Sections a' x ) <$> f a+ Number a x y -> (\a' -> Number a' x y) <$> f a+ Floating a x y -> (\a' -> Floating a' x y) <$> f a+ Text a x -> (\a' -> Text a' x ) <$> f a+ Atom a x -> (\a' -> Atom a' x ) <$> f a+ List a x -> (\a' -> List a' x ) <$> f a
src/Config/Parser.y view
@@ -4,23 +4,23 @@ module Config.Parser (parseValue) where import Config.Value (Section(..), Value(..), Atom(..))-import Config.Tokens (Located(..), Token)+import Config.Tokens (Located(..), Token, Position) import qualified Config.Tokens as T } %tokentype { Located Token } %token-SECTION { Located _ (T.Section $$) }-STRING { Located _ (T.String $$) }-ATOM { Located _ (T.Atom $$) }-NUMBER { Located _ $$@T.Number{} }-FLOATING { Located _ $$@T.Floating{} }-'*' { Located _ T.Bullet }-'[' { Located _ T.OpenList }+SECTION { Located _ T.Section{} }+STRING { Located _ T.String{} }+ATOM { Located _ T.Atom{} }+NUMBER { Located _ T.Number{} }+FLOATING { Located _ T.Floating{} }+'*' { Located $$ T.Bullet }+'[' { Located $$ T.OpenList } ',' { Located _ T.Comma } ']' { Located _ T.CloseList }-'{' { Located _ T.OpenMap }+'{' { Located $$ T.OpenMap } '}' { Located _ T.CloseMap } SEP { Located _ T.LayoutSep } END { Located _ T.LayoutEnd }@@ -33,48 +33,48 @@ %% -config :: { Value }+config :: { Value Position } : value EOF { $1 } -value :: { Value }- : sections END { Sections (reverse $1) }- | list END { List (reverse $1) }+value :: { Value Position }+ : sections END { sections $1 }+ | '*' list END { List $1 (reverse $2) } | simple { $1 } -simple :: { Value }- : NUMBER { number $1 }+simple :: { Value Position }+ : NUMBER { number $1 } | FLOATING { floating $1 }- | STRING { Text $1 }- | ATOM { Atom (MkAtom $1) }- | '{' inlinesections '}' { Sections (reverse $2) }- | '[' inlinelist ']' { List (reverse $2) }+ | STRING { text $1 }+ | ATOM { atom $1 }+ | '{' inlinesections '}' { Sections $1 (reverse $2) }+ | '[' inlinelist ']' { List $1 (reverse $2) } -sections :: { [Section] }+sections :: { [Section Position] } : section { [$1] } | sections SEP section { $3 : $1 } -inlinesections :: { [Section] }+inlinesections :: { [Section Position] } : { [] } | inlinesections1 { $1 } | inlinesections1 ',' { $1 } -inlinesections1 :: { [Section] }+inlinesections1 :: { [Section Position] } : section { [$1] } | inlinesections1 ',' section { $3 : $1 } -section :: { Section }- : SECTION value { Section $1 $2 }+section :: { Section Position }+ : SECTION value { section $1 $2 } -list :: { [Value] }- : '*' value { [$2] }+list :: { [Value Position] }+ : value { [$1] } | list SEP '*' value { $4 : $1 } -inlinelist :: { [Value] }+inlinelist :: { [Value Position] } : { [] } | inlinelist1 { $1 } | inlinelist1 ',' { $1 } -inlinelist1 :: { [Value] }+inlinelist1 :: { [Value Position] } : simple { [$1] } | inlinelist1 ',' simple { $3 : $1 } @@ -83,23 +83,36 @@ -- | Convert number token to number value. This needs a custom -- function like this because there are two value matched from -- the constructor.-number :: Token -> Value-number = \(T.Number base val) -> Number base val+number :: Located Token -> Value Position+number = \(Located a (T.Number base val)) -> Number a base val -- | Convert floating token to floating value. This needs a custom -- function like this because there are two value matched from -- the constructor.-floating :: Token -> Value-floating = \(T.Floating coef expo) -> Floating coef expo+floating :: Located Token -> Value Position+floating = \(Located a (T.Floating coef expo)) -> Floating a coef expo +section :: Located Token -> Value Position -> Section Position+section = \(Located a (T.Section k)) v -> Section a k v++sections :: [Section Position] -> Value Position+sections xxs = Sections (sectionAnn x) (x:xs)+ where x:xs = reverse xxs++text :: Located Token -> Value Position+text = \(Located a (T.String x)) -> Text a x++atom :: Located Token -> Value Position+atom = \(Located a (T.Atom x)) -> Atom a (MkAtom x)+ errorP :: [Located Token] -> Either (Located Token) a errorP xs = Left (head xs) -- | Attempt to parse a layout annotated token stream or -- the token that caused the parse to fail. parseValue ::- [Located Token] {- ^ layout annotated token stream -} ->- Either (Located Token) Value {- ^ token at failure or result -}+ [Located Token] {- ^ layout annotated token stream -} ->+ Either (Located Token) (Value Position) {- ^ token at failure or result -} parseValue = config }
src/Config/Pretty.hs view
@@ -13,17 +13,17 @@ -- Sections will nest complex values underneath with -- indentation and simple values will be rendered on -- the same line as their section.-pretty :: Value -> Doc+pretty :: Value a -> Doc pretty value = case value of- Sections [] -> text "{}"- Sections xs -> prettySections xs- Number b n -> prettyNum b n- Floating c e-> prettyFloating c e- Text t -> prettyText (Text.unpack t)- Atom t -> text (Text.unpack (atomName t))- List [] -> text "[]"- List xs -> vcat [ char '*' <+> pretty x | x <- xs ]+ Sections _ [] -> text "{}"+ Sections _ xs -> prettySections xs+ Number _ b n -> prettyNum b n+ Floating _ c e-> prettyFloating c e+ Text _ t -> prettyText (Text.unpack t)+ Atom _ t -> text (Text.unpack (atomName t))+ List _ [] -> text "[]"+ List _ xs -> vcat [ char '*' <+> pretty x | x <- xs ] prettyNum :: Int -> Integer -> Doc@@ -48,7 +48,7 @@ | otherwise = (False, char '\\' <> int (fromEnum x)) -prettySections :: [Section] -> Doc+prettySections :: [Section a] -> Doc prettySections ss = prettySmallSections small $$ rest where (small,big) = break (isBig . sectionValue) ss@@ -56,12 +56,12 @@ [] -> empty b : bs -> prettyBigSection b $$ prettySections bs -prettyBigSection :: Section -> Doc+prettyBigSection :: Section a -> Doc prettyBigSection s = text (Text.unpack (sectionName s)) <> colon $$ nest 2 (pretty (sectionValue s)) -prettySmallSections :: [Section] -> Doc+prettySmallSections :: [Section a] -> Doc prettySmallSections ss = vcat (map pp annotated) where annotate s = (Text.length (sectionName s), s)@@ -69,15 +69,15 @@ indent = 1 + maximum (0 : map fst annotated) pp (l,s) = prettySmallSection (indent - l) s -prettySmallSection :: Int -> Section -> Doc+prettySmallSection :: Int -> Section a -> Doc prettySmallSection n s = text (Text.unpack (sectionName s)) <> colon <> text (replicate n ' ') <> pretty (sectionValue s) -isBig :: Value -> Bool-isBig (Sections (_:_)) = True-isBig (List (_:_)) = True-isBig _ = False+isBig :: Value a -> Bool+isBig (Sections _ (_:_)) = True+isBig (List _ (_:_)) = True+isBig _ = False
src/Config/Tokens.hs view
@@ -13,7 +13,7 @@ -- | A position in a text file data Position = Position { posIndex, posLine, posColumn :: {-# UNPACK #-} !Int }- deriving (Read, Show)+ deriving (Read, Show, Ord, Eq) -- | A value annotated with its text file position data Located a = Located
src/Config/Value.hs view
@@ -1,10 +1,4 @@-{-# LANGUAGE CPP #-}-{-# LANGUAGE DeriveGeneric #-}-{-# LANGUAGE DeriveDataTypeable #-}--#ifndef MIN_VERSION_base-#define MIN_VERSION_base(x,y,z) 1-#endif+{-# Language DeriveGeneric, DeriveTraversable, DeriveDataTypeable #-} -- | This module provides the types used in this package for configuration. -- Visit "ConfigFile.Parser" to parse values of this type in a convenient@@ -13,39 +7,35 @@ ( Section(..) , Value(..) , Atom(..)+ , valueAnn ) where import Data.Text (Text) import Data.Data (Data, Typeable) import Data.String (IsString(..))--#if MIN_VERSION_base(4,6,0)-import GHC.Generics (Generic)-#endif+import GHC.Generics (Generic, Generic1) -- | A single section of a 'Value' -- -- Example: -- -- * @my-key: my-value@ is @'Section' ('Atom' "my-key") ('Atom' "my-value")@-data Section = Section- { sectionName :: Text- , sectionValue :: Value+data Section a = Section+ { sectionAnn :: a+ , sectionName :: Text+ , sectionValue :: Value a }- deriving (Eq, Read, Show, Typeable, Data-#if MIN_VERSION_base(4,6,0)- , Generic-#endif+ deriving ( Eq, Read, Show, Typeable, Data+ , Functor, Foldable, Traversable+ , Generic, Generic1 ) -- | Wrapper to distinguish 'Atom' from 'Text' by -- type in a configuration. Atoms can be constructed -- using the @OverloadedStrings@ extension. newtype Atom = MkAtom { atomName :: Text }- deriving (Eq, Ord, Show, Read, Typeable, Data-#if MIN_VERSION_base(4,6,0)+ deriving ( Eq, Ord, Show, Read, Typeable, Data , Generic-#endif ) instance IsString Atom where@@ -60,6 +50,9 @@ -- the concrete syntax. This allows representing numbers that would -- otherwise overflow a 'Double'. --+-- 'Value' is parameterized over an annotation type indented to be used for+-- file position or other application specific information.+-- -- Examples: -- -- * @0xff@ is @'Number' 16 255@@@ -68,15 +61,25 @@ -- -- * @123e10@ is @'Floating' 123 10@ -- * @123.45@ is @'Floating' 12345 (-2)@-data Value- = Sections [Section] -- ^ lists of key-value pairs- | Number Int Integer -- ^ integer literal base (2, 8, 10, or 16) and integer value- | Floating Integer Integer -- ^ coef exponent: coef * 10 ^ exponent- | Text Text -- ^ quoted strings- | Atom Atom -- ^ unquoted strings- | List [Value] -- ^ lists- deriving (Eq, Read, Show, Typeable, Data-#if MIN_VERSION_base(4,6,0)- , Generic-#endif+data Value a+ = Sections a [Section a] -- ^ lists of key-value pairs+ | Number a Int Integer -- ^ integer literal base (2, 8, 10, or 16) and integer value+ | Floating a Integer Integer -- ^ coef exponent: coef * 10 ^ exponent+ | Text a Text -- ^ quoted strings+ | Atom a Atom -- ^ unquoted strings+ | List a [Value a] -- ^ lists+ deriving ( Eq, Read, Show, Typeable, Data+ , Functor, Foldable, Traversable+ , Generic, Generic1 )++-- | Returns the annotation for a value.+valueAnn :: Value a -> a+valueAnn v =+ case v of+ Sections a _ -> a+ Number a _ _ -> a+ Floating a _ _ -> a+ Text a _ -> a+ Atom a _ -> a+ List a _ -> a