func (p *parser) labelMatchers(operators ...ItemType) []*labels.Matcher {
	const ctx = "label matching"

	matchers := []*labels.Matcher{}

	p.expect(ItemLeftBrace, ctx)

	// Check if no matchers are provided.
	if p.peek().typ == ItemRightBrace {
		p.next()
		return matchers
	}

	for {
		label := p.expect(ItemIdentifier, ctx)

		op := p.next().typ
		if !op.isOperator() {
			p.errorf("expected label matching operator but got %s", op)
		}
		var validOp = false
		for _, allowedOp := range operators {
			if op == allowedOp {
				validOp = true
			}
		}
		if !validOp {
			p.errorf("operator must be one of %q, is %q", operators, op)
		}

		val := p.unquoteString(p.expect(ItemString, ctx).val)

		// Map the item to the respective match type.
		var matchType labels.MatchType
		switch op {
		case ItemEQL:
			matchType = labels.MatchEqual
		case ItemNEQ:
			matchType = labels.MatchNotEqual
		case ItemEQLRegex:
			matchType = labels.MatchRegexp
		case ItemNEQRegex:
			matchType = labels.MatchNotRegexp
		default:
			p.errorf("item %q is not a metric match type", op)
		}

		m, err := labels.NewMatcher(matchType, label.val, val)
		if err != nil {
			p.error(err)
		}

		matchers = append(matchers, m)

		if p.peek().typ == ItemIdentifier {
			p.errorf("missing comma before next identifier %q", p.peek().val)
		}

		// Terminate list if last matcher.
		if p.peek().typ != ItemComma {
			break
		}
		p.next()

		// Allow comma after each item in a multi-line listing.
		if p.peek().typ == ItemRightBrace {
			break
		}
	}

	p.expect(ItemRightBrace, ctx)

	return matchers
}
func (p *parser) labelMatchers(operators ...ItemType) []*labels.Matcher {
	const ctx = "label matching"

	matchers := []*labels.Matcher{}

	p.expect(ItemLeftBrace, ctx)

	
	if p.peek().typ == ItemRightBrace {
		p.next()
		return matchers
	}

	for {
		label := p.expect(ItemIdentifier, ctx)

		op := p.next().typ
		if !op.isOperator() {
			p.errorf("expected label matching operator but got %s", op)
		}
		var validOp = false
		for _, allowedOp := range operators {
			if op == allowedOp {
				validOp = true
			}
		}
		if !validOp {
			p.errorf("operator must be one of %q, is %q", operators, op)
		}

		val := p.unquoteString(p.expect(ItemString, ctx).val)

		
		var matchType labels.MatchType
		switch op {
		case ItemEQL:
			matchType = labels.MatchEqual
		case ItemNEQ:
			matchType = labels.MatchNotEqual
		case ItemEQLRegex:
			matchType = labels.MatchRegexp
		case ItemNEQRegex:
			matchType = labels.MatchNotRegexp
		default:
			p.errorf("item %q is not a metric match type", op)
		}

		m, err := labels.NewMatcher(matchType, label.val, val)
		if err != nil {
			p.error(err)
		}

		matchers = append(matchers, m)

		if p.peek().typ == ItemIdentifier {
			p.errorf("missing comma before next identifier %q", p.peek().val)
		}

		
		if p.peek().typ != ItemComma {
			break
		}
		p.next()

		
		if p.peek().typ == ItemRightBrace {
			break
		}
	}

	p.expect(ItemRightBrace, ctx)

	return matchers
}
func ( p * parser ) labelMatchers ( operators ... ItemType ) [ ] * labels . Matcher { const ctx = " " matchers := [ ] * labels . Matcher { } p . expect ( ItemLeftBrace , ctx ) // Check if no matchers are provided. if p . peek ( ) . typ == ItemRightBrace { p . next ( ) return matchers } for { label := p . expect ( ItemIdentifier , ctx ) op := p . next ( ) . typ if ! op . isOperator ( ) { p . errorf ( " " , op ) } var validOp = false for _ , allowedOp := range operators { if op == allowedOp { validOp = true } } if ! validOp { p . errorf ( " " , operators , op ) } val := p . unquoteString ( p . expect ( ItemString , ctx ) . val ) // Map the item to the respective match type. var matchType labels . MatchType switch op { case ItemEQL : matchType = labels . MatchEqual case ItemNEQ : matchType = labels . MatchNotEqual case ItemEQLRegex : matchType = labels . MatchRegexp case ItemNEQRegex : matchType = labels . MatchNotRegexp default : p . errorf ( " " , op ) } m , err := labels . NewMatcher ( matchType , label . val , val ) if err != nil { p . error ( err ) } matchers = append ( matchers , m ) if p . peek ( ) . typ == ItemIdentifier { p . errorf ( " " , p . peek ( ) . val ) } // Terminate list if last matcher. if p . peek ( ) . typ != ItemComma { break } p . next ( ) // Allow comma after each item in a multi-line listing. if p . peek ( ) . typ == ItemRightBrace { break } } p . expect ( ItemRightBrace , ctx ) return matchers }
// labelMatchers parses a set of label matchers.
//
//		'{' [ <labelname> <match_op> <match_string>, ... ] '}'
//
labelMatchers parses a set of label matchers . { [ <labelname > <match_op > <match_string > ... ] }