View Source Intro to DSL : parse a comma separated list of identifiers

Mix.install([:grammar])

Local setup

To use this livebook within a local clone the project, use the following setup, and launch the livebook from it's directory.

Mix.install(
  [
    {:grammar, path: Path.join(__DIR__, ".."), env: :dev}
  ],
  lockfile: :grammar
)

Section

defmodule MyGrammar do
  use Grammar

  rule list("[", :list?, "]") do
    [_, list, _] = params
    list || []
  end

  # A maybe empty
  rule? list?(:element, :list_cont?) do
    [element, list_cont] = params
    [element | list_cont || []]
  end

  # An element of the list matches a peculiar regex
  rule element(~r/[a-zA-Z]+/) do
    [element] = params
    element
  end

  # List continuation may be empty
  rule? list_cont?(",", :element, :list_cont?) do
    [_, element, list_cont] = params
    [element | list_cont || []]
  end
end

Parse some valid inputs

# Empty list
IO.inspect(MyGrammar.parse("[]"))

# Single item list
IO.inspect(MyGrammar.parse("[a]"))

# Regular list
IO.inspect(MyGrammar.parse("[a, bb, ccc]"))

Try parse invalid inputs

MyGrammar.parse("ident")
MyGrammar.parse("[ident")
MyGrammar.parse("[ident,]")