promql/parse.go
func (p *parser) labels() []string {
	const ctx = "grouping opts"

	p.expect(ItemLeftParen, ctx)

	labels := []string{}
	if p.peek().typ != ItemRightParen {
		for {
			id := p.next()
			if !isLabel(id.val) {
				p.errorf("unexpected %s in %s, expected label", id.desc(), ctx)
			}
			labels = append(labels, id.val)

			if p.peek().typ != ItemComma {
				break
			}
			p.next()
		}
	}
	p.expect(ItemRightParen, ctx)

	return labels
}
func (p *parser) labels() []string {
	const ctx = "grouping opts"

	p.expect(ItemLeftParen, ctx)

	labels := []string{}
	if p.peek().typ != ItemRightParen {
		for {
			id := p.next()
			if !isLabel(id.val) {
				p.errorf("unexpected %s in %s, expected label", id.desc(), ctx)
			}
			labels = append(labels, id.val)

			if p.peek().typ != ItemComma {
				break
			}
			p.next()
		}
	}
	p.expect(ItemRightParen, ctx)

	return labels
}
// labels parses a list of labelnames.
//
//		'(' <label_name>, ... ')'
//