roc-parser icon indicating copy to clipboard operation
roc-parser copied to clipboard

Add documentation for combining parser results

Open TeaDrinkingProgrammer opened this issue 2 months ago • 1 comments

I am writing a parser using this package, and it's working very nicely!

One thing I ran into though, was how to combine multiple parsers into one output. I want to parse a function and its parameters and get a result like in the expect block. With some digging through some of the built in parsers and reading the documentation again, I used the structure of the apply parser. This is the way I got it working in the end:

param_parser =
    many(codeunit_satisfies(|c| c != ')' and c != ',')) |> map str_from_utf8

function_name_parser =
    const(|codeunits| codeunits)
    |> keep(chomp_until('('))
    |> map String.str_from_utf8

params_parser = between(sep_by(param_parser, codeunit(',')), codeunit('('), codeunit(')'))
function_parser =
    combined = |input|
        { val: function_name, input: rest } = parse_partial(function_name_parser, input)?

        parse_partial(params_parser, rest)
        |> Result.map_ok(
            |{ val: params, input: rest2 }|
                { val: { function_name, params }, input: rest2 },
        )

    build_primitive_parser(combined)

expect
    input = "hello_world(param1,param2)"
    parser = function_parser
    result = parse_str(parser, input)
    result == Ok { function_name: "hello_world", params: ["param1", "param2"] }

Now, I have two questions:

  1. am I using the parsers correctly, or is there some other way to do the same thing in a more elegant way?
  2. If this is correct, can we add this example to parse_partial to demonstrate the principle described in the doc comment?

Edit: So I found out a better way which I think is the way you are supposed to do it:

function_parser =
    const(|function_name| |params| { function_name, params })
    |> keep(function_name_parser)
    |> keep(params_parser)

I know understand that it works, but it is not quite clear to my why it works. Again, I personally think it is useful to add some more examples on this pattern and explain why it works.

TeaDrinkingProgrammer avatar Oct 11 '25 12:10 TeaDrinkingProgrammer

Thank you @TeaDrinkingProgrammer

It looks good to me.

Have you seen the docs? https://lukewilliamboswell.github.io/roc-parser/0.10.0/Parser/

I'll need to upgrade this package to the new syntax soon, so just holding off any big documentation updates until then. We can roll these into that work -- I'd love to have lots of good examples.

lukewilliamboswell avatar Oct 13 '25 00:10 lukewilliamboswell