package toml import ( "git.makaay.nl/mauricem/go-parsekit/parse" ) // Arrays are square brackets with values inside. Whitespace is ignored. // Elements are separated by commas. Data types may not be mixed (different // ways to define strings should be considered the same type, and so should // arrays with different element types). // // arr1 = [ 1, 2, 3 ] // arr2 = [ "red", "yellow", "green" ] // arr3 = [ [ 1, 2 ], [3, 4, 5] ] // arr4 = [ "all", 'strings', """are the same""", '''type'''] // arr5 = [ [ 1, 2 ], ["a", "b", "c"] ] // // arr6 = [ 1, 2.0 ] # INVALID // // Arrays can also be multiline. A terminating comma (also called trailing // comma) is ok after the last value of the array. There can be an arbitrary // number of newlines and comments before a value and before the closing bracket. // // arr7 = [ // 1, 2, 3 // ] // // arr8 = [ // 1, // 2, # this is ok // ] var ( arraySpace = c.ZeroOrMore(c.Any(blank, newline, comment)) arrayOpen = a.SquareOpen.Then(arraySpace) arraySeparator = c.Seq(arraySpace, a.Comma, arraySpace) arrayClose = c.Seq(c.Optional(arraySpace.Then(a.Comma)), arraySpace, a.SquareClose) ) func (t *parser) parseArray(p *parse.API) (*item, bool) { // Check for the start of the array. if !p.Accept(arrayOpen) { p.Expected("an array") return nil, false } // Check for an empty array. if p.Accept(arrayClose) { return newItem(pArray), true } // Not an empty array, parse the array items. items := []interface{}{} for { // Check for a value item. value, ok := t.parseValue(p) if !ok { return nil, false } // Data types may not be mixed (different ways to define strings should be // considered the same type, and so should arrays with different element types). if len(items) > 0 && value.Type != items[0].(*item).Type { p.Error("type mismatch in array of %ss: found an item of type %s", items[0].(*item).Type, value.Type) return nil, false } items = append(items, value) // Check for the end of the array. if p.Accept(arrayClose) { return newItem(pArray, items...), true } // Not the end of the array? Then we should find an array separator. if !p.Accept(arraySeparator) { p.Expected("an array separator") return nil, false } } }