Block-Based Configuration Language

3 months ago 3

3.1.Content

BCL content is represented as a sequence of character, each character being a Unicode codepoint. BCL content is always encoded using UTF-8 (see RFC 3629).

3.1.1.Lines

A physical line is a sequence of character sending with an end-of-line sequence being a newline character (U+001A, "\n") optionally preceded by a carriage return character (U+001D, "\r").

A logical line is a sequence of one or more physical lines where all physical lines but the last ends with a backslash character (U+005C, "\").

For example the following document is made of 3 physical lines that are interpreted as 2 logical lines:

match path "/private" reply 401 \ "access denied"

Lines are significant in BCL content: an entry is defined by a single logical line, i.e. one or more physical lines.

3.1.2.Whitespace

Whitespace is defined as a sequence of one or more space (U+0020, " ") or tabulation character (U+0009, "\t").

Whitespace is not significant: in the following example, all three lines are equivalent:

reply 200 "ok" reply 200 "ok" reply 200 "ok"

3.1.4.Tokens

Non-whitespace characters are aggregated into tokens. The following tokens are defined:

Opening brackets
  • The opening delimiter for blocks (U+007B, "{").

Closing brackets
  • The closing delimitere for blocks (U+007D, "}").

Symbols
  • Sequences of alphanumerical characters (U+0030-U+0039, "0" to "9", and U+0061-U+007A, "a" to "z") and underscore characters (U+005F, "_") starting with an alphabetical character (U+0061-U+007A, "a" to "z"). E.g. foo, bar-baz-42.

Strings
  • Sequences of characters starting and ending with a double quote character (U+0022), optionally preceded by a sigil. Double quote characters (U+0022) and backslash characters (U+005C "\") can be included in strings provided that they are escaped with a backslash character. The sigil starts with a tilde character (U+007E, "~") and only contains alphanumerical characters (U+0030-U+0039, "0" to "9", and U+0061-U+007A, "a" to "z"). E.g. "foo", "a \"b\" c", ~re"^ab{1,3}c?".

Integers
  • Decimal integers optionally preceded by a sign character. E.g. 42, -123, +456.

Floats
  • Double precision floating point numbers. E.g. 1.0, -2.345, 0.7e-89.

3.2.Elements

A document contains a sequence of elements, each element being either a block or an entry.

3.2.1.Blocks

A block is a grouping construct starting with a symbol identifying the type of the block, optionally followed by a string (the name of the block), then an opening bracket, a sequence (possibly empty) of elements and a closing bracket.

Examples

# An empty named block account "bob" { } # An unnamed block storage { path "/var/lib/example" }

3.2.2.Entries

An entry is made of a symbol identifying the type of the entry, optionally followed by a list of values, each value being either a symbol, a string, an integer or a float.

Examples

# An entry with no value log_debug_messages # An entry with multiple values match path "/app"

3.2.3.Values

3.2.3.1.Strings

Strings are used to represent arbitrary textual data.

Strings can be annotated with a sigil, a marker signaling that the string can be interpreted with a different semantic. For example the the ~re sigil could be used to indicate that the string is the textual representation of a regular expression. Implementations must not assign meaning to specific sigils: applications are free to interpret them as they see fit, including ignoring them altogether.

3.2.3.2.Integers

Integer values are the decimal representation of signed 64 bit integers.

3.2.3.3.Floats

Float values are the decimal representation of double precision floating point numbers as specified by IEEE 754.

3.2.3.4.Booleans

Boolean values are specified as the true and false symbols.

3.2.3.5.Symbols

Symbols are used to represent fixed values, e.g. enumeration values or constants.

3.2.4.Grammar

The following ABNF grammar (see RFC 5234) is the authoritative description of the BCL language.

document = element* element = block / entry block = block-type [ block-name ] "{" element* "}" block-type = symbol block-name = string entry = entry-name value* entry-name = symbol value = symbol / boolean / string / integer / float symbol = %x61-7A *( %x61-7A / %x30-39 / %x5F) ; /[a-z][a-z0-9_]*/ boolean = "true" / "false" string = [ sigil ] %x22 ( character / escape-sequence ) %x22 character = %x20-21 / %x23-5B / %x5D-7E / %x80-10FFFF character /= %x5C ( %x22 / %x5C ) ; \" \\ character /= %x5C ( %x61 / %x62 / %x74 / %x6E / %x76 / %x66 / %x72) ; \a \b \t \n \v \f \r sigil = %x7E 1*( %x61-7A / %x30-39 ) ; /~[a-z0-9]+/ integer = [ sign ] ( %x30 / ( %x31-39 *%x30-39 ) ) ; /0|(?:[1-9][0-9]*)/ float = [ sign ] integer "." fraction [ exponent ] fraction = 1*%x30-39 ; /[0-9]+/ exponent = ( "e" / "E" ) integer sign = "+" / "-"
Read Entire Article