RASCL 1.0 Specification

Author: Matt Gushee
Version: Review draft 1
Date: June 10, 2006
Copyright: This document is licensed under the Creative Commons Attribution-NonCommercial-NoDerivs 2.5 license

1   Introduction

RASCL stands for RASCL's A Simple Configuration Language. RASCL is intended for use in software configuration files. As its name suggests, it does not support all possible use cases; rather, it attempts to be intuitive and easy to use, both for end users and implementors. This document is a technical description of the language, consisting of an English-language description and an EBNF syntax definition. If you are interested in why RASCL is the way it is, you may wish to read the accompanying design notes. For example configuration files written in RASCL, see the examples.

2   Description

2.1   Data types and structures

2.1.1   Primitives

Four primitive data types are supported:

  • integer
  • float,
  • boolean, and
  • string.

Integers may be written in decimal, octal, or hexadecimal notation. Hexadecimal numbers are prefixed with 0x, and octals with 0o.

Floating point syntax follows the OCaml convention, where at least one digit is required before the decimal point, but there can be zero or more digits after the decimal point. E.g., 3.14159, 0.7, and 225. are all valid floats, but .03 is invalid.

The boolean type consists of the words true and false in any combination of upper and lower case; thus, true, FALSE, truE, False, and tRUe are all valid booleans.

Finally, any group of characters that does not match any other data type is considered a string; in general, double quotes are not required, but they may be used to force a value to be interpreted as a string when it would otherwise be parsed as a different type, or when the string contains unescaped special characters.

2.1.2   Lists

A list is a homogenous ordered collection consisting of zero or more elements of one of the primitive types, enclosed in square brackets ([ .. ]) and separated by commas and/or newlines.

2.1.3   Dictionaries

A dictionary consists of zero or more key-value pairs separated by commas and/or newlines. With the exception noted in File structure, a dictionary must be enclosed in curly braces ({ .. }). A key-value pair consists of a string key and a value, which may be of any data type, separated by a colon (:); the colon may be preceded and followed by one or more white space characters. Note that while this specification allows any string to be used as a key (and requires a RASCL parser to accept any string), it may be desirable in practice to require keys to be valid identifiers in the target programming language.

Comments and blank lines may occur anywhere in a multiline dictionary.

2.2   Comments

Comments are denoted with the character #. Any text beginning with this character and ending with the end of the line is a comment. When the # character occurs within a double-quoted string or is escaped with \, it will be interpreted as a normal character.

Multiline comments are not currently supported.

[Note to implementors: since a newline is a separator, and a comment may occur at the end of a line containing non-comment values, a RASCL lexer should treat comments as separators]

2.3   Special characters

The following characters have special meanings in RASCL:

'#'         Start of comment
':'         Assignment--occurs between key and value
'"'         String delimiter
'\'         Escape character
'[', ']'    List delimiters
'{', '}'    Dictionary delimiters
',', LF     List/dictionary separator

Any of these special characters may be interpreted as a normal character by escaping it with the escape character. Except for '"' and '', any special character is interpreted as a normal character when it occurs in a double-quoted string.

2.4   Configuration files

2.4.1   File structure

A RASCL configuration file is an implicit dictionary. This means that its contents consist of one dictionary as described in Dictionaries, except that the opening and closing braces are omitted.

2.4.2   File extensions

This specification does not require a RASCL file to have any particular extension, but .rsc is suggested.

3   Formal Syntax

dict_content   := dict_entry?
                | dict_entry (separator dict_entry)*) separator?
dict_entry     := dict_key inline_space* ':' inline_space* dict_value
dict_key       := string
dict_value     := bool
                | integer
                | float
                | ustring
                | qstring
                | list
                | dictionary
list           := '[' inline_space* list_content inline_space* ']'
list_content   := separator?
                | bool (separator bool)* separator?
                | int (separator int)* separator?
                | float (separator float)* separator?
                | string (separator string)* separator?
dictionary     := '{' white_space* dict_content white_space* '}'
inline_space   := #x9|#x10|#xB
white_space    := #x9|#x10|#xA|#xB
bool           := [Tt] [Rr] [Uu] [Ee]
                | [Ff] [Aa] [Ll] [Ss] [Ee]
integer        := oct_int | hex_int | dec_int
oct_int        := '0' 'o' [0-7]+
hex_int        := '0' 'x' [0-9A-Fa-f]+
dec_int        := [0-9]+
float          := [0-9]+ '.' [0-9]* | '.' [0-9]+
string         := ustring | qstring
ustring        := [^ ][{},:" #xA ]+
qstring        := '"' ([#x1-#x9] | [#xB-#x21] | [#x23-#xFF] | '\' #xA | '\"')* '"'
separator      := ','
                | comment? #xA
comment        := '#' [^#xA]* '\n'