func (p *parser) addParseErr(positionRange PositionRange, err error) {
	perr := ParseErr{
		PositionRange: positionRange,
		Err:           err,
		Query:         p.lex.input,
	}
	p.parseErrors = append(p.parseErrors, perr)
}
addParseErr appends the provided error to the list of parsing errors.
package parser
import (
	"fmt"
	"math"
	"os"
	"runtime"
	"strconv"
	"strings"
	"sync"
	"time"
	"github.com/pkg/errors"
	"github.com/prometheus/common/model"
	"github.com/prometheus/prometheus/pkg/labels"
	"github.com/prometheus/prometheus/pkg/timestamp"
	"github.com/prometheus/prometheus/util/strutil"
)
var parserPool = sync.Pool{
	New: func() interface{} {
		return &parser{}
	},
}
type parser struct {
	lex Lexer
	inject    ItemType
	injecting bool
	lastClosing Pos
	yyParser yyParserImpl
	generatedParserResult interface{}
	parseErrors           ParseErrors
}
type ParseErr struct {
	PositionRange PositionRange
	Err           error
	Query         string
	LineOffset int
}
func (e *ParseErr) Error() string {
	pos := int(e.PositionRange.Start)
	lastLineBreak := -1
	line := e.LineOffset + 1
	var positionStr string
	if pos < 0 || pos > len(e.Query) {
		positionStr = "invalid position:"
	} else {
		for i, c := range e.Query[:pos] {
			if c == '\n' {
				lastLineBreak = i
				line++
			}
		}
		col := pos - lastLineBreak
		positionStr = fmt.Sprintf("%d:%d:", line, col)
	}
	return fmt.Sprintf("%s parse error: %s", positionStr, e.Err)
}
type ParseErrors []ParseErr
func (errs ParseErrors) Error() string {
	if len(errs) != 0 {
		return errs[0].Error()
	}
	return "error contains no error message"
}
func ParseExpr(input string) (expr Expr, err error) {
	p := newParser(input)
	defer parserPool.Put(p)
	defer p.recover(&err)
	parseResult := p.parseGenerated(START_EXPRESSION)
	if parseResult != nil {
		expr = parseResult.(Expr)
	}
	if len(p.parseErrors) == 0 {
		p.checkAST(expr)
	}
	if len(p.parseErrors) != 0 {
		err = p.parseErrors
	}
	return expr, err
}
func ParseMetric(input string) (m labels.Labels, err error) {
	p := newParser(input)
	defer parserPool.Put(p)
	defer p.recover(&err)
	parseResult := p.parseGenerated(START_METRIC)
	if parseResult != nil {
		m = parseResult.(labels.Labels)
	}
	if len(p.parseErrors) != 0 {
		err = p.parseErrors
	}
	return m, err
}
func ParseMetricSelector(input string) (m []*labels.Matcher, err error) {
	p := newParser(input)
	defer parserPool.Put(p)
	defer p.recover(&err)
	parseResult := p.parseGenerated(START_METRIC_SELECTOR)
	if parseResult != nil {
		m = parseResult.(*VectorSelector).LabelMatchers
	}
	if len(p.parseErrors) != 0 {
		err = p.parseErrors
	}
	return m, err
}
func newParser(input string) *parser {
	p := parserPool.Get().(*parser)
	p.injecting = false
	p.parseErrors = nil
	p.generatedParserResult = nil
	p.lex = Lexer{
		input: input,
		state: lexStatements,
	}
	return p
}
type SequenceValue struct {
	Value   float64
	Omitted bool
}
func (v SequenceValue) String() string {
	if v.Omitted {
		return "_"
	}
	return fmt.Sprintf("%f", v.Value)
}
type seriesDescription struct {
	labels labels.Labels
	values []SequenceValue
}
func ParseSeriesDesc(input string) (labels labels.Labels, values []SequenceValue, err error) {
	p := newParser(input)
	p.lex.seriesDesc = true
	defer parserPool.Put(p)
	defer p.recover(&err)
	parseResult := p.parseGenerated(START_SERIES_DESCRIPTION)
	if parseResult != nil {
		result := parseResult.(*seriesDescription)
		labels = result.labels
		values = result.values
	}
	if len(p.parseErrors) != 0 {
		err = p.parseErrors
	}
	return labels, values, err
}
func (p *parser) addParseErrf(positionRange PositionRange, format string, args ...interface{}) {
	p.addParseErr(positionRange, errors.Errorf(format, args...))
}