tmbb

tmbb

NimbleRegex - compile regular expressions into NimbleParsec combinators

I’ve started working on a toy project to compile extended POSIX-compatible regular expressions into NimbleParsec combinators. These combnators can be used to match on strings directly (only on the start of the strings, though) or as part of a bigger parser.I don’t support all of the POSIX standard yet. The goal is to help converting regex-based programing language highlighter into makeup lexers.

Example:

defmodule NimbleRegex.PosixExtended.CompilerTest do
  use ExUnit.Case

  alias NimbleRegex.PosixExtended.Parser
  alias NimbleRegex.PosixExtended.Compiler

  import NimbleParsec

  def simplify_result({:ok, result, rest, _, _, _}), do: {:ok, to_string(result), rest}
  def simplify_result({:error, _result, _rest, _, _, _}), do: :error

  test "simplify" do
    parsed = Parser.regex!("a|b|c")

    assert Compiler.simplify_alternatives(parsed) == [
             alternatives: [
               literal_char: ?a,
               literal_char: ?b,
               literal_char: ?c
             ]
           ]
  end

  defparsec(:comb1, Compiler.parsed_to_combinator("a|b|c"))

  test "example - comb1" do
    assert comb1("a") |> simplify_result() == {:ok, "a", ""}
    assert comb1("b") |> simplify_result() == {:ok, "b", ""}
    assert comb1("c") |> simplify_result() == {:ok, "c", ""}
    assert comb1("x") |> simplify_result() == :error
    assert comb1("xy") |> simplify_result() == :error
  end

  defparsec(:comb2, Compiler.compile_to_combinator("(ax)|b|c"))

  test "example - comb2" do
    assert comb2("a") |> simplify_result() == :error
    assert comb2("b") |> simplify_result() == {:ok, "b", ""}
    assert comb2("c") |> simplify_result() == {:ok, "c", ""}
    assert comb2("ax") |> simplify_result() == {:ok, "ax", ""}
  end

  defparsec(:comb3, Compiler.compile_to_combinator("ax|b"))

  test "example - comb3" do
    assert comb3("a") |> simplify_result() == :error
    assert comb3("ax") |> simplify_result() == {:ok, "ax", ""}
    assert comb3("ab") |> simplify_result() == {:ok, "ab", ""}
    assert comb3("b") |> simplify_result() == :error
  end

  defparsec(:comb4, Compiler.compile_to_combinator("[[:word:]]+"))

  test "example - comb4" do
    assert comb4("ábç") |> simplify_result() == {:ok, "ábç", ""}
  end
end

It’s currently 3x as fast as the Regex module when matching the beginning of a string (I’m not sure this is a fair comparison)

Where Next?

Popular in RFCs Top

bennydreamtech23
So recently I have been looking for ways to improve my workflow in elixir and I saw all the commands I need to run to setup a project and...
New
sleipnir
Hey! Want to contribute to a cool compiler project? Check out the good first issues in the Honey Potion Compiler! Honey Potion is a com...
New
senconscious
EctoJuno is a package that provides parsing, validation and applying sorting parameters for your ecto queries on models. Currently sortin...
New
BartOtten
This thread once discussed Routex in it’s early form. It has been repurposed to gather feedback and discusses pre-releases. Currently: p...
New
jarlah
Hi! I have recently created, after having tried to get in touch with the creator of excontainers for quite some time, a new library call...
New
bortzmeyer
Not a replacement for serious authoritative DNS servers, of course, but useful for some uses (such as returning the IP address of the DNS...
New
miolini
Hi :waving_hand: I’ve been working on CanvasCraft, a 2D drawing library for Elixir built on top of Skia via Rustler. It provides a decla...
New
marick
TL;DR I’ve forked the Lens package, changed the API some, added new lens makers and – most importantly – added a ton of documentation. In...
New
Hedgehog-ai
Hello I would like feedback on an experimental neuroevolution (including substrate encoding) library called Bardo based on the amazing wo...
New
manuel-rubio
There was some time when I started thinking about giving a boost to Lambdapad, the initiative from @garretsmith in Erlang that I loved wa...
New

Other popular topics Top

lessless
I believe there are people here who are dealing with CSV files import on the daily basis, and since Excel is a really popular tool there ...
New
JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New
fireproofsocks
I’m working on defining a simple Ecto schema for a table (in PostGres), but I don’t see where I can define a column as NOT NULL. Conside...
New
nsuchy
Hi. I’ve noticed that Windows Powershell has it’s own IEX command and you cannot access Elixir’s IEX due to the conflict. This isn’t a cr...
New
vertexbuffer
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
New
myronmarston
The Elixir Typespec docs show the following syntax for keyword lists in typespecs: # ... | [key: type] # keyword lis...
New
aadeshere1
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible. total = 10 while total != 0 ...
New
minhajuddin
I have seen a lot of code which picks the first element from a list using Enum.at(0) instead of List.first. Is there a reason why people ...
New
chensan
I have a User schema with a :from_id field set to type :string: defmodule TweetBot.Repo.Migrations.CreateUsers do use Ecto.Migration ...
New
lucidguppy
I have a super simple question about elixir - how would I take a file like this foo bar baz and output a new file that enumerates th...
New

We're in Beta

About us Mission Statement