config-value-0.4: src/Config/Parser.y
{
{-# LANGUAGE Trustworthy #-}
module Config.Parser (parseValue) where
import Config.Value (Section(..), Value(..), Atom(..))
import Config.ParserUtils (Parser, runParser, lexerP, errorP)
import Config.Tokens (Located(..), Token)
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{} }
'*' { Located _ T.Bullet }
'[' { Located _ T.OpenList }
',' { Located _ T.Comma }
']' { Located _ T.CloseList }
'{' { Located _ T.OpenMap }
'}' { Located _ T.CloseMap }
SEP { Located _ T.LayoutSep }
END { Located _ T.LayoutEnd }
%monad { Parser (Located Token) }
%lexer { (>>=) lexerP } { Located _ T.EOF }
%error { errorP }
%name value
%%
value :: { Value }
: sections { Sections $1 }
| list { List $1 }
| simple { $1 }
simple :: { Value }
: NUMBER { number $1 }
| STRING { Text $1 }
| ATOM { Atom (MkAtom $1) }
| '{' '}' { Sections [] }
| '[' inlinelist ']' { List $2 }
sections :: { [Section] }
: section END { [$1] }
| section SEP sections { $1 : $3 }
section :: { Section }
: SECTION value { Section $1 $2 }
list :: { [Value] }
: '*' value END { [$2] }
| '*' value SEP list { $2 : $4 }
inlinelist :: { [Value] }
: { [] }
| inlinelist1 { $1 }
inlinelist1 :: { [Value] }
: simple { [$1] }
| simple ',' inlinelist1 { $1 : $3 }
{
-- | 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
-- | 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 -}
parseValue = runParser value
}