func (p *parser) parseSeriesDesc() (m labels.Labels, vals []sequenceValue, err error) {
	defer p.recover(&err)

	m = p.metric()

	const ctx = "series values"
	for {
		for p.peek().typ == ItemSpace {
			p.next()
		}
		if p.peek().typ == ItemEOF {
			break
		}

		// Extract blanks.
		if p.peek().typ == ItemBlank {
			p.next()
			times := uint64(1)
			if p.peek().typ == ItemTimes {
				p.next()
				times, err = strconv.ParseUint(p.expect(ItemNumber, ctx).val, 10, 64)
				if err != nil {
					p.errorf("invalid repetition in %s: %s", ctx, err)
				}
			}
			for i := uint64(0); i < times; i++ {
				vals = append(vals, sequenceValue{omitted: true})
			}
			// This is to ensure that there is a space between this and the next number.
			// This is especially required if the next number is negative.
			if t := p.expectOneOf(ItemSpace, ItemEOF, ctx).typ; t == ItemEOF {
				break
			}
			continue
		}

		// Extract values.
		sign := 1.0
		if t := p.peek().typ; t == ItemSUB || t == ItemADD {
			if p.next().typ == ItemSUB {
				sign = -1
			}
		}
		var k float64
		if t := p.peek().typ; t == ItemNumber {
			k = sign * p.number(p.expect(ItemNumber, ctx).val)
		} else if t == ItemIdentifier && p.peek().val == "stale" {
			p.next()
			k = math.Float64frombits(value.StaleNaN)
		} else {
			p.errorf("expected number or 'stale' in %s but got %s (value: %s)", ctx, t.desc(), p.peek())
		}
		vals = append(vals, sequenceValue{
			value: k,
		})

		// If there are no offset repetitions specified, proceed with the next value.
		if t := p.peek(); t.typ == ItemSpace {
			// This ensures there is a space between every value.
			continue
		} else if t.typ == ItemEOF {
			break
		} else if t.typ != ItemADD && t.typ != ItemSUB {
			p.errorf("expected next value or relative expansion in %s but got %s (value: %s)", ctx, t.desc(), p.peek())
		}

		// Expand the repeated offsets into values.
		sign = 1.0
		if p.next().typ == ItemSUB {
			sign = -1.0
		}
		offset := sign * p.number(p.expect(ItemNumber, ctx).val)
		p.expect(ItemTimes, ctx)

		times, err := strconv.ParseUint(p.expect(ItemNumber, ctx).val, 10, 64)
		if err != nil {
			p.errorf("invalid repetition in %s: %s", ctx, err)
		}

		for i := uint64(0); i < times; i++ {
			k += offset
			vals = append(vals, sequenceValue{
				value: k,
			})
		}
		// This is to ensure that there is a space between this expanding notation
		// and the next number. This is especially required if the next number
		// is negative.
		if t := p.expectOneOf(ItemSpace, ItemEOF, ctx).typ; t == ItemEOF {
			break
		}
	}
	return m, vals, nil
}
func (p *parser) parseSeriesDesc() (m labels.Labels, vals []sequenceValue, err error) {
	defer p.recover(&err)

	m = p.metric()

	const ctx = "series values"
	for {
		for p.peek().typ == ItemSpace {
			p.next()
		}
		if p.peek().typ == ItemEOF {
			break
		}

		
		if p.peek().typ == ItemBlank {
			p.next()
			times := uint64(1)
			if p.peek().typ == ItemTimes {
				p.next()
				times, err = strconv.ParseUint(p.expect(ItemNumber, ctx).val, 10, 64)
				if err != nil {
					p.errorf("invalid repetition in %s: %s", ctx, err)
				}
			}
			for i := uint64(0); i < times; i++ {
				vals = append(vals, sequenceValue{omitted: true})
			}
			
			
			if t := p.expectOneOf(ItemSpace, ItemEOF, ctx).typ; t == ItemEOF {
				break
			}
			continue
		}

		
		sign := 1.0
		if t := p.peek().typ; t == ItemSUB || t == ItemADD {
			if p.next().typ == ItemSUB {
				sign = -1
			}
		}
		var k float64
		if t := p.peek().typ; t == ItemNumber {
			k = sign * p.number(p.expect(ItemNumber, ctx).val)
		} else if t == ItemIdentifier && p.peek().val == "stale" {
			p.next()
			k = math.Float64frombits(value.StaleNaN)
		} else {
			p.errorf("expected number or 'stale' in %s but got %s (value: %s)", ctx, t.desc(), p.peek())
		}
		vals = append(vals, sequenceValue{
			value: k,
		})

		
		if t := p.peek(); t.typ == ItemSpace {
			
			continue
		} else if t.typ == ItemEOF {
			break
		} else if t.typ != ItemADD && t.typ != ItemSUB {
			p.errorf("expected next value or relative expansion in %s but got %s (value: %s)", ctx, t.desc(), p.peek())
		}

		
		sign = 1.0
		if p.next().typ == ItemSUB {
			sign = -1.0
		}
		offset := sign * p.number(p.expect(ItemNumber, ctx).val)
		p.expect(ItemTimes, ctx)

		times, err := strconv.ParseUint(p.expect(ItemNumber, ctx).val, 10, 64)
		if err != nil {
			p.errorf("invalid repetition in %s: %s", ctx, err)
		}

		for i := uint64(0); i < times; i++ {
			k += offset
			vals = append(vals, sequenceValue{
				value: k,
			})
		}
		
		
		
		if t := p.expectOneOf(ItemSpace, ItemEOF, ctx).typ; t == ItemEOF {
			break
		}
	}
	return m, vals, nil
}
func ( p * parser ) parseSeriesDesc ( ) ( m labels . Labels , vals [ ] sequenceValue , err error ) { defer p . recover ( & err ) m = p . metric ( ) const ctx = " " for { for p . peek ( ) . typ == ItemSpace { p . next ( ) } if p . peek ( ) . typ == ItemEOF { break } // Extract blanks. if p . peek ( ) . typ == ItemBlank { p . next ( ) times := uint64 ( 1 ) if p . peek ( ) . typ == ItemTimes { p . next ( ) times , err = strconv . ParseUint ( p . expect ( ItemNumber , ctx ) . val , 10 , 64 ) if err != nil { p . errorf ( " " , ctx , err ) } } for i := uint64 ( 0 ) ; i < times ; i ++ { vals = append ( vals , sequenceValue { omitted : true } ) } // This is to ensure that there is a space between this and the next number. // This is especially required if the next number is negative. if t := p . expectOneOf ( ItemSpace , ItemEOF , ctx ) . typ ; t == ItemEOF { break } continue } // Extract values. sign := 1.0 if t := p . peek ( ) . typ ; t == ItemSUB || t == ItemADD { if p . next ( ) . typ == ItemSUB { sign = - 1 } } var k float64 if t := p . peek ( ) . typ ; t == ItemNumber { k = sign * p . number ( p . expect ( ItemNumber , ctx ) . val ) } else if t == ItemIdentifier && p . peek ( ) . val == " " { p . next ( ) k = math . Float64frombits ( value . StaleNaN ) } else { p . errorf ( " " , ctx , t . desc ( ) , p . peek ( ) ) } vals = append ( vals , sequenceValue { value : k , } ) // If there are no offset repetitions specified, proceed with the next value. if t := p . peek ( ) ; t . typ == ItemSpace { // This ensures there is a space between every value. continue } else if t . typ == ItemEOF { break } else if t . typ != ItemADD && t . typ != ItemSUB { p . errorf ( " " , ctx , t . desc ( ) , p . peek ( ) ) } // Expand the repeated offsets into values. sign = 1.0 if p . next ( ) . typ == ItemSUB { sign = - 1.0 } offset := sign * p . number ( p . expect ( ItemNumber , ctx ) . val ) p . expect ( ItemTimes , ctx ) times , err := strconv . ParseUint ( p . expect ( ItemNumber , ctx ) . val , 10 , 64 ) if err != nil { p . errorf ( " " , ctx , err ) } for i := uint64 ( 0 ) ; i < times ; i ++ { k += offset vals = append ( vals , sequenceValue { value : k , } ) } // This is to ensure that there is a space between this expanding notation // and the next number. This is especially required if the next number // is negative. if t := p . expectOneOf ( ItemSpace , ItemEOF , ctx ) . typ ; t == ItemEOF { break } } return m , vals , nil }
// parseSeriesDesc parses a description of a time series into its metric and value sequence.
parseSeriesDesc parses a description of a time series into its metric and value sequence .