From bc3827ae156089db553c7afea0d255933427c72a Mon Sep 17 00:00:00 2001 From: Larpon Date: Wed, 27 Oct 2021 19:26:33 +0200 Subject: [PATCH] toml: improve array parsing (#12322) --- vlib/toml/parser/parser.v | 27 ++++++++++++++++++--- vlib/toml/tests/burntsushi.toml-test_test.v | 2 +- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/vlib/toml/parser/parser.v b/vlib/toml/parser/parser.v index 3fec043f2d..b28b37d625 100644 --- a/vlib/toml/parser/parser.v +++ b/vlib/toml/parser/parser.v @@ -508,15 +508,32 @@ pub fn (mut p Parser) array() ?[]ast.Value { util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'parsing array...') mut arr := []ast.Value{} p.expect(.lsbr) ? // '[' bracket + mut previous_token_was_value := false for p.tok.kind != .eof { p.next() ? util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'parsing token "$p.tok.kind" "$p.tok.lit"') + + if previous_token_was_value { + if p.tok.kind != .rsbr && p.tok.kind != .hash { + p.expect(.comma) ? + } + previous_token_was_value = false + } + match p.tok.kind { .boolean { arr << ast.Value(p.boolean() ?) + previous_token_was_value = true } .comma { - util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'skipping comma array value seperator "$p.tok.lit"') + // Trailing commas before array close is allowed + // so we skip `if p.peek_tok.kind == .rsbr { ... }` + if p.peek_tok.kind == .comma { + p.next() ? // Forward to the peek_tok + return error(@MOD + '.' + @STRUCT + '.' + @FN + + ' unexpected "$p.tok.kind" "$p.tok.lit" at this (excerpt): "...${p.excerpt()}..."') + } + util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'skipping comma table value seperator "$p.tok.lit"') continue } .eof { @@ -524,25 +541,29 @@ pub fn (mut p Parser) array() ?[]ast.Value { ' could not parse array. Reached EOF "$p.tok.kind" "$p.tok.lit" ("$p.tok.lit") in this (excerpt): "...${p.excerpt()}..."') } .hash { - // TODO array.comments << p.comment() c := p.comment() + p.ast_root.comments << c util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'skipping comment "$c.text"') } .lcbr { mut t := map[string]ast.Value{} p.inline_table(mut t) ? - ast.Value(t) + arr << ast.Value(t) + previous_token_was_value = true } .number { val := p.number_or_date() ? arr << val + previous_token_was_value = true } .quoted { arr << ast.Value(p.quoted()) + previous_token_was_value = true } .lsbr { util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'parsing array in array "$p.tok.kind" "$p.tok.lit"') arr << ast.Value(p.array() ?) + previous_token_was_value = true } .rsbr { break diff --git a/vlib/toml/tests/burntsushi.toml-test_test.v b/vlib/toml/tests/burntsushi.toml-test_test.v index 3967ba36c3..bb43d4a8a6 100644 --- a/vlib/toml/tests/burntsushi.toml-test_test.v +++ b/vlib/toml/tests/burntsushi.toml-test_test.v @@ -23,7 +23,7 @@ const ( 'table/duplicate-table-array.toml', // Array 'array/tables-1.toml', - 'array/missing-separator.toml', + //'array/missing-separator.toml', 'array/text-after-array-entries.toml', 'array/text-before-array-separator.toml', // Date / Time