package parse import ( "git.makaay.nl/mauricem/go-parsekit/parse" "git.makaay.nl/mauricem/go-toml/ast" ) // 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 ( arrayWhitespaceComment = c.OneOrMore(whitespaceInclNewlines.Or(comment)) arrayOpen = a.SquareOpen.Then(arrayWhitespaceComment.Optional()) arraySeparator = c.Seq(whitespace, a.Comma, arrayWhitespaceComment.Optional()) arrayClose = c.Seq(whitespace, a.Comma.Optional(), arrayWhitespaceComment.Optional(), a.SquareClose) ) func (t *parser) parseArray(p *parse.API) (*ast.Value, bool) { // Check for the start of the array. if !p.Accept(arrayOpen) { p.Expected("an array") return nil, false } a := ast.NewArray() // Check for an empty array. if p.Accept(arrayClose) { return ast.NewValue(ast.TypeArray, a), true } // Not an empty array, parse the array values. 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). // This constraint is checked by ast.Array.Append(). if err := a.Append(value); err != nil { p.Error(err.Error()) return nil, false } // Check for the end of the array. if p.Accept(arrayClose) { return ast.NewValue(ast.TypeArray, a), 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 } } }