zf

zenflows testing
git clone https://s.sonu.ch/~srfsh/zf.git
Log | Files | Refs | Submodules | README | LICENSE

README.md (5520B)


      1 # NimbleParsec
      2 
      3 [Online Documentation](https://hexdocs.pm/nimble_parsec).
      4 
      5 <!-- MDOC !-->
      6 
      7 `NimbleParsec` is a simple and fast library for text-based parser
      8 combinators.
      9 
     10 Combinators are built during runtime and compiled into multiple
     11 clauses with binary matching. This provides the following benefits:
     12 
     13   * Performance: since it compiles to binary matching, it leverages
     14     many Erlang VM optimizations to generate extremely fast parser
     15     code with low memory usage
     16 
     17   * Composable: this library does not rely on macros for building and
     18     composing parsers, therefore they are fully composable. The only
     19     macros are `defparsec/3` and `defparsecp/3` which emit the compiled
     20     clauses with  binary matching
     21 
     22   * No runtime dependency: after compilation, the generated parser
     23     clauses have no runtime dependency on `NimbleParsec`. This opens up
     24     the possibility to compile parsers and do not impose a dependency on
     25     users of your library
     26 
     27   * No footprints: `NimbleParsec` only needs to be imported in your modules.
     28     There is no need for `use NimbleParsec`, leaving no footprints on your
     29     modules
     30 
     31 The goal of this library is to focus on a set of primitives for writing
     32 efficient parser combinators. The composition aspect means you should be
     33 able to use those primitives to implement higher level combinators.
     34 
     35 Note this library does not handle low-level binary parsing. In such cases,
     36 we recommend using [Elixir's bitstring syntax](https://hexdocs.pm/elixir/Kernel.SpecialForms.html#%3C%3C%3E%3E/1).
     37 
     38 ## Examples
     39 
     40 ```elixir
     41 defmodule MyParser do
     42   import NimbleParsec
     43 
     44   date =
     45     integer(4)
     46     |> ignore(string("-"))
     47     |> integer(2)
     48     |> ignore(string("-"))
     49     |> integer(2)
     50 
     51   time =
     52     integer(2)
     53     |> ignore(string(":"))
     54     |> integer(2)
     55     |> ignore(string(":"))
     56     |> integer(2)
     57     |> optional(string("Z"))
     58 
     59   defparsec :datetime, date |> ignore(string("T")) |> concat(time), debug: true
     60 end
     61 
     62 MyParser.datetime("2010-04-17T14:12:34Z")
     63 #=> {:ok, [2010, 4, 17, 14, 12, 34, "Z"], "", %{}, 1, 21}
     64 ```
     65 
     66 If you add `debug: true` to `defparsec/3`, it will print the generated
     67 clauses, which are shown below:
     68 
     69 ```elixir
     70 defp datetime__0(<<x0, x1, x2, x3, "-", x4, x5, "-", x6, x7, "T",
     71                    x8, x9, ":", x10, x11, ":", x12, x13, rest::binary>>,
     72                  acc, stack, comb__context, comb__line, comb__column)
     73      when x0 >= 48 and x0 <= 57 and (x1 >= 48 and x1 <= 57) and
     74          (x2 >= 48 and x2 <= 57) and (x3 >= 48 and x3 <= 57) and
     75          (x4 >= 48 and x4 <= 57) and (x5 >= 48 and x5 <= 57) and
     76          (x6 >= 48 and x6 <= 57) and (x7 >= 48 and x7 <= 57) and
     77          (x8 >= 48 and x8 <= 57) and (x9 >= 48 and x9 <= 57) and
     78          (x10 >= 48 and x10 <= 57) and (x11 >= 48 and x11 <= 57) and
     79          (x12 >= 48 and x12 <= 57) and (x13 >= 48 and x13 <= 57) do
     80   datetime__1(
     81     rest,
     82     [(x13 - 48) * 1 + (x12 - 48) * 10, (x11 - 48) * 1 + (x10 - 48) * 10,
     83      (x9 - 48) * 1 + (x8 - 48) * 10, (x7 - 48) * 1 + (x6 - 48) * 10, (x5 - 48) * 1 + (x4 - 48) * 10,
     84      (x3 - 48) * 1 + (x2 - 48) * 10 + (x1 - 48) * 100 + (x0 - 48) * 1000] ++ acc,
     85     stack,
     86     comb__context,
     87     comb__line,
     88     comb__column + 19
     89   )
     90 end
     91 
     92 defp datetime__0(rest, acc, _stack, context, line, column) do
     93   {:error, "...", rest, context, line, column}
     94 end
     95 
     96 defp datetime__1(<<"Z", rest::binary>>, acc, stack, comb__context, comb__line, comb__column) do
     97   datetime__2(rest, ["Z"] ++ acc, stack, comb__context, comb__line, comb__column + 1)
     98 end
     99 
    100 defp datetime__1(rest, acc, stack, context, line, column) do
    101   datetime__2(rest, acc, stack, context, line, column)
    102 end
    103 
    104 defp datetime__2(rest, acc, _stack, context, line, column) do
    105   {:ok, acc, rest, context, line, column}
    106 end
    107 ```
    108 
    109 As you can see, it generates highly inlined code, comparable to
    110 hand-written parsers. This gives `NimbleParsec` an order of magnitude
    111 performance gains compared to other parser combinators. Further performance
    112 can be gained by giving the `inline: true` option to `defparsec/3`.
    113 
    114 <!-- MDOC !-->
    115 
    116 ## Installation
    117 
    118 Add `nimble_parsec` to your list of dependencies in `mix.exs`:
    119 
    120 ```elixir
    121 def deps do
    122   [
    123     {:nimble_parsec, "~> 1.0"}
    124   ]
    125 end
    126 ```
    127 
    128 ## Nimble*
    129 
    130 All nimble libraries by Dashbit:
    131 
    132   * [NimbleCSV](https://github.com/dashbitco/nimble_csv) - simple and fast CSV parsing
    133   * [NimbleOptions](https://github.com/dashbitco/nimble_options) - tiny library for validating and documenting high-level options
    134   * [NimbleParsec](https://github.com/dashbitco/nimble_parsec) - simple and fast parser combinators
    135   * [NimblePool](https://github.com/dashbitco/nimble_pool) - tiny resource-pool implementation
    136   * [NimblePublisher](https://github.com/dashbitco/nimble_publisher) - a minimal filesystem-based publishing engine with Markdown support and code highlighting
    137   * [NimbleTOTP](https://github.com/dashbitco/nimble_totp) - tiny library for generating time-based one time passwords (TOTP)
    138 
    139 ## License
    140 
    141 Copyright 2018 Plataformatec \
    142 Copyright 2020 Dashbit
    143 
    144   Licensed under the Apache License, Version 2.0 (the "License");
    145   you may not use this file except in compliance with the License.
    146   You may obtain a copy of the License at
    147 
    148       http://www.apache.org/licenses/LICENSE-2.0
    149 
    150   Unless required by applicable law or agreed to in writing, software
    151   distributed under the License is distributed on an "AS IS" BASIS,
    152   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    153   See the License for the specific language governing permissions and
    154   limitations under the License.