NimbleParsec composition does not recognize defined parser

Can’t figure out why my composable parser is not working.

import NimbleParsec

sign = optional(string("-"))
element = sign |> integer(min: 1)
operator = choice([string("multiplied by"), string("divided by"), string("plus"), string("minus")])
operation = element |> operator |> element
defparsec :math_problem, operation

(CompileError) undefined function element/1
But it is defined. I can use element in the defparsec definition on its own, I just can’t compose with it. In fact, I can’t seem to compose any of my parsers together. What am I missing?

Hello, the functions provided by NimbleParsec do not return functions. They return combinators that will be used in defparsec.
What you probably want is:

defmodule Parser do
  import NimbleParsec

  sign = optional(string("-"))
  element = sign |> integer(min: 1)

  operator =
    choice([string("multiplied by"), string("divided by"), string("plus"), string("minus")])

  math = element |> concat(operator) |> concat(element)

  defparsec(:math_problem, math)
end

Then you can use the parser:

iex> Parser.math_problem("1plus2")
{:ok, [1, "plus", 2], "", %{}, {1, 0}, 6}
2 Likes

Thanks. I figured out the need for concat but forgot to come back and edit the post. I appreciate your help.

1 Like