All Projects → dashbitco → Nimble_parsec

dashbitco / Nimble_parsec

A simple and fast library for text-based parser combinators

Programming Languages

elixir
2628 projects

Labels

Projects that are alternatives of or similar to Nimble parsec

Structurae
Data structures for high-performance JavaScript applications.
Stars: ✭ 323 (-39.29%)
Mutual labels:  binary
Binjs Ref
Reference implementation for the JavaScript Binary AST format
Stars: ✭ 399 (-25%)
Mutual labels:  binary
Deta parser
快速中文分词分析word segmentation
Stars: ✭ 476 (-10.53%)
Mutual labels:  binary
Gasper
Your Cloud in a Binary
Stars: ✭ 331 (-37.78%)
Mutual labels:  binary
Execa
Process execution for humans
Stars: ✭ 4,318 (+711.65%)
Mutual labels:  binary
Fastbinaryencoding
Fast Binary Encoding is ultra fast and universal serialization solution for C++, C#, Go, Java, JavaScript, Kotlin, Python, Ruby, Swift
Stars: ✭ 421 (-20.86%)
Mutual labels:  binary
E9patch
A powerful static binary rewriting tool
Stars: ✭ 317 (-40.41%)
Mutual labels:  binary
Android interviews
🚀Everything you need to know to find a android job. 算法 / 面试题 / Android 知识点 🔥🔥🔥 总结不易,你的 star 是我最大的动力!
Stars: ✭ 510 (-4.14%)
Mutual labels:  binary
0day Security Software Vulnerability Analysis Technology
0day安全_软件漏洞分析技术
Stars: ✭ 393 (-26.13%)
Mutual labels:  binary
Hdiffpatch
a C\C++ library and command-line tools for Diff & Patch between binary files or directories(folder); cross-platform; run fast; create small delta/differential; support large files and limit memory requires when diff & patch.
Stars: ✭ 459 (-13.72%)
Mutual labels:  binary
Rspirv
Rust implementation of SPIR-V module processing functionalities
Stars: ✭ 332 (-37.59%)
Mutual labels:  binary
Ceras
Universal binary serializer for a wide variety of scenarios https://discord.gg/FGaCX4c
Stars: ✭ 374 (-29.7%)
Mutual labels:  binary
Nar
node.js application archive - create self-contained binary like executable applications that are ready to ship and run
Stars: ✭ 428 (-19.55%)
Mutual labels:  binary
Ddisasm
A fast and accurate disassembler
Stars: ✭ 325 (-38.91%)
Mutual labels:  binary
Iguana
universal serialization engine
Stars: ✭ 481 (-9.59%)
Mutual labels:  binary
Tensorflow Windows Wheel
Tensorflow prebuilt binary for Windows
Stars: ✭ 3,428 (+544.36%)
Mutual labels:  binary
Binee
Binee: binary emulation environment
Stars: ✭ 408 (-23.31%)
Mutual labels:  binary
Dark Mode
Control the macOS dark mode from the command-line
Stars: ✭ 518 (-2.63%)
Mutual labels:  binary
Wpfhexeditorcontrol
Wpf Hexeditor is a powerful and fully customisable user control for editing file or stream as hexadecimal, decimal and binary. Can be used in Wpf or WinForm application
Stars: ✭ 484 (-9.02%)
Mutual labels:  binary
Qsym
QSYM: A Practical Concolic Execution Engine Tailored for Hybrid Fuzzing
Stars: ✭ 459 (-13.72%)
Mutual labels:  binary

NimbleParsec

Online Documentation.

NimbleParsec is a simple and fast library for text-based parser combinators.

Combinators are built during runtime and compiled into multiple clauses with binary matching. This provides the following benefits:

  • Performance: since it compiles to binary matching, it leverages many Erlang VM optimizations to generate extremely fast parser code with low memory usage

  • Composable: this library does not rely on macros for building and composing parsers, therefore they are fully composable. The only macros are defparsec/3 and defparsecp/3 which emit the compiled clauses with binary matching

  • No runtime dependency: after compilation, the generated parser clauses have no runtime dependency on NimbleParsec. This opens up the possibility to compile parsers and do not impose a dependency on users of your library

  • No footprints: NimbleParsec only needs to be imported in your modules. There is no need for use NimbleParsec, leaving no footprints on your modules

The goal of this library is to focus on a set of primitives for writing efficient parser combinators. The composition aspect means you should be able to use those primitives to implement higher level combinators.

Note this library does not handle low-level binary parsing. In such cases, we recommend using Elixir's bitstring syntax.

Examples

defmodule MyParser do
  import NimbleParsec

  date =
    integer(4)
    |> ignore(string("-"))
    |> integer(2)
    |> ignore(string("-"))
    |> integer(2)

  time =
    integer(2)
    |> ignore(string(":"))
    |> integer(2)
    |> ignore(string(":"))
    |> integer(2)
    |> optional(string("Z"))

  defparsec :datetime, date |> ignore(string("T")) |> concat(time), debug: true
end

MyParser.datetime("2010-04-17T14:12:34Z")
#=> {:ok, [2010, 4, 17, 14, 12, 34, "Z"], "", %{}, 1, 21}

If you add debug: true to defparsec/3, it will print the generated clauses, which are shown below:

defp datetime__0(<<x0, x1, x2, x3, "-", x4, x5, "-", x6, x7, "T",
                   x8, x9, ":", x10, x11, ":", x12, x13, rest::binary>>,
                 acc, stack, comb__context, comb__line, comb__column)
     when x0 >= 48 and x0 <= 57 and (x1 >= 48 and x1 <= 57) and
         (x2 >= 48 and x2 <= 57) and (x3 >= 48 and x3 <= 57) and
         (x4 >= 48 and x4 <= 57) and (x5 >= 48 and x5 <= 57) and
         (x6 >= 48 and x6 <= 57) and (x7 >= 48 and x7 <= 57) and
         (x8 >= 48 and x8 <= 57) and (x9 >= 48 and x9 <= 57) and
         (x10 >= 48 and x10 <= 57) and (x11 >= 48 and x11 <= 57) and
         (x12 >= 48 and x12 <= 57) and (x13 >= 48 and x13 <= 57) do
  datetime__1(
    rest,
    [(x13 - 48) * 1 + (x12 - 48) * 10, (x11 - 48) * 1 + (x10 - 48) * 10,
     (x9 - 48) * 1 + (x8 - 48) * 10, (x7 - 48) * 1 + (x6 - 48) * 10, (x5 - 48) * 1 + (x4 - 48) * 10,
     (x3 - 48) * 1 + (x2 - 48) * 10 + (x1 - 48) * 100 + (x0 - 48) * 1000] ++ acc,
    stack,
    comb__context,
    comb__line,
    comb__column + 19
  )
end

defp datetime__0(rest, acc, _stack, context, line, column) do
  {:error, "...", rest, context, line, column}
end

defp datetime__1(<<"Z", rest::binary>>, acc, stack, comb__context, comb__line, comb__column) do
  datetime__2(rest, ["Z"] ++ acc, stack, comb__context, comb__line, comb__column + 1)
end

defp datetime__1(rest, acc, stack, context, line, column) do
  datetime__2(rest, acc, stack, context, line, column)
end

defp datetime__2(rest, acc, _stack, context, line, column) do
  {:ok, acc, rest, context, line, column}
end

As you can see, it generates highly inlined code, comparable to hand-written parsers. This gives NimbleParsec an order of magnitude performance gains compared to other parser combinators. Further performance can be gained by giving the inline: true option to defparsec/3.

Installation

Add nimble_parsec to your list of dependencies in mix.exs:

def deps do
  [{:nimble_parsec, "~> 1.0"}]
end

Nimble*

All nimble libraries by Dashbit:

  • NimbleCSV - simple and fast CSV parsing
  • NimbleOptions - tiny library for validating and documenting high-level options
  • NimbleParsec - simple and fast parser combinators
  • NimblePool - tiny resource-pool implementation
  • NimblePublisher - a minimal filesystem-based publishing engine with Markdown support and code highlighting
  • NimbleTOTP - tiny library for generating time-based one time passwords (TOTP)

License

Copyright 2018 Plataformatec
Copyright 2020 Dashbit

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].