112 lines
3.1 KiB
Go
112 lines
3.1 KiB
Go
package toml
|
|
|
|
import (
|
|
"git.makaay.nl/mauricem/go-parsekit/parse"
|
|
)
|
|
|
|
var (
|
|
// Tables (also known as hash tables or dictionaries) are collections of
|
|
// key/value pairs. They appear in square brackets on a line by themselves.
|
|
// You can tell them apart from arrays because arrays are only ever values.
|
|
//
|
|
// Under that, and until the next table or EOF are the key/values of that
|
|
// table. Key/value pairs within tables are not guaranteed to be in any
|
|
// specific order.
|
|
//
|
|
// [table-1]
|
|
// key1 = "some string"
|
|
// key2 = 123
|
|
//
|
|
// [table-2]
|
|
// key1 = "another string"
|
|
// key2 = 456
|
|
//
|
|
// Naming rules for tables are the same as for keys.
|
|
//
|
|
// [dog."tater.man"]
|
|
// type.name = "pug"
|
|
//
|
|
// Whitespace around the key is ignored, however, best practice is to not
|
|
// use any extraneous whitespace.
|
|
//
|
|
// [a.b.c] # this is best practice
|
|
// [ d.e.f ] # same as [d.e.f]
|
|
// [ g . h . i ] # same as [g.h.i]
|
|
// [ j . "ʞ" . 'l' ] # same as [j."ʞ".'l']
|
|
//
|
|
// You don't need to specify all the super-tables if you don't want to.
|
|
// TOML knows how to do it for you.
|
|
//
|
|
// # [x] you
|
|
// # [x.y] don't
|
|
// # [x.y.z] need these
|
|
// [x.y.z.w] # for this to work
|
|
//
|
|
// Empty tables are allowed and simply have no key/value pairs within them.
|
|
//
|
|
tableOpen = c.Seq(dropBlanks, a.SquareOpen, dropBlanks)
|
|
tableClose = c.Seq(dropBlanks, a.SquareClose, dropBlanks, a.EndOfLine.Or(comment))
|
|
|
|
// Arrays of tables can be expressed by using a table name in double brackets.
|
|
// Each table with the same double bracketed name will be an element in the
|
|
// array. The tables are inserted in the order encountered. A double bracketed
|
|
// table without any key/value pairs will be considered an empty table.
|
|
//
|
|
// [[products]]
|
|
// name = "Hammer"
|
|
// sku = 738594937
|
|
//
|
|
// [[products]]
|
|
//
|
|
// [[products]]
|
|
// name = "Nail"
|
|
// sku = 284758393
|
|
// color = "gray"
|
|
//
|
|
// You can create nested arrays of tables as well. Just use the same double
|
|
// bracket syntax on sub-tables. Each double-bracketed sub-table will belong
|
|
// to the most recently defined table element above it.
|
|
//
|
|
// [[fruit]]
|
|
// name = "apple"
|
|
//
|
|
// [fruit.physical]
|
|
// color = "red"
|
|
// shape = "round"
|
|
//
|
|
// [[fruit.variety]]
|
|
// name = "red delicious"
|
|
//
|
|
// [[fruit.variety]]
|
|
// name = "granny smith"
|
|
//
|
|
// [[fruit]]
|
|
// name = "banana"
|
|
//
|
|
// [[fruit.variety]]
|
|
// name = "plantain"
|
|
tableArrayOpen = c.Seq(dropBlanks, a.SquareOpen, a.SquareOpen, dropBlanks)
|
|
tableArrayClose = c.Seq(dropBlanks, a.SquareClose, a.SquareClose, a.EndOfLine.Or(comment))
|
|
)
|
|
|
|
func (t *parser) startTable(p *parse.API) {
|
|
switch {
|
|
case p.Accept(tableOpen):
|
|
p.Handle(t.startPlainTable)
|
|
default:
|
|
p.Expected("a table")
|
|
}
|
|
}
|
|
|
|
func (t *parser) startPlainTable(p *parse.API) {
|
|
if !p.Handle(t.startKey) {
|
|
return
|
|
}
|
|
if !p.Accept(tableClose) {
|
|
p.Expected("closing ']' for table name")
|
|
}
|
|
key := t.Items[0]
|
|
t.Items = t.Items[1:]
|
|
t.newTable(key)
|
|
}
|