Packages

An URI parser trying to be strictly compatible with RFC3986. Uses official ABNF grammar and ex_abnf as interpreter.

Current section

Files

Jump to
ex_rfc3986 priv RFC3986.abnf
Raw

priv/RFC3986.abnf

URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
hier-part = "//" authority path-abempty
/ path-absolute
/ path-rootless
/ path-empty
URI-reference = URI / relative-ref
absolute-URI = scheme ":" hier-part [ "?" query ]
relative-ref = relative-part [ "?" query ] [ "#" fragment ]
relative-part = "//" authority path-abempty
/ path-absolute
/ path-noscheme
/ path-empty
scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) !!!
state = Map.put state, :scheme, rule
{:ok, state}
!!!
authority = [ userinfo "@" ] host [ ":" port ]
userinfo = *( unreserved / pct-encoded / sub-delims / ":" ) !!!
state = Map.put state, :userinfo, rule
{:ok, state}
!!!
host = IP-literal / IPv4address / reg-name
port = *DIGIT !!!
state = Map.put state, :port, rule
{:ok, state}
!!!
IP-literal = "[" ( IPv6address / IPvFuture ) "]"
IPvFuture = "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" ) !!!
state = Map.put state, :host_type, :ipv_future
state = Map.put state, :host, rule
{:ok, state}
!!!
IPv6address = 6( h16 ":" ) ls32
/ "::" 5( h16 ":" ) ls32
/ [ h16 ] "::" 4( h16 ":" ) ls32
/ [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32
/ [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32
/ [ *3( h16 ":" ) h16 ] "::" h16 ":" ls32
/ [ *4( h16 ":" ) h16 ] "::" ls32
/ [ *5( h16 ":" ) h16 ] "::" h16
/ [ *6( h16 ":" ) h16 ] "::" !!!
state = Map.put state, :host, rule
state = Map.put state, :host_type, :ipv6
{:ok, state}
!!!
h16 = 1*4HEXDIG
ls32 = ( h16 ":" h16 ) / IPv4address
IPv4address =
dec-octet "."
dec-octet "."
dec-octet "."
dec-octet !!!
state = Map.put state, :host_type, :ipv4
state = Map.put state, :host, rule
{:ok, state}
!!!
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
reg-name = *( unreserved / pct-encoded / sub-delims ) !!!
state = Map.put state, :host_type, :reg_name
state = Map.put state, :host, rule
{:ok, state}
!!!
path = path-abempty ; begins with "/" or is empty
/ path-absolute ; begins with "/" but not "//"
/ path-noscheme ; begins with a non-colon segment
/ path-rootless ; begins with a segment
/ path-empty ; zero characters
path-abempty = *( "/" segment ) !!!
state = Map.put state, :type, :authority
{:ok, state}
!!!
path-absolute = "/" [ segment-nz *( "/" segment ) ] !!!
state = Map.put state, :type, :path_absolute
{:ok, state}
!!!
path-noscheme = segment-nz-nc *( "/" segment ) !!!
state = Map.put state, :type, :noscheme
{:ok, state}
!!!
path-rootless = segment-nz *( "/" segment ) !!!
state = Map.put state, :type, :path_rootless
{:ok, state}
!!!
path-empty = 0<pchar> !!!
state = Map.put state, :type, :path_empty
{:ok, state}
!!!
segment = *pchar !!!
segments = state.segments
case rule do
[] -> {:ok, state}
_ ->
state = Map.put state, :segments, (segments ++ [rule])
{:ok, state}
end
!!!
segment-nz = 1*pchar !!!
segments = state.segments
state = Map.put state, :segments, Enum.reverse([rule|segments])
{:ok, state}
!!!
segment-nz-nc = 1*( unreserved / pct-encoded / sub-delims / "@" ) !!!
segments = state.segments
state = Map.put state, :segments, Enum.reverse([rule|segments])
{:ok, state}
!!!
; non-zero-length segment without any colon ":"
pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
query = *( pchar / "/" / "?" ) !!!
state = Map.put state, :query, rule
{:ok, state}
!!!
fragment = *( pchar / "/" / "?" ) !!!
state = Map.put state, :fragment, rule
{:ok, state}
!!!
pct-encoded = "%" HEXDIG HEXDIG
unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
reserved = gen-delims / sub-delims
gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@"
sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
/ "*" / "+" / "," / ";" / "="
ALPHA = %x41-5A / %x61-7A ; A-Z / a-z
BIT = "0" / "1"
CHAR = %x01-7F
; any 7-bit US-ASCII character,
; excluding NUL
CR = %x0D
; carriage return
CRLF = CR LF
; Internet standard newline
CTL = %x00-1F / %x7F
; controls
DIGIT = %x30-39
; 0-9
DQUOTE = %x22
; " (Double Quote)
HEXDIG = DIGIT / "A" / "B" / "C" / "D" / "E" / "F"
HTAB = %x09
; horizontal tab
LF = %x0A
; linefeed
LWSP = *(WSP / CRLF WSP)
; linear white space (past newline)
OCTET = %x00-FF
; 8 bits of data
SP = %x20
VCHAR = %x21-7E
; visible (printing) characters
WSP = SP / HTAB
; white space