ferronconf 0.2.0

A Rust library for parsing `ferron.conf` configuration files — a domain-specific language for Ferron web server configurations.
Documentation
/* whitespace would be discarded by a lexer */

config          ::= statement* EOF

statement       ::= directive
                  | host-block
                  | match-block
                  | global-block
                  | snippet-block

directive       ::= identifier value* block?

block           ::= '{' statement* '}'

host-block      ::= host-pattern ( ',' host-pattern )* block
                  /* only allowed at top level */

global-block    ::= block
                  /* only allowed at top level */

snippet-block   ::= 'snippet' identifier block

match-block     ::= 'match' identifier matcher-block

matcher-block   ::= '{' matcher-expression* '}'

matcher-expression
                ::= operand operator operand

operand         ::= identifier-path
                  | string
                  | number

value           ::= string
                  | number
                  | boolean
                  | interpolation

interpolation   ::= '{{' identifier-path '}}'

identifier-path ::= identifier ( '.' identifier )*

operator        ::= '=='
                  | '!='
                  | '~'
                  | '!~'
                  | 'in'

host-pattern    ::= protocol? host ( ':' port )?

protocol        ::= identifier | bare-string

host            ::= '*'
                  | hostname
                  | ipv4
                  | '[' ipv6 ']'

hostname        ::= host-label ( '.' host-label )*

host-label      ::= identifier
                  | '*'

ipv4            ::= dec-octet '.' dec-octet '.' dec-octet '.' dec-octet
dec-octet       ::= DIGIT+   /* validated 0–255 by parser */

ipv6            ::= ipv6-hex ( ':' ipv6-hex )*  /* validated by parser */
ipv6-hex         ::= ( DIGIT | [A-Fa-f] )*

port            ::= DIGIT+

string          ::= quoted-string
                  | bare-string

quoted-string   ::= '"' quoted-char* '"'

quoted-char     ::= [^"\\]
                  | '\\' .

bare-string     ::= bare-char+

bare-char       ::= ALPHA
                  | DIGIT
                  | '_'
                  | '-'
                  | '.'
                  | ':'
                  | '/'
                  | '*'
                  | '+'

identifier      ::= ALPHA ( ALPHA | DIGIT | '_' | '-' )*

boolean         ::= 'true'
                  | 'false'

number          ::= '-'? DIGIT+ ( '.' DIGIT+ )?

/* comments are skipped. */
comment         ::= '#' comment-char*
comment-char    ::= . - ( '\r' | '\n' )

ALPHA           ::= [A-Za-z]
DIGIT           ::= [0-9]