ArrayParser
Parsing of tokenized input
Data types
A parser processes a sequence of src
values.
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 src dst
consists of this backlog
and the sequence of produced values
of type dst
.
Basic parsers
Parse a fixed array.
> parse = Parse.array [ "a", "b", "c" ]
> parse [ "a", "b", "c", "d", "e", "f" ]
Just { backlog = [ "d", "e", "f" ], values = [ "a", "b", "c" ] }
Always fail.
> parse = Parse.fail
> parse [ "a", "b", "c" ]
Nothing
Always succeed and produce a fixed list of values.
> parse = Parse.succeed [ "x" ]
> parse [ "a", "b", "c" ]
Just ( backlog = [ "a", "b", "c" ], values = [ "x" ] )
Combinators
Apply a parser and discard the result.
> parse = Parse.skip ( Parse.array [ "a", "b", "c" ] )
> parse [ "a", "b", "c", "d", "e", "f" ]
Just { backlog = [ "d", "e", "f" ], values = [] }
Apply a parser if possible.
> parse = Parse.optional ( Parse.array [ "x" ] )
> parse [ "x", "y", "z" ]
Just { backlog = [ "y", "z" ], values = [ "x" ] }
Do not fail if the parser cannot be applied.
> parse = Parse.optional ( Parse.string [ "x" ] )
> parse [ "a", "b", "c" ]
Just { backlog = [ "a", "b", "c" ], values = [] }
Apply a parser as often as possible.
> parse = Parse.zeroOrMore ( Parse.array [ "x" ] )
> parse [ "x", "x", "x", "x", "a" ]
Just { backlog = [ "a" ], values = [ "x", "x", "x", "x" ] }
> parse = Parse.zerorMore ( Parse.array [ "x" ] )
> parse [ "a", "a", "a", "a", "a" ]
Just { backlog = [ "a", "a", "a", "a", "a" ], values = [] }
Apply a parser as often as possible, but at least once.
> parse = Parse.oneOrMore ( Parse.array [ "x" ] )
> parse [ "x", "x", "x", "x", "a" ]
Just { backlog = [ "a" ], values = [ "x", "x", "x", "x" ] }
> parse = Parse.oneOrMore ( Parse.array [ "x" ] )
> parse [ "a", "a", "a", "a", "a" ]
Nothing
Apply the first successful parser from a list of parsers.
> parse =
Parse.oneOf
[ Parse.array [ "x" ]
, Parse.array [ "y" ]
, Parse.array [ "z" ]
]
> parse [ "y", "a", "k" ]
Just { backlog = [ "a", "k" ], values = [ "y" ] }
Apply several parsers in succession.
> parse =
Parse.sequence
[ Parse.array [ "x" ]
, Parse.array [ "y" ]
, Parse.array [ "z" ]
]
> parse [ "x", "y", "z" ]
Just { backlog = [], values = [ "x", "y", "z" ] }
Transformations
Transform the parsed values.
> parse = Parse.map ( Array.map Array.reverse ) ( Parse.array [ "a", "b", "c" ] )
> parse [ "a", "b", "c", "d", "ef" ]
Just { backlog = [ "d", "e", "f" ], values = [ "c", "b", "a" ] }
This can be used, for example, to change the target data type of a parser.
> parse = Parse.array [ "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.array [ "x" ] )
|> Parse.andThen
( \ result ->
if Array.length result.values > 3 then Nothing
else Just result
)
> parse [ "x", "x", "x" ]
Just { backlog = [], values = [ "x", "x", "x" ] }
> parse [ "x", "x", "x", "x" ]
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.array [ "foo" ]
> run parser [ "foo" ]
Just "foo"
> run parser [ "foo", "x" ]
Nothing