Reconize brackets patterns

Hello guys! I new in Elixir and NimbleParsec library, I am trying to reconize a bracket pattern like this
Statement ::= "{" ( Statement )* "}" use the following code

defmodule Jotamenos.Parser.Statement do
  import NimbleParsec
  # Statement ::= "{" ( Statement )* "}"
  #   left_bracket = string("(") |> eos() |> unwrap_and_tag(:left_bracket)
  #   right_bracket = string(")") |> eos() |> unwrap_and_tag(:right_bracket)

  defparsec(
    :parser,
    ascii_char([?{])
    |> eos()
    |> optional(repeat(ascii_char([?{]) |> eos |> ascii_char([?{])) |> eos())
    |> ascii_char([?{])
    |> eos()
  )
end

I feel that I almost there but I can’t figure out

I haven’t worked with NimbleParsec much but:

  • Are you sure about that all eos() combinators?
  • Aren’t some of them should be ?} instead of ?{?

Wouldn’t this work:

defparsec :statement,  ascii_char('{') |> optional(repeat(parsec(:statement))) |> ascii_char('}')
2 Likes

A recursive definition like this would require a parsec combinator I believe. So something like:

  defparsec(
    :parser,
    ascii_char([?{])
    |> repeat(parsec(:parser))
    |> ascii_char([?}])
    |> eos()
  )

Now this will be infinitely recursive which is probably not what you want. But I assume this is only part of whatever grammar you are parsing. it also does not account for whitespace. I usually end up with ignore(optional(whitespace())) in a few places in a grammar.

2 Likes

yeah I’m using eos() because if I have {something_else it will return ok, the recursive way is more elegant, I like it,

Yeah I also thought about this recursive loop, this is the minijava grammar, I’m using your modified version it match ok when I have a string like this {} but when I test the string {{}} I got an error saying there is no end of file, it is weird because we have the last } that should follow an end of string

iex(29)> Jotamenos.Parser.Statement.parser("{{}}")
{:error, "expected byte equal to ?}, followed by end of string", "{}}", %{}, {1, 0}, 1}
``