I thought I'd re-ask this question to see if anyone has any ideas. My
original post is a bit long so I'll be briefer:
TL/DR: how does one replace an error message generated by elm-tools/parser
with a custom error message?
If an error condition is detected by directly my code while parsing, then I
can use
P.fail "my custom error message"
But what if the problem is found not directly in my code, but in
elm-tools/parser code that I call? For example,
Parser.list spaces Parser.int
If the current text doesn't look like a list of integers, then Parser.list will
generate a Problem. But suppose I want to output a custom error message
instead of simply reporting the error message contained in the Problem
generated
by Parser.list. How can I do this?
It's analogous to (in imperative languages with exceptions) catching an
exception thrown by a called function and throwing a new, more informative
exception.
On Thursday, August 3, 2017 at 12:03:34 PM UTC-7, Dave Doty wrote:
>
> I'm a bit confused what is the intended usage of elm-tools/parser to
> generate custom error messages. In particular, when creating a Parser
> value, but before calling run, there's no way to specify what sorts of
> errors can happen and messages to generate in response.
>
> The only interface in the module with errors seems to happen when calling
> the Parser.run function, which happens just once in client code.
>
> For instance, suppose I build up a big Parser hierarchically out of
> several smaller parsers:
>
> fullParser : Parser ...
> fullParser =
> succeed identity
> |. keyword "key1"
> |= (inContext "subparser 1" <| subparser1)
> |. keyword "key2"
> |= (inContext "subparser 2" <| subparser2)
> |. P.keyword "key3"
> |= (inContext "subparser 3" <| subparser3)
>
> and perhaps those are hierarchically constructed as well:
>
> subparser1 : Parser ...
> subparser1 =
> succeed identity
> |. keyword "subkey1"
> |= (inContext "subsubparser 1:1" <| subparser11)
> |. keyword "subkey2"
> |= (inContext "subsubparser 1:2" <| subparser12)
>
> And at the base level, perhaps I call library code, for instance from
> Parser.LanguageKit:
>
> subparser11 : P.Parser (List Int)
> subparser11 =
> sequence
> { start = "{"
> , separator = ","
> , end = "}"
> , spaces = spaces
> , item = int
> , trailing = Forbidden
> }
>
> Now, to run the parser, I call
>
> case run fullParser source of
> Ok parsedValue ->
> parsedValue
>
> Err { row, col, source, problem, context } ->
> <generate some error message>
>
> Suppose a problem happened in subparser11 because
> Parser.LanguageKit.sequence detected an error such as a missing comma ("{34,
> 56 78}"). So in the Err, the information we have access to is the Problem
> generated by Parser.LanguageKit.sequence, which will be something like
>
> BadOneOf ([ExpectingSymbol ",",ExpectingSymbol "}"])
>
>
> That's not a terrible thing to print, but we can do better. I also have
> access to the Context value with description "subsubparser 1:1" and a row and
> col.
>
>
> It seems that to create a custom error message that says something like "I
> was expecting either , or } at this point in the 'subparser 1:1' set",
>
> I can use the context description string, but it seems necessary to use a big
> case statement after the call to run
>
> that uses context strings and the type of Errors that are returned to tell
> where in the parsing the problem failed, and then customize the error message.
>
>
> In a language with exceptions, I would do something like this at the point in
> the parser code itself, where the Problem is generated
>
>
> def fullParser(source):
> subparser1(source)
> ...
>
> def subparser1(source):
> subparser11(source)
> ...
>
> def subparser11(source):
> try:
> Parser.LanguageKit.sequence(source)
> except BadOneOf:
> raise CustomException()
>
>
> In other words, I could catch the BadOneOf exception generated by the library
> code, and based on the local context in which I caught that exception,
> create a custom Exception of my own.
>
>
> But I don't see a way to do that sort of "Problem transforming" with
> elm-tools/parser,
>
> i.e., put the error-transforming code at the point in the definition of the
> parser where it is relevant.
>
>
> It seems the only option is to put lots of information into the context
> string at that point, and then have a big case statement after calling
> Parser.run
>
> to see where exactly in the parser hierarchy the problem occurred. But this
> anti-pattern of using Strings as poor man's Enums seems very un-Elm to me.
>
>
--
You received this message because you are subscribed to the Google Groups "Elm
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.