Skip to content

Commit b72131b

Browse files
committed
Add support for trailing comma in arrays and maps
1 parent 3607640 commit b72131b

File tree

2 files changed

+58
-9
lines changed

2 files changed

+58
-9
lines changed

parser/parser.go

+26-9
Original file line numberDiff line numberDiff line change
@@ -373,7 +373,22 @@ func (p *parser) parseClosure() Node {
373373
}
374374

375375
func (p *parser) parseArrayExpression(token Token) Node {
376-
nodes := p.parseList("[", "]")
376+
nodes := make([]Node, 0)
377+
378+
p.expect(Bracket, "[")
379+
for !p.current.Is(Bracket, "]") && p.err == nil {
380+
if len(nodes) > 0 {
381+
p.expect(Operator, ",")
382+
if p.current.Is(Bracket, "]") {
383+
goto end
384+
}
385+
}
386+
node := p.parseExpression(0)
387+
nodes = append(nodes, node)
388+
}
389+
end:
390+
p.expect(Bracket, "]")
391+
377392
return &ArrayNode{Base: Loc(token.Location), Nodes: nodes}
378393
}
379394

@@ -384,6 +399,12 @@ func (p *parser) parseMapExpression(token Token) Node {
384399
for !p.current.Is(Bracket, "}") && p.err == nil {
385400
if len(nodes) > 0 {
386401
p.expect(Operator, ",")
402+
if p.current.Is(Bracket, "}") {
403+
goto end
404+
}
405+
if p.current.Is(Operator, ",") {
406+
p.error("unexpected token %v", p.current)
407+
}
387408
}
388409

389410
var key Node
@@ -407,6 +428,7 @@ func (p *parser) parseMapExpression(token Token) Node {
407428
nodes = append(nodes, &PairNode{Base: Loc(token.Location), Key: key, Value: node})
408429
}
409430

431+
end:
410432
p.expect(Bracket, "}")
411433

412434
return &MapNode{Base: Loc(token.Location), Pairs: nodes}
@@ -526,21 +548,16 @@ func isAlphabetic(r rune) bool {
526548
}
527549

528550
func (p *parser) parseArguments() []Node {
529-
return p.parseList("(", ")")
530-
}
531-
532-
func (p *parser) parseList(start, end string) []Node {
533-
p.expect(Bracket, start)
534-
551+
p.expect(Bracket, "(")
535552
nodes := make([]Node, 0)
536-
for !p.current.Is(Bracket, end) && p.err == nil {
553+
for !p.current.Is(Bracket, ")") && p.err == nil {
537554
if len(nodes) > 0 {
538555
p.expect(Operator, ",")
539556
}
540557
node := p.parseExpression(0)
541558
nodes = append(nodes, node)
542559
}
560+
p.expect(Bracket, ")")
543561

544-
p.expect(Bracket, end)
545562
return nodes
546563
}

parser/parser_test.go

+32
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,10 @@ func TestParse(t *testing.T) {
142142
"{foo:1, bar:2}",
143143
&ast.MapNode{Pairs: []ast.Node{&ast.PairNode{Key: &ast.StringNode{Value: "foo"}, Value: &ast.IntegerNode{Value: 1}}, &ast.PairNode{Key: &ast.StringNode{Value: "bar"}, Value: &ast.IntegerNode{Value: 2}}}},
144144
},
145+
{
146+
"{foo:1, bar:2, }",
147+
&ast.MapNode{Pairs: []ast.Node{&ast.PairNode{Key: &ast.StringNode{Value: "foo"}, Value: &ast.IntegerNode{Value: 1}}, &ast.PairNode{Key: &ast.StringNode{Value: "bar"}, Value: &ast.IntegerNode{Value: 2}}}},
148+
},
145149
{
146150
`{"a": 1, 'b': 2}`,
147151
&ast.MapNode{Pairs: []ast.Node{&ast.PairNode{Key: &ast.StringNode{Value: "a"}, Value: &ast.IntegerNode{Value: 1}}, &ast.PairNode{Key: &ast.StringNode{Value: "b"}, Value: &ast.IntegerNode{Value: 2}}}},
@@ -214,6 +218,14 @@ func TestParse(t *testing.T) {
214218
"array[:]",
215219
&ast.SliceNode{Node: &ast.IdentifierNode{Value: "array"}},
216220
},
221+
{
222+
"[]",
223+
&ast.ArrayNode{},
224+
},
225+
{
226+
"[1, 2, 3,]",
227+
&ast.ArrayNode{Nodes: []ast.Node{&ast.IntegerNode{Value: 1}, &ast.IntegerNode{Value: 2}, &ast.IntegerNode{Value: 3}}},
228+
},
217229
}
218230
for _, test := range parseTests {
219231
actual, err := parser.Parse(test.input)
@@ -274,6 +286,26 @@ a map key must be a quoted string, a number, a identifier, or an expression encl
274286
cannot use pointer accessor outside closure (1:1)
275287
| .foo
276288
| ^
289+
290+
[1, 2, 3,,]
291+
unexpected token Operator(",") (1:10)
292+
| [1, 2, 3,,]
293+
| .........^
294+
295+
[,]
296+
unexpected token Operator(",") (1:2)
297+
| [,]
298+
| .^
299+
300+
{,}
301+
a map key must be a quoted string, a number, a identifier, or an expression enclosed in parentheses (unexpected token Operator(",")) (1:2)
302+
| {,}
303+
| .^
304+
305+
{foo:1, bar:2, ,}
306+
unexpected token Operator(",") (1:16)
307+
| {foo:1, bar:2, ,}
308+
| ...............^
277309
`
278310

279311
func TestParse_error(t *testing.T) {

0 commit comments

Comments
 (0)