summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEricMertens <>2017-05-19 16:23:00 (GMT)
committerhdiff <hdiff@hdiff.luite.com>2017-05-19 16:23:00 (GMT)
commitbcc6292356e8f2fa63abb794f13895160d789137 (patch)
tree7e69f295e7d3e3605b324386fb86b0cc5bf1d338
parenta93bbe4029fd3a3b8b948866dfc9643039f47074 (diff)
version 0.6.20.6.2
-rw-r--r--CHANGELOG.md5
-rw-r--r--config-value.cabal4
-rw-r--r--config-value.vim14
-rw-r--r--dist/build/Config/Parser.hs100
-rw-r--r--src/Config.hs3
-rw-r--r--src/Config/LexerUtils.hs16
-rw-r--r--src/Config/Parser.y12
-rw-r--r--src/Config/Tokens.hs3
8 files changed, 100 insertions, 57 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3c57935..62ca806 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,8 @@
+0.6.2
+---
+* Nicer errors on unterminated inline lists and sections.
+* Stop enforcing well-formed text files
+
0.6.1
---
* Add vim syntax highlighting file
diff --git a/config-value.cabal b/config-value.cabal
index ec5ddb4..2ec9a84 100644
--- a/config-value.cabal
+++ b/config-value.cabal
@@ -1,5 +1,5 @@
name: config-value
-version: 0.6.1
+version: 0.6.2
synopsis: Simple, layout-based value language similar to YAML or JSON
license: MIT
license-file: LICENSE
@@ -15,7 +15,7 @@ description: This package implements a language similar to YAML or JSON
with fewer special cases and fewer dependencies. It emphasizes
layout structure for sections and lists, and requires quotes
around strings.
-tested-with: GHC==7.4.2, GHC==7.6.3, GHC==7.8.4, GHC==7.10.3, GHC==8.0.2, GHC==8.2.1
+tested-with: GHC==7.10.3, GHC==8.0.2, GHC==8.2.1
extra-source-files: README.md
CHANGELOG.md
diff --git a/config-value.vim b/config-value.vim
index 98cc964..0db8d3f 100644
--- a/config-value.vim
+++ b/config-value.vim
@@ -11,14 +11,12 @@ syn match cvDelimiter "*\|:\|\[\|\]\|,\|{\|}\|="
" Strings and constants -- copied from haskell.vim
syn match cvStringGap contained "\\[\n\ \t]*\\"
-syn match cvSpecialChar contained "\\\([0-9]\+\|o[0-7]\+\|x[0-9a-fA-F]\+\|[\"\\'&\\abfnrtv]\|\^[A-Z^_\[\\\]]\)"
+syn match cvSpecialChar contained "\\\([0-9]\+\|o[0-7]\+\|x[0-9a-fA-F]\+\|[\"\\'&\\abfnrtv]\|\^[@A-Z^_\[\\\]]\)"
syn match cvSpecialChar contained "\\\(NUL\|SOH\|STX\|ETX\|EOT\|ENQ\|ACK\|BEL\|BS\|HT\|LF\|VT\|FF\|CR\|SO\|SI\|DLE\|DC1\|DC2\|DC3\|DC4\|NAK\|SYN\|ETB\|CAN\|EM\|SUB\|ESC\|FS\|GS\|RS\|US\|SP\|DEL\)"
-syn match cvSpecialCharError contained "\\&\|'''\+"
-syn region cvString start=+"+ skip=+\\\\\|\\"+ end=+"+ contains=cvStringGap,cvSpecialChar
-syn match cvCharacter "[^a-zA-Z0-9_']'\([^\\]\|\\[^']\+\|\\'\)'"lc=1 contains=cvSpecialChar,cvSpecialCharError
-syn match cvCharacter "^'\([^\\]\|\\[^']\+\|\\'\)'" contains=cvSpecialChar,cvSpecialCharError
-syn match cvNumber "\<[0-9]\+\>\|\<0[xX][0-9a-fA-F]\+\>\|\<0[oO][0-7]\+\>\|\<0[bB][0-1]\+\>"
-syn match cvFloat "\<[0-9]\+\.[0-9]\+\([eE][-+]\=[0-9]\+\)\=\>"
+syn region cvString start=+"+ skip=+\\\\\|\\"+ end=+"\|\n+ contains=cvStringGap,cvSpecialChar
+syn match cvNumber "-\=\([0-9]\+\|0[xX][0-9a-fA-F]\+\|0[oO][0-7]\+\|0[bB][0-1]\+\)\>"
+syn match cvFloat "-\=[0-9]\+\.[0-9]\+\([eE][-+]\=[0-9]\+\)\=\>"
+syn match cvFloat "-\=[0-9]\+[eE][-+]\=[0-9]\+\>"
syn match cvAtom "\<[a-zA-Z][a-zA-Z0-9\._\-]*\>"
@@ -28,11 +26,9 @@ syn region cvBlockComment start="{-" end="-}" contains=cvString,cvBlockComm
hi def link cvAtom Identifier
hi def link cvDelimiter Delimiter
-hi def link cvSpecialCharError Error
hi def link cvSpecialChar SpecialChar
hi def link cvStringGap SpecialChar
hi def link cvString String
-hi def link cvCharacter Character
hi def link cvNumber Number
hi def link cvFloat Float
diff --git a/dist/build/Config/Parser.hs b/dist/build/Config/Parser.hs
index 89d9b03..fa9d424 100644
--- a/dist/build/Config/Parser.hs
+++ b/dist/build/Config/Parser.hs
@@ -89,21 +89,21 @@ happyOutTok x = Happy_GHC_Exts.unsafeCoerce# x
happyActOffsets :: HappyAddr
-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"#
+happyActOffsets = HappyA# "\x03\x00\x03\x00\x30\x00\x00\x00\x11\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x0c\x00\x37\x00\x23\x00\x01\x00\x2f\x00\x00\x00\x00\x00\x02\x00\x29\x00\x00\x00\x08\x00\x00\x00\x2a\x00\x00\x00\x00\x00\x00\x00\x26\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x25\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00"#
happyGotoOffsets :: HappyAddr
-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"#
+happyGotoOffsets = HappyA# "\x21\x00\x33\x00\x00\x00\x00\x00\x00\x00\x00\x00\x2d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x19\x00\x10\x00\x36\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x15\x00\x00\x00\x00\x00\xfd\xff\x00\x00\x00\x00\x00\x00\x00\x00\x27\x00\x00\x00\x00\x00"#
happyDefActions :: HappyAddr
-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"#
+happyDefActions = HappyA# "\x00\x00\x00\x00\x00\x00\xfb\xff\x00\x00\xf2\xff\x00\x00\xf8\xff\xf7\xff\xfa\xff\xf9\xff\x00\x00\xe8\xff\xf0\xff\x00\x00\x00\x00\xef\xff\xed\xff\xe5\xff\x00\x00\xe7\xff\xea\xff\x00\x00\xeb\xff\x00\x00\xfd\xff\xfe\xff\xf1\xff\x00\x00\xfc\xff\xe6\xff\xf3\xff\xf5\xff\xee\xff\xf4\xff\xf6\xff\xec\xff\xe4\xff\x00\x00\xe9\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\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"#
+happyCheck = HappyA# "\xff\xff\x00\x00\x00\x00\x06\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x09\x00\x0b\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\x0c\x00\x0d\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\x01\x00\x06\x00\x06\x00\x01\x00\x02\x00\x03\x00\x08\x00\x0f\x00\x06\x00\x01\x00\x02\x00\x03\x00\x08\x00\x01\x00\x06\x00\x04\x00\x05\x00\x06\x00\xff\xff\x0e\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"#
happyTable :: HappyAddr
-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"#
+happyTable = HappyA# "\x00\x00\x23\x00\x20\x00\x24\x00\x07\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x21\x00\x24\x00\x0e\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x12\x00\x0d\x00\x1d\x00\x1e\x00\x0e\x00\x25\x00\x13\x00\x14\x00\x15\x00\x03\x00\x04\x00\x19\x00\x1a\x00\x05\x00\x16\x00\x0e\x00\x02\x00\x03\x00\x04\x00\x1b\x00\x07\x00\x05\x00\x27\x00\x03\x00\x04\x00\x07\x00\x27\x00\x05\x00\x17\x00\x03\x00\x04\x00\x1f\x00\xff\xff\x05\x00\x02\x00\x03\x00\x04\x00\x22\x00\x07\x00\x05\x00\x0f\x00\x10\x00\x11\x00\x00\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) [
+happyReduceArr = Happy_Data_Array.array (1, 27) [
(1 , happyReduce_1),
(2 , happyReduce_2),
(3 , happyReduce_3),
@@ -128,7 +128,9 @@ happyReduceArr = Happy_Data_Array.array (1, 25) [
(22 , happyReduce_22),
(23 , happyReduce_23),
(24 , happyReduce_24),
- (25 , happyReduce_25)
+ (25 , happyReduce_25),
+ (26 , happyReduce_26),
+ (27 , happyReduce_27)
]
happy_n_terms = 16 :: Int
@@ -215,15 +217,33 @@ happyReduction_10 happy_x_3
(List happy_var_1 (reverse happy_var_2)
)}}
-happyReduce_11 = happySpecReduce_1 3# happyReduction_11
-happyReduction_11 happy_x_1
+happyReduce_11 = happyMonadReduce 3# 2# happyReduction_11
+happyReduction_11 (happy_x_3 `HappyStk`
+ happy_x_2 `HappyStk`
+ happy_x_1 `HappyStk`
+ happyRest) tk
+ = happyThen (case happyOutTok happy_x_1 of { (Located happy_var_1 T.OpenMap) ->
+ ( untermSections happy_var_1)}
+ ) (\r -> happyReturn (happyIn6 r))
+
+happyReduce_12 = happyMonadReduce 3# 2# happyReduction_12
+happyReduction_12 (happy_x_3 `HappyStk`
+ happy_x_2 `HappyStk`
+ happy_x_1 `HappyStk`
+ happyRest) tk
+ = happyThen (case happyOutTok happy_x_1 of { (Located happy_var_1 T.OpenList) ->
+ ( untermList happy_var_1)}
+ ) (\r -> happyReturn (happyIn6 r))
+
+happyReduce_13 = happySpecReduce_1 3# happyReduction_13
+happyReduction_13 happy_x_1
= case happyOut10 happy_x_1 of { happy_var_1 ->
happyIn7
([happy_var_1]
)}
-happyReduce_12 = happySpecReduce_3 3# happyReduction_12
-happyReduction_12 happy_x_3
+happyReduce_14 = happySpecReduce_3 3# happyReduction_14
+happyReduction_14 happy_x_3
happy_x_2
happy_x_1
= case happyOut7 happy_x_1 of { happy_var_1 ->
@@ -232,35 +252,35 @@ happyReduction_12 happy_x_3
(happy_var_3 : happy_var_1
)}}
-happyReduce_13 = happySpecReduce_0 4# happyReduction_13
-happyReduction_13 = happyIn8
+happyReduce_15 = happySpecReduce_0 4# happyReduction_15
+happyReduction_15 = happyIn8
([]
)
-happyReduce_14 = happySpecReduce_1 4# happyReduction_14
-happyReduction_14 happy_x_1
+happyReduce_16 = happySpecReduce_1 4# happyReduction_16
+happyReduction_16 happy_x_1
= case happyOut9 happy_x_1 of { happy_var_1 ->
happyIn8
(happy_var_1
)}
-happyReduce_15 = happySpecReduce_2 4# happyReduction_15
-happyReduction_15 happy_x_2
+happyReduce_17 = happySpecReduce_2 4# happyReduction_17
+happyReduction_17 happy_x_2
happy_x_1
= case happyOut9 happy_x_1 of { happy_var_1 ->
happyIn8
(happy_var_1
)}
-happyReduce_16 = happySpecReduce_1 5# happyReduction_16
-happyReduction_16 happy_x_1
+happyReduce_18 = happySpecReduce_1 5# happyReduction_18
+happyReduction_18 happy_x_1
= case happyOut10 happy_x_1 of { happy_var_1 ->
happyIn9
([happy_var_1]
)}
-happyReduce_17 = happySpecReduce_3 5# happyReduction_17
-happyReduction_17 happy_x_3
+happyReduce_19 = happySpecReduce_3 5# happyReduction_19
+happyReduction_19 happy_x_3
happy_x_2
happy_x_1
= case happyOut9 happy_x_1 of { happy_var_1 ->
@@ -269,8 +289,8 @@ happyReduction_17 happy_x_3
(happy_var_3 : happy_var_1
)}}
-happyReduce_18 = happySpecReduce_2 6# happyReduction_18
-happyReduction_18 happy_x_2
+happyReduce_20 = happySpecReduce_2 6# happyReduction_20
+happyReduction_20 happy_x_2
happy_x_1
= case happyOutTok happy_x_1 of { happy_var_1 ->
case happyOut5 happy_x_2 of { happy_var_2 ->
@@ -278,15 +298,15 @@ happyReduction_18 happy_x_2
(section happy_var_1 happy_var_2
)}}
-happyReduce_19 = happySpecReduce_1 7# happyReduction_19
-happyReduction_19 happy_x_1
+happyReduce_21 = happySpecReduce_1 7# happyReduction_21
+happyReduction_21 happy_x_1
= case happyOut5 happy_x_1 of { happy_var_1 ->
happyIn11
([happy_var_1]
)}
-happyReduce_20 = happyReduce 4# 7# happyReduction_20
-happyReduction_20 (happy_x_4 `HappyStk`
+happyReduce_22 = happyReduce 4# 7# happyReduction_22
+happyReduction_22 (happy_x_4 `HappyStk`
happy_x_3 `HappyStk`
happy_x_2 `HappyStk`
happy_x_1 `HappyStk`
@@ -297,35 +317,35 @@ happyReduction_20 (happy_x_4 `HappyStk`
(happy_var_4 : happy_var_1
) `HappyStk` happyRest}}
-happyReduce_21 = happySpecReduce_0 8# happyReduction_21
-happyReduction_21 = happyIn12
+happyReduce_23 = happySpecReduce_0 8# happyReduction_23
+happyReduction_23 = happyIn12
([]
)
-happyReduce_22 = happySpecReduce_1 8# happyReduction_22
-happyReduction_22 happy_x_1
+happyReduce_24 = happySpecReduce_1 8# happyReduction_24
+happyReduction_24 happy_x_1
= case happyOut13 happy_x_1 of { happy_var_1 ->
happyIn12
(happy_var_1
)}
-happyReduce_23 = happySpecReduce_2 8# happyReduction_23
-happyReduction_23 happy_x_2
+happyReduce_25 = happySpecReduce_2 8# happyReduction_25
+happyReduction_25 happy_x_2
happy_x_1
= case happyOut13 happy_x_1 of { happy_var_1 ->
happyIn12
(happy_var_1
)}
-happyReduce_24 = happySpecReduce_1 9# happyReduction_24
-happyReduction_24 happy_x_1
+happyReduce_26 = happySpecReduce_1 9# happyReduction_26
+happyReduction_26 happy_x_1
= case happyOut6 happy_x_1 of { happy_var_1 ->
happyIn13
([happy_var_1]
)}
-happyReduce_25 = happySpecReduce_3 9# happyReduction_25
-happyReduction_25 happy_x_3
+happyReduce_27 = happySpecReduce_3 9# happyReduction_27
+happyReduction_27 happy_x_3
happy_x_2
happy_x_1
= case happyOut13 happy_x_1 of { happy_var_1 ->
@@ -404,6 +424,12 @@ atom = \(Located a (T.Atom x)) -> Atom a (MkAtom x)
errorP :: [Located Token] -> Either (Located Token) a
errorP xs = Left (head xs)
+untermSections :: Position -> Either (Located Token) a
+untermSections p = Left (Located p (T.Error T.UntermSections))
+
+untermList :: Position -> Either (Located Token) a
+untermList p = Left (Located p (T.Error T.UntermList))
+
-- | Attempt to parse a layout annotated token stream or
-- the token that caused the parse to fail.
parseValue ::
diff --git a/src/Config.hs b/src/Config.hs
index 62faef9..a63e0da 100644
--- a/src/Config.hs
+++ b/src/Config.hs
@@ -318,6 +318,7 @@ explainError e =
case e of
T.UntermComment -> "lexical error: unterminated comment"
T.UntermString -> "lexical error: unterminated string literal"
- T.UntermFile -> "lexical error: unterminated line"
+ T.UntermSections -> "lexical error: unterminated sections"
+ T.UntermList -> "lexical error: unterminated list"
T.BadEscape c -> "lexical error: bad escape sequence: " ++ Text.unpack c
T.NoMatch c -> "lexical error at character " ++ show c
diff --git a/src/Config/LexerUtils.hs b/src/Config/LexerUtils.hs
index 6ed47ab..cb48b62 100644
--- a/src/Config/LexerUtils.hs
+++ b/src/Config/LexerUtils.hs
@@ -49,11 +49,17 @@ move (Position ix line column) c =
eofAction :: Position -> LexerMode -> [Located Token]
eofAction eofPosn st =
case st of
- _ | posColumn eofPosn /= 1 -> [Located eofPosn (Error UntermFile)]
- InComment posn _ -> [Located posn (Error UntermComment)]
- InCommentString posn _ -> [Located posn (Error UntermComment)]
- InString posn _ -> [Located posn (Error UntermString)]
- InNormal -> [Located eofPosn{posColumn=0} EOF]
+ InComment posn _ -> [Located posn (Error UntermComment)]
+ InCommentString posn _ -> [Located posn (Error UntermComment)]
+ InString posn _ -> [Located posn (Error UntermString)]
+ InNormal -> [Located (park eofPosn) EOF]
+
+-- | Terminate the line if needed and move the cursor to column 0 to ensure
+-- that it terminates any top-level block.
+park :: Position -> Position
+park pos
+ | posColumn pos == 1 = pos { posColumn = 0 }
+ | otherwise = pos { posColumn = 0, posLine = posLine pos + 1 }
-- | Action to perform when lexer gets stuck. Emits an error.
errorAction :: AlexInput -> [Located Token]
diff --git a/src/Config/Parser.y b/src/Config/Parser.y
index ceed707..290f6ff 100644
--- a/src/Config/Parser.y
+++ b/src/Config/Parser.y
@@ -46,8 +46,10 @@ simple :: { Value Position }
| FLOATING { floating $1 }
| STRING { text $1 }
| ATOM { atom $1 }
- | '{' inlinesections '}' { Sections $1 (reverse $2) }
- | '[' inlinelist ']' { List $1 (reverse $2) }
+ | '{' inlinesections '}' { Sections $1 (reverse $2) }
+ | '[' inlinelist ']' { List $1 (reverse $2) }
+ | '{' inlinesections error {% untermSections $1 }
+ | '[' inlinelist error {% untermList $1 }
sections :: { [Section Position] }
: section { [$1] }
@@ -108,6 +110,12 @@ atom = \(Located a (T.Atom x)) -> Atom a (MkAtom x)
errorP :: [Located Token] -> Either (Located Token) a
errorP xs = Left (head xs)
+untermSections :: Position -> Either (Located Token) a
+untermSections p = Left (Located p (T.Error T.UntermSections))
+
+untermList :: Position -> Either (Located Token) a
+untermList p = Left (Located p (T.Error T.UntermList))
+
-- | Attempt to parse a layout annotated token stream or
-- the token that caused the parse to fail.
parseValue ::
diff --git a/src/Config/Tokens.hs b/src/Config/Tokens.hs
index da80f0f..8820342 100644
--- a/src/Config/Tokens.hs
+++ b/src/Config/Tokens.hs
@@ -51,7 +51,8 @@ data Token
data Error
= UntermComment
| UntermString
- | UntermFile
+ | UntermList
+ | UntermSections
| BadEscape Text
| NoMatch Char
deriving (Show)