Build Status

About

A parser and interpreter for ABNF grammars.

ABNF is defined in: https://tools.ietf.org/html/rfc4234, and updated in https://tools.ietf.org/html/rfc5234.

Use example

iex(1)> grammar = ABNF.load_file "test/resources/ipv4.abnf"
iex(2)> initial_state = %{}
iex(2)> ABNF.apply grammar, "ipv4address", '250.246.192.34', initial_state
%ABNF.CaptureResult{
input: '250.246.192.34',
rest: '',
state: %{ipv4address: '250.246.192.34'},
string_text: '250.246.192.34',
string_tokens: ['250', '.', '246', '.', '192', '.', '34'],
values: ["Your ip address is: 250.246.192.34"]
}

The result can be read as an %ABNF.CaptureResult{} where:

More complex examples

The unit tests use different sample RFCs to test the grammar parser and the interpreter

How it works

This is not a parser generator, but an interpreter. It will load up an ABNF grammar, and generate an (kind of) AST for it. Then you can apply any of the rules to an input and the interpreter will parse the input according to the rule.

Using it with Mix

To use it in your Mix projects, first add it as a dependency:

def deps do
[{:ex_abnf, "~> 0.2.4"}]
end

Then run mix deps.get to install it.

Adding custom code to reduce rules

After a rule, you can add your own code, for example:

userinfo = *( unreserved / pct-encoded / sub-delims / ":" ) !!!
state = Map.put state, :userinfo, rule
{:ok, state}
!!!

The code in question will be packed together into a module that is created in runtime to speed up execution later on.

Your code can return:

And your code will be called with the following bindings:

Adding helper code

You can also start your grammar with code to write your own helper functions and module additions. For example:

!!!
require Logger
def return_value(ip) do
Logger.debug "Hello world"
"Your ip address is: #{ip}"
end
!!!
IPv4address =
dec-octet "."
dec-octet "."
dec-octet "."
dec-octet !!!
state = Map.put state, :ipv4address, rule
{:ok, state, return_value(rule)}
!!!
dec-octet = DIGIT ; 0-9
/ %x31-39 DIGIT ; 10-99
/ "1" 2DIGIT ; 100-199
/ "2" %x30-34 DIGIT ; 200-249
/ "25" %x30-35 ; 250-255
DIGIT = %x30-39

Note how the result of the IPv4address rule is the result of a call to the function return_value.

TODO

Changes from 0.1.x to 0.2.x

License

The source code is released under Apache 2 License.

Check LICENSE file for more information.