StringParser.Parse
Parsing string input.
Data types
A parser processes an input string.
If it is successful, it produces a result.
Otherwise, it produces Nothing
.
If a parser has only processed part of its input, a backlog
remains.
This is the unprocessed part of the input.
A Result a
consists of this backlog
and the sequence of produced values
of type a
.
Basic parsers
Parse a fixed string.
> parse = Parse.string "abc"
> parse "abcdef"
Just { backlog = "def", values = [ "abc" ] }
Always fail.
> parse = Parse.fail
> parse "abc"
Nothing
Always succeed and produce a fixed list of values.
> parse = Parse.succeed [ "x" ]
> parse "abc"
Just ( backlog = "abc", values = [ "x" ] )
Combinators
Apply a parser and discard the result.
> parse = Parse.skip ( Parse.string "abc" )
> parse "abcdef"
Just { backlog = "def", values = [] }
Apply a parser if possible.
> parse = Parse.optional ( Parse.string "x" )
> parse "xyz"
Just { backlog = "yz", values = [ "x" ] }
Do not fail if the parser cannot be applied.
> parse = Parse.optional ( Parse.string "x" )
> parse "abc"
Just { backlog = "abc", values = [] }
Apply a parser as often as possible.
> parse = Parse.zeroOrMore ( Parse.string "x" )
> parse "xxxxa"
Just { backlog = "a", values = [ "x", "x", "x", "x" ] }
> parse = Parse.zerorMore ( Parse.string "x" )
> parse "aaaaa"
Just { backlog = "aaaaa", values = [] }
Apply a parser as often as possible, but at least once.
> parse = Parse.oneOrMore ( Parse.string "x" )
> parse "xxxxa"
Just { backlog = "a", values = [ "x", "x", "x", "x" ] }
> parse = Parse.oneOrMore ( Parse.string "x" )
> parse "aaaaa"
Nothing
Use the first parser, or the second if the first fails.
> parse = Parse.eitherOr ( Parse.string "x" ) ( Parse.string "y" )
> parse "yak"
Just { backlog = "ak", values = [ "y" ] }
oneOf
is defined as a fold over this function.
Therefore:
oneOf [ a, b ] == eitherOr a b
--
Apply the first successful parser from a list of parsers.
> parse =
Parse.oneOf
[ Parse.string "x"
, Parse.string "y"
, Parse.string "z"
]
> parse "yak"
Just { backlog = "ak", values = [ "y" ] }
Concatenate two parsers.
> parse = Parse.pair ( Parse.string "x" ) ( Parse.string "y" )
> parse "xyz"
Just { backlog = "z", values = [ "x", "y" ] }
sequence
is defined as a fold over this function.
Therefore:
sequence [ a, b ] == pair a b
--
Apply several parsers in succession.
> parse =
Parse.sequence
[ Parse.string "x"
, Parse.string "y"
, Parse.string "z"
]
> parse "xyz"
Just { backlog = "", values = [ "x", "y", "z" ] }
Transformations
Transform the parsed values.
> parse = Parse.map ( Array.map String.reverse ) ( string "abc" )
> parse "abcdef"
Just { backlog = "def", values = [ "cba" ] }
This can be used, for example, to change the target data type of a parser.
> parse = Parse.string "true" |> Parse.map ( \ _ -> [ True ] )
> parse "true"
> Just { backlog = "", values = [ True ] }
Transform the result of a parser.
This can do everything that map
can do.
In addition, you can use it to decide whether a parser should fail based on the values it produces.
For example, we can use it to limit zeroOrMore
to three repetitions.
> parse =
Parse.zeroOrMore ( Parse.string "x" )
|> Parse.andThen
( \ result ->
if Array.length result.values > 3 then Nothing
else Just result
)
> parse "xxx"
Just { backlog = "", values = [ "x", "x", "x" ] }
> parse "xxxx"
Nothing
Execution
Apply a parser and produce a final result.
run
expects a parser to process its input completely (i.e. to leave an empty backlog),
and to produce exactly one value.
If successful, the produced value is returned. Otherwise, nothing is returned.
> parser = Parse.string "foo"
> run parser "foo"
Just "foo"
> run parser "foox"
Nothing