This never really got finished, but was a fun little project for me to learn about tokenizing / parsing. I think a better solution now would be to implement a json5 parser instead.
Goal: define a "simple" configuration language (yet another) which is easy to write but does not give too much freedom. The configuration language must support a json-like syntax but also be able to load "prettier" structures similar to yaml. The language will be strict in its indentation and form to encourage uniformity.
The python implementation intends to provide the following things:
- A
load,loads,dump,dumpsinterface similar tojson - The ability to retrieve a mutable ast representation which can be used for automatic refactoring of dumbconf files
dumbconf files are invariantly UTF-8 encoded.
- Empty lines are ignored
- Comments start with a
#character followed by a space and a comment - Inline comments must have a whitespace character before and after the
# - (Suggested) It is suggested to put two space characters before the
#as in PEP8
# A comment
true # an inline comment- Both single and quoted strings are appropriate
- Escape sequences in quoted strings will be interpreted according to python rules.
['foo', "foo", 'foo\'bar', "foo\"bar"]- Maps may contain bare words keys
- Keys which would otherwise be interpreted as another value must be quoted
{
im_a_bare_word_key: 'value',
'true': 'indeed, my key needed quoting',
}- There are 2 tokens interpreted as booleans
[true, false]There are four supported forms of integers:
[
# hexadecimal
0xdeadBEEF,
# binary
0b10101010,
# octal
0o755,
# decimal
-1234,
][
# integers with exponents
0e5, 1e-10,
# numbers with a decimal point
0., .5, 1.5,
# numbers with a decimal point and exponent
6.02E23,
]- There is one toke interpreted as null
[null][]['value']['value', 'value', 'value']- Trailing commas are required
[
'value',
'value',
'value',
]- Closing bracket matches starting indentation
- For instance in a mapping type:
{
key: [
'value',
'value',
'value',
],
}- Values may appear inline (to improve readability)
[
'value', 'value', 'value',
'value', 'value',
]- Keys may be any of the primitive types
{}{key: 'value'}{key: 'value', other_key: 'other value'}- Trailing commas are required
{
key1: 'value1',
key2: 'value2',
key3: 'value3',
}- Closing bracket matches starting indentation
- For instance in a mapping type:
{
key: {
key1: 'value1',
key2: 'value2',
key3: 'value3',
},
}- Pairs may appear inline (to improve readability)
{
key1: 'value1', key2: 'value2',
key3: 'value3', key4: 'value4',
}- A top level map may omit brackets and commas
True: ['I', 'am', 'a', 'map']
False: ['I', 'have', 'brackets']# A comment followed by a blank line
scalars: {
bool_values: [true, false], # An inline comment
null_value: [null],
strings: ["double quoted", 'single quoted', 'unicode: \u2603'],
ints: [0xDEADBEEF, 0b101010, 0o755, 0, 1234],
floats: [1., 1e5, .142857, 6.02e23],
}
'a json style map': {"key": "value", "other key": "other value"}
'a json style list': ["i", "am", "a", "list"]
'a python style map': {'key': 'value', 'other key': 'other value'}
'a python style list': ['i', 'am', 'a', 'list']
'a bare words map': {key: 'value', other_key: 'other value'}