Repository: prometheus/prometheus
Pull request #13593 (2024-02-16 13:22:47)

discovery: kubernetes: Avoid creating unnecessary Kubernetes indexers…
… in RoleEndpointSlice

This was due to a missing "return", see https://github.com/prometheus/prometheus/pull/13554#discussion_r1490965817

<!--
    Please give your PR a title in the form "area: short description".  For example "tsdb: reduce disk usage by 95%"

    If your PR is to fix an issue, put "Fixes #issue-number" in the description.

    Don't forget!

    - Please sign CNCF's Developer Certificate of Origin and sign-off your commits by adding the -s / --signoff flag to `git commit`. See https://github.com/apps/dco for more information.

    - If the PR adds or changes a behaviour or fixes a bug of an exported API it would need a unit/e2e test.

    - Where possible use only exported APIs for tests to simplify the review and make it as close as possible to an actual library usage.

    - Performance improvements would need a benchmark test to prove it.

    - All exposed objects should have a comment.

    - All comments should start with a capital letter and end with a full stop.
 -->



Patch:
diff --git a/discovery/kubernetes/kubernetes.go b/discovery/kubernetes/kubernetes.go
index 489365fa4..d6b811584 100644
--- a/discovery/kubernetes/kubernetes.go
+++ b/discovery/kubernetes/kubernetes.go
@@ -815,7 +815,7 @@ func (d *Discovery) newEndpointsByNodeInformer(plw *cache.ListWatch) cache.Share
 func (d *Discovery) newEndpointSlicesByNodeInformer(plw *cache.ListWatch, object runtime.Object) cache.SharedIndexInformer {
 	indexers := make(map[string]cache.IndexFunc)
 	if !d.attachMetadata.Node {
-		cache.NewSharedIndexInformer(plw, &disv1.EndpointSlice{}, resyncDisabled, indexers)
+		return cache.NewSharedIndexInformer(plw, object, resyncDisabled, indexers)
 	}
 
 	indexers[nodeIndex] = func(obj interface{}) ([]string, error) {
diff --git a/go.mod b/go.mod
index faf9c2627..0ba4deb40 100644
--- a/go.mod
+++ b/go.mod
@@ -52,7 +52,7 @@ require (
 	github.com/prometheus/alertmanager v0.26.0
 	github.com/prometheus/client_golang v1.18.0
 	github.com/prometheus/client_model v0.5.0
-	github.com/prometheus/common v0.47.0
+	github.com/prometheus/common v0.46.0
 	github.com/prometheus/common/assets v0.2.0
 	github.com/prometheus/common/sigv4 v0.1.0
 	github.com/prometheus/exporter-toolkit v0.11.0
diff --git a/go.sum b/go.sum
index 8c362eb86..fd9c104ca 100644
--- a/go.sum
+++ b/go.sum
@@ -670,8 +670,8 @@ github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8b
 github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
 github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
 github.com/prometheus/common v0.29.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
-github.com/prometheus/common v0.47.0 h1:p5Cz0FNHo7SnWOmWmoRozVcjEp0bIVU8cV7OShpjL1k=
-github.com/prometheus/common v0.47.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc=
+github.com/prometheus/common v0.46.0 h1:doXzt5ybi1HBKpsZOL0sSkaNHJJqkyfEWZGGqqScV0Y=
+github.com/prometheus/common v0.46.0/go.mod h1:Tp0qkxpb9Jsg54QMe+EAmqXkSV7Evdy1BTn+g2pa/hQ=
 github.com/prometheus/common/assets v0.2.0 h1:0P5OrzoHrYBOSM1OigWL3mY8ZvV2N4zIE/5AahrSrfM=
 github.com/prometheus/common/assets v0.2.0/go.mod h1:D17UVUE12bHbim7HzwUvtqm6gwBEaDQ0F+hIGbFbccI=
 github.com/prometheus/common/sigv4 v0.1.0 h1:qoVebwtwwEhS85Czm2dSROY5fTo2PAPEVdDeppTwGX4=
diff --git a/model/textparse/openmetricslex.l b/model/textparse/openmetricslex.l
index 9afbbbd8b..91e443942 100644
--- a/model/textparse/openmetricslex.l
+++ b/model/textparse/openmetricslex.l
@@ -50,15 +50,12 @@ S     [ ]
 <sComment>TYPE{S}                     l.state = sMeta1; return tType
 <sComment>UNIT{S}                     l.state = sMeta1; return tUnit
 <sComment>"EOF"\n?                    l.state = sInit; return tEOFWord
-<sMeta1>\"(\\.|[^\\"])*\"             l.state = sMeta2; return tMName
 <sMeta1>{M}({M}|{D})*                 l.state = sMeta2; return tMName
 <sMeta2>{S}{C}*\n                     l.state = sInit; return tText
 
 {M}({M}|{D})*                         l.state = sValue; return tMName
 <sValue>\{                            l.state = sLabels; return tBraceOpen
-\{                                    l.state = sLabels; return tBraceOpen
 <sLabels>{L}({L}|{D})*                return tLName
-<sLabels>\"(\\.|[^\\"])*\"            l.state = sLabels; return tQString
 <sLabels>\}                           l.state = sValue; return tBraceClose
 <sLabels>=                            l.state = sLValue; return tEqual
 <sLabels>,                            return tComma
diff --git a/model/textparse/openmetricslex.l.go b/model/textparse/openmetricslex.l.go
index c8789ef60..9f17cfd43 100644
--- a/model/textparse/openmetricslex.l.go
+++ b/model/textparse/openmetricslex.l.go
@@ -37,25 +37,25 @@ yystate0:
 	case 0: // start condition: INITIAL
 		goto yystart1
 	case 1: // start condition: sComment
-		goto yystart6
+		goto yystart5
 	case 2: // start condition: sMeta1
-		goto yystart26
+		goto yystart25
 	case 3: // start condition: sMeta2
-		goto yystart31
+		goto yystart27
 	case 4: // start condition: sLabels
-		goto yystart34
+		goto yystart30
 	case 5: // start condition: sLValue
-		goto yystart42
+		goto yystart35
 	case 6: // start condition: sValue
-		goto yystart46
+		goto yystart39
 	case 7: // start condition: sTimestamp
-		goto yystart50
+		goto yystart43
 	case 8: // start condition: sExemplar
-		goto yystart57
+		goto yystart50
 	case 9: // start condition: sEValue
-		goto yystart62
+		goto yystart55
 	case 10: // start condition: sETimestamp
-		goto yystart68
+		goto yystart61
 	}
 
 yystate1:
@@ -68,8 +68,6 @@ yystart1:
 		goto yystate2
 	case c == ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z':
 		goto yystate4
-	case c == '{':
-		goto yystate5
 	}
 
 yystate2:
@@ -89,574 +87,514 @@ yystate4:
 	c = l.next()
 	switch {
 	default:
-		goto yyrule9
+		goto yyrule8
 	case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z':
 		goto yystate4
 	}
 
 yystate5:
 	c = l.next()
-	goto yyrule11
-
-yystate6:
-	c = l.next()
-yystart6:
+yystart5:
 	switch {
 	default:
 		goto yyabort
 	case c == 'E':
-		goto yystate7
+		goto yystate6
 	case c == 'H':
-		goto yystate11
+		goto yystate10
 	case c == 'T':
-		goto yystate16
+		goto yystate15
 	case c == 'U':
-		goto yystate21
+		goto yystate20
 	}
 
-yystate7:
+yystate6:
 	c = l.next()
 	switch {
 	default:
 		goto yyabort
 	case c == 'O':
-		goto yystate8
+		goto yystate7
 	}
 
-yystate8:
+yystate7:
 	c = l.next()
 	switch {
 	default:
 		goto yyabort
 	case c == 'F':
-		goto yystate9
+		goto yystate8
 	}
 
-yystate9:
+yystate8:
 	c = l.next()
 	switch {
 	default:
 		goto yyrule5
 	case c == '\n':
-		goto yystate10
+		goto yystate9
 	}
 
-yystate10:
+yystate9:
 	c = l.next()
 	goto yyrule5
 
-yystate11:
+yystate10:
 	c = l.next()
 	switch {
 	default:
 		goto yyabort
 	case c == 'E':
-		goto yystate12
+		goto yystate11
 	}
 
-yystate12:
+yystate11:
 	c = l.next()
 	switch {
 	default:
 		goto yyabort
 	case c == 'L':
-		goto yystate13
+		goto yystate12
 	}
 
-yystate13:
+yystate12:
 	c = l.next()
 	switch {
 	default:
 		goto yyabort
 	case c == 'P':
-		goto yystate14
+		goto yystate13
 	}
 
-yystate14:
+yystate13:
 	c = l.next()
 	switch {
 	default:
 		goto yyabort
 	case c == ' ':
-		goto yystate15
+		goto yystate14
 	}
 
-yystate15:
+yystate14:
 	c = l.next()
 	goto yyrule2
 
-yystate16:
+yystate15:
 	c = l.next()
 	switch {
 	default:
 		goto yyabort
 	case c == 'Y':
-		goto yystate17
+		goto yystate16
 	}
 
-yystate17:
+yystate16:
 	c = l.next()
 	switch {
 	default:
 		goto yyabort
 	case c == 'P':
-		goto yystate18
+		goto yystate17
 	}
 
-yystate18:
+yystate17:
 	c = l.next()
 	switch {
 	default:
 		goto yyabort
 	case c == 'E':
-		goto yystate19
+		goto yystate18
 	}
 
-yystate19:
+yystate18:
 	c = l.next()
 	switch {
 	default:
 		goto yyabort
 	case c == ' ':
-		goto yystate20
+		goto yystate19
 	}
 
-yystate20:
+yystate19:
 	c = l.next()
 	goto yyrule3
 
-yystate21:
+yystate20:
 	c = l.next()
 	switch {
 	default:
 		goto yyabort
 	case c == 'N':
-		goto yystate22
+		goto yystate21
 	}
 
-yystate22:
+yystate21:
 	c = l.next()
 	switch {
 	default:
 		goto yyabort
 	case c == 'I':
-		goto yystate23
+		goto yystate22
 	}
 
-yystate23:
+yystate22:
 	c = l.next()
 	switch {
 	default:
 		goto yyabort
 	case c == 'T':
-		goto yystate24
+		goto yystate23
 	}
 
-yystate24:
+yystate23:
 	c = l.next()
 	switch {
 	default:
 		goto yyabort
 	case c == ' ':
-		goto yystate25
+		goto yystate24
 	}
 
-yystate25:
+yystate24:
 	c = l.next()
 	goto yyrule4
 
-yystate26:
+yystate25:
 	c = l.next()
-yystart26:
+yystart25:
 	switch {
 	default:
 		goto yyabort
-	case c == '"':
-		goto yystate27
 	case c == ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z':
-		goto yystate30
+		goto yystate26
 	}
 
-yystate27:
-	c = l.next()
-	switch {
-	default:
-		goto yyabort
-	case c == '"':
-		goto yystate28
-	case c == '\\':
-		goto yystate29
-	case c >= '\x01' && c <= '!' || c >= '#' && c <= '[' || c >= ']' && c <= 'ÿ':
-		goto yystate27
-	}
-
-yystate28:
-	c = l.next()
-	goto yyrule6
-
-yystate29:
-	c = l.next()
-	switch {
-	default:
-		goto yyabort
-	case c >= '\x01' && c <= '\t' || c >= '\v' && c <= 'ÿ':
-		goto yystate27
-	}
-
-yystate30:
+yystate26:
 	c = l.next()
 	switch {
 	default:
-		goto yyrule7
+		goto yyrule6
 	case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z':
-		goto yystate30
+		goto yystate26
 	}
 
-yystate31:
+yystate27:
 	c = l.next()
-yystart31:
+yystart27:
 	switch {
 	default:
 		goto yyabort
 	case c == ' ':
-		goto yystate32
+		goto yystate28
 	}
 
-yystate32:
+yystate28:
 	c = l.next()
 	switch {
 	default:
 		goto yyabort
 	case c == '\n':
-		goto yystate33
+		goto yystate29
 	case c >= '\x01' && c <= '\t' || c >= '\v' && c <= 'ÿ':
-		goto yystate32
+		goto yystate28
 	}
 
-yystate33:
+yystate29:
 	c = l.next()
-	goto yyrule8
+	goto yyrule7
 
-yystate34:
+yystate30:
 	c = l.next()
-yystart34:
+yystart30:
 	switch {
 	default:
 		goto yyabort
-	case c == '"':
-		goto yystate35
 	case c == ',':
-		goto yystate38
+		goto yystate31
 	case c == '=':
-		goto yystate39
+		goto yystate32
 	case c == '}':
-		goto yystate41
+		goto yystate34
 	case c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z':
-		goto yystate40
-	}
-
-yystate35:
-	c = l.next()
-	switch {
-	default:
-		goto yyabort
-	case c == '"':
-		goto yystate36
-	case c == '\\':
-		goto yystate37
-	case c >= '\x01' && c <= '!' || c >= '#' && c <= '[' || c >= ']' && c <= 'ÿ':
-		goto yystate35
+		goto yystate33
 	}
 
-yystate36:
+yystate31:
 	c = l.next()
 	goto yyrule13
 
-yystate37:
-	c = l.next()
-	switch {
-	default:
-		goto yyabort
-	case c >= '\x01' && c <= '\t' || c >= '\v' && c <= 'ÿ':
-		goto yystate35
-	}
-
-yystate38:
-	c = l.next()
-	goto yyrule16
-
-yystate39:
+yystate32:
 	c = l.next()
-	goto yyrule15
+	goto yyrule12
 
-yystate40:
+yystate33:
 	c = l.next()
 	switch {
 	default:
-		goto yyrule12
+		goto yyrule10
 	case c >= '0' && c <= '9' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z':
-		goto yystate40
+		goto yystate33
 	}
 
-yystate41:
+yystate34:
 	c = l.next()
-	goto yyrule14
+	goto yyrule11
 
-yystate42:
+yystate35:
 	c = l.next()
-yystart42:
+yystart35:
 	switch {
 	default:
 		goto yyabort
 	case c == '"':
-		goto yystate43
+		goto yystate36
 	}
 
-yystate43:
+yystate36:
 	c = l.next()
 	switch {
 	default:
 		goto yyabort
 	case c == '"':
-		goto yystate44
+		goto yystate37
 	case c == '\\':
-		goto yystate45
+		goto yystate38
 	case c >= '\x01' && c <= '\t' || c >= '\v' && c <= '!' || c >= '#' && c <= '[' || c >= ']' && c <= 'ÿ':
-		goto yystate43
+		goto yystate36
 	}
 
-yystate44:
+yystate37:
 	c = l.next()
-	goto yyrule17
+	goto yyrule14
 
-yystate45:
+yystate38:
 	c = l.next()
 	switch {
 	default:
 		goto yyabort
 	case c >= '\x01' && c <= '\t' || c >= '\v' && c <= 'ÿ':
-		goto yystate43
+		goto yystate36
 	}
 
-yystate46:
+yystate39:
 	c = l.next()
-yystart46:
+yystart39:
 	switch {
 	default:
 		goto yyabort
 	case c == ' ':
-		goto yystate47
+		goto yystate40
 	case c == '{':
-		goto yystate49
+		goto yystate42
 	}
 
-yystate47:
+yystate40:
 	c = l.next()
 	switch {
 	default:
 		goto yyabort
 	case c >= '\x01' && c <= '\t' || c >= '\v' && c <= '\x1f' || c >= '!' && c <= 'ÿ':
-		goto yystate48
+		goto yystate41
 	}
 
-yystate48:
+yystate41:
 	c = l.next()
 	switch {
 	default:
-		goto yyrule18
+		goto yyrule15
 	case c >= '\x01' && c <= '\t' || c >= '\v' && c <= '\x1f' || c >= '!' && c <= 'ÿ':
-		goto yystate48
+		goto yystate41
 	}
 
-yystate49:
+yystate42:
 	c = l.next()
-	goto yyrule10
+	goto yyrule9
 
-yystate50:
+yystate43:
 	c = l.next()
-yystart50:
+yystart43:
 	switch {
 	default:
 		goto yyabort
 	case c == ' ':
-		goto yystate52
+		goto yystate45
 	case c == '\n':
-		goto yystate51
+		goto yystate44
 	}
 
-yystate51:
+yystate44:
 	c = l.next()
-	goto yyrule20
+	goto yyrule17
 
-yystate52:
+yystate45:
 	c = l.next()
 	switch {
 	default:
 		goto yyabort
 	case c == '#':
-		goto yystate54
+		goto yystate47
 	case c >= '\x01' && c <= '\t' || c >= '\v' && c <= '\x1f' || c == '!' || c == '"' || c >= '$' && c <= 'ÿ':
-		goto yystate53
+		goto yystate46
 	}
 
-yystate53:
+yystate46:
 	c = l.next()
 	switch {
 	default:
-		goto yyrule19
+		goto yyrule16
 	case c >= '\x01' && c <= '\t' || c >= '\v' && c <= '\x1f' || c >= '!' && c <= 'ÿ':
-		goto yystate53
+		goto yystate46
 	}
 
-yystate54:
+yystate47:
 	c = l.next()
 	switch {
 	default:
-		goto yyrule19
+		goto yyrule16
 	case c == ' ':
-		goto yystate55
+		goto yystate48
 	case c >= '\x01' && c <= '\t' || c >= '\v' && c <= '\x1f' || c >= '!' && c <= 'ÿ':
-		goto yystate53
+		goto yystate46
 	}
 
-yystate55:
+yystate48:
 	c = l.next()
 	switch {
 	default:
 		goto yyabort
 	case c == '{':
-		goto yystate56
+		goto yystate49
 	}
 
-yystate56:
+yystate49:
 	c = l.next()
-	goto yyrule21
+	goto yyrule18
 
-yystate57:
+yystate50:
 	c = l.next()
-yystart57:
+yystart50:
 	switch {
 	default:
 		goto yyabort
 	case c == ',':
-		goto yystate58
+		goto yystate51
 	case c == '=':
-		goto yystate59
+		goto yystate52
 	case c == '}':
-		goto yystate61
+		goto yystate54
 	case c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z':
-		goto yystate60
+		goto yystate53
 	}
 
-yystate58:
+yystate51:
 	c = l.next()
-	goto yyrule26
+	goto yyrule23
 
-yystate59:
+yystate52:
 	c = l.next()
-	goto yyrule24
+	goto yyrule21
 
-yystate60:
+yystate53:
 	c = l.next()
 	switch {
 	default:
-		goto yyrule22
+		goto yyrule19
 	case c >= '0' && c <= '9' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z':
-		goto yystate60
+		goto yystate53
 	}
 
-yystate61:
+yystate54:
 	c = l.next()
-	goto yyrule23
+	goto yyrule20
 
-yystate62:
+yystate55:
 	c = l.next()
-yystart62:
+yystart55:
 	switch {
 	default:
 		goto yyabort
 	case c == ' ':
-		goto yystate63
+		goto yystate56
 	case c == '"':
-		goto yystate65
+		goto yystate58
 	}
 
-yystate63:
+yystate56:
 	c = l.next()
 	switch {
 	default:
 		goto yyabort
 	case c >= '\x01' && c <= '\t' || c >= '\v' && c <= '\x1f' || c >= '!' && c <= 'ÿ':
-		goto yystate64
+		goto yystate57
 	}
 
-yystate64:
+yystate57:
 	c = l.next()
 	switch {
 	default:
-		goto yyrule27
+		goto yyrule24
 	case c >= '\x01' && c <= '\t' || c >= '\v' && c <= '\x1f' || c >= '!' && c <= 'ÿ':
-		goto yystate64
+		goto yystate57
 	}
 
-yystate65:
+yystate58:
 	c = l.next()
 	switch {
 	default:
 		goto yyabort
 	case c == '"':
-		goto yystate66
+		goto yystate59
 	case c == '\\':
-		goto yystate67
+		goto yystate60
 	case c >= '\x01' && c <= '\t' || c >= '\v' && c <= '!' || c >= '#' && c <= '[' || c >= ']' && c <= 'ÿ':
-		goto yystate65
+		goto yystate58
 	}
 
-yystate66:
+yystate59:
 	c = l.next()
-	goto yyrule25
+	goto yyrule22
 
-yystate67:
+yystate60:
 	c = l.next()
 	switch {
 	default:
 		goto yyabort
 	case c >= '\x01' && c <= '\t' || c >= '\v' && c <= 'ÿ':
-		goto yystate65
+		goto yystate58
 	}
 
-yystate68:
+yystate61:
 	c = l.next()
-yystart68:
+yystart61:
 	switch {
 	default:
 		goto yyabort
 	case c == ' ':
-		goto yystate70
+		goto yystate63
 	case c == '\n':
-		goto yystate69
+		goto yystate62
 	}
 
-yystate69:
+yystate62:
 	c = l.next()
-	goto yyrule29
+	goto yyrule26
 
-yystate70:
+yystate63:
 	c = l.next()
 	switch {
 	default:
 		goto yyabort
 	case c >= '\x01' && c <= '\t' || c >= '\v' && c <= '\x1f' || c >= '!' && c <= 'ÿ':
-		goto yystate71
+		goto yystate64
 	}
 
-yystate71:
+yystate64:
 	c = l.next()
 	switch {
 	default:
-		goto yyrule28
+		goto yyrule25
 	case c >= '\x01' && c <= '\t' || c >= '\v' && c <= '\x1f' || c >= '!' && c <= 'ÿ':
-		goto yystate71
+		goto yystate64
 	}
 
 yyrule1: // #{S}
@@ -688,133 +626,115 @@ yyrule5: // "EOF"\n?
 		return tEOFWord
 		goto yystate0
 	}
-yyrule6: // \"(\\.|[^\\"])*\"
+yyrule6: // {M}({M}|{D})*
 	{
 		l.state = sMeta2
 		return tMName
 		goto yystate0
 	}
-yyrule7: // {M}({M}|{D})*
-	{
-		l.state = sMeta2
-		return tMName
-		goto yystate0
-	}
-yyrule8: // {S}{C}*\n
+yyrule7: // {S}{C}*\n
 	{
 		l.state = sInit
 		return tText
 		goto yystate0
 	}
-yyrule9: // {M}({M}|{D})*
+yyrule8: // {M}({M}|{D})*
 	{
 		l.state = sValue
 		return tMName
 		goto yystate0
 	}
-yyrule10: // \{
-	{
-		l.state = sLabels
-		return tBraceOpen
-		goto yystate0
-	}
-yyrule11: // \{
+yyrule9: // \{
 	{
 		l.state = sLabels
 		return tBraceOpen
 		goto yystate0
 	}
-yyrule12: // {L}({L}|{D})*
+yyrule10: // {L}({L}|{D})*
 	{
 		return tLName
 	}
-yyrule13: // \"(\\.|[^\\"])*\"
-	{
-		l.state = sLabels
-		return tQString
-		goto yystate0
-	}
-yyrule14: // \}
+yyrule11: // \}
 	{
 		l.state = sValue
 		return tBraceClose
 		goto yystate0
 	}
-yyrule15: // =
+yyrule12: // =
 	{
 		l.state = sLValue
 		return tEqual
 		goto yystate0
 	}
-yyrule16: // ,
+yyrule13: // ,
 	{
 		return tComma
 	}
-yyrule17: // \"(\\.|[^\\"\n])*\"
+yyrule14: // \"(\\.|[^\\"\n])*\"
 	{
 		l.state = sLabels
 		return tLValue
 		goto yystate0
 	}
-yyrule18: // {S}[^ \n]+
+yyrule15: // {S}[^ \n]+
 	{
 		l.state = sTimestamp
 		return tValue
 		goto yystate0
 	}
-yyrule19: // {S}[^ \n]+
+yyrule16: // {S}[^ \n]+
 	{
 		return tTimestamp
 	}
-yyrule20: // \n
+yyrule17: // \n
 	{
 		l.state = sInit
 		return tLinebreak
 		goto yystate0
 	}
-yyrule21: // {S}#{S}\{
+yyrule18: // {S}#{S}\{
 	{
 		l.state = sExemplar
 		return tComment
 		goto yystate0
 	}
-yyrule22: // {L}({L}|{D})*
+yyrule19: // {L}({L}|{D})*
 	{
 		return tLName
 	}
-yyrule23: // \}
+yyrule20: // \}
 	{
 		l.state = sEValue
 		return tBraceClose
 		goto yystate0
 	}
-yyrule24: // =
+yyrule21: // =
 	{
 		l.state = sEValue
 		return tEqual
 		goto yystate0
 	}
-yyrule25: // \"(\\.|[^\\"\n])*\"
+yyrule22: // \"(\\.|[^\\"\n])*\"
 	{
 		l.state = sExemplar
 		return tLValue
 		goto yystate0
 	}
-yyrule26: // ,
+yyrule23: // ,
 	{
 		return tComma
 	}
-yyrule27: // {S}[^ \n]+
+yyrule24: // {S}[^ \n]+
 	{
 		l.state = sETimestamp
 		return tValue
 		goto yystate0
 	}
-yyrule28: // {S}[^ \n]+
+yyrule25: // {S}[^ \n]+
 	{
 		return tTimestamp
 	}
-yyrule29: // \n
+yyrule26: // \n
 	if true { // avoid go vet determining the below panic will not be reached
 		l.state = sInit
 		return tLinebreak
@@ -823,7 +743,9 @@ yyrule29: // \n
 	panic("unreachable")
 
 yyabort: // no lexem recognized
+	//
 	// silence unused label errors for build and satisfy go vet reachability analysis
+	//
 	{
 		if false {
 			goto yyabort
@@ -835,34 +757,34 @@ yyabort: // no lexem recognized
 			goto yystate1
 		}
 		if false {
-			goto yystate6
+			goto yystate5
 		}
 		if false {
-			goto yystate26
+			goto yystate25
 		}
 		if false {
-			goto yystate31
+			goto yystate27
 		}
 		if false {
-			goto yystate34
+			goto yystate30
 		}
 		if false {
-			goto yystate42
+			goto yystate35
 		}
 		if false {
-			goto yystate46
+			goto yystate39
 		}
 		if false {
-			goto yystate50
+			goto yystate43
 		}
 		if false {
-			goto yystate57
+			goto yystate50
 		}
 		if false {
-			goto yystate62
+			goto yystate55
 		}
 		if false {
-			goto yystate68
+			goto yystate61
 		}
 	}
 
diff --git a/model/textparse/openmetricsparse.go b/model/textparse/openmetricsparse.go
index 2a7eae080..4c15ff5fc 100644
--- a/model/textparse/openmetricsparse.go
+++ b/model/textparse/openmetricsparse.go
@@ -81,12 +81,6 @@ type OpenMetricsParser struct {
 	ts      int64
 	hasTS   bool
 	start   int
-	// offsets is a list of offsets into series that describe the positions
-	// of the metric name and label names and values for this series.
-	// p.offsets[0] is the start character of the metric name.
-	// p.offsets[1] is the end of the metric name.
-	// Subsequently, p.offsets is a pair of pair of offsets for the positions
-	// of the label name and value start and end characters.
 	offsets []int
 
 	eOffsets      []int
@@ -159,18 +153,20 @@ func (p *OpenMetricsParser) Metric(l *labels.Labels) string {
 	s := string(p.series)
 
 	p.builder.Reset()
-	metricName := unreplace(s[p.offsets[0]-p.start : p.offsets[1]-p.start])
-	p.builder.Add(labels.MetricName, metricName)
+	p.builder.Add(labels.MetricName, s[:p.offsets[0]-p.start])
 
-	for i := 2; i < len(p.offsets); i += 4 {
+	for i := 1; i < len(p.offsets); i += 4 {
 		a := p.offsets[i] - p.start
 		b := p.offsets[i+1] - p.start
-		label := unreplace(s[a:b])
 		c := p.offsets[i+2] - p.start
 		d := p.offsets[i+3] - p.start
-		value := unreplace(s[c:d])
 
-		p.builder.Add(label, value)
+		value := s[c:d]
+		// Replacer causes allocations. Replace only when necessary.
+		if strings.IndexByte(s[c:d], byte('\\')) >= 0 {
+			value = lvalReplacer.Replace(value)
+		}
+		p.builder.Add(s[a:b], value)
 	}
 
 	p.builder.Sort()
@@ -259,13 +255,7 @@ func (p *OpenMetricsParser) Next() (Entry, error) {
 	case tHelp, tType, tUnit:
 		switch t2 := p.nextToken(); t2 {
 		case tMName:
-			mStart := p.l.start
-			mEnd := p.l.i
-			if p.l.b[mStart] == '"' && p.l.b[mEnd-1] == '"' {
-				mStart++
-				mEnd--
-			}
-			p.offsets = append(p.offsets, mStart, mEnd)
+			p.offsets = append(p.offsets, p.l.start, p.l.i)
 		default:
 			return EntryInvalid, p.parseError("expected metric name after "+t.String(), t2)
 		}
@@ -322,33 +312,58 @@ func (p *OpenMetricsParser) Next() (Entry, error) {
 			return EntryUnit, nil
 		}
 
-	case tBraceOpen:
-		// We found a brace, so make room for the eventual metric name. If these
-		// values aren't updated, then the metric name was not set inside the
-		// braces and we can return an error.
-		if len(p.offsets) == 0 {
-			p.offsets = []int{-1, -1}
-		}
-		if p.offsets, err = p.parseLVals(p.offsets, false); err != nil {
-			return EntryInvalid, err
-		}
-
-		p.series = p.l.b[p.start:p.l.i]
-		return p.parseMetricSuffix(p.nextToken())
 	case tMName:
-		p.offsets = append(p.offsets, p.start, p.l.i)
+		p.offsets = append(p.offsets, p.l.i)
 		p.series = p.l.b[p.start:p.l.i]
 
 		t2 := p.nextToken()
 		if t2 == tBraceOpen {
-			p.offsets, err = p.parseLVals(p.offsets, false)
+			p.offsets, err = p.parseLVals(p.offsets)
 			if err != nil {
 				return EntryInvalid, err
 			}
 			p.series = p.l.b[p.start:p.l.i]
 			t2 = p.nextToken()
 		}
-		return p.parseMetricSuffix(t2)
+		p.val, err = p.getFloatValue(t2, "metric")
+		if err != nil {
+			return EntryInvalid, err
+		}
+
+		p.hasTS = false
+		switch t2 := p.nextToken(); t2 {
+		case tEOF:
+			return EntryInvalid, errors.New("data does not end with # EOF")
+		case tLinebreak:
+			break
+		case tComment:
+			if err := p.parseComment(); err != nil {
+				return EntryInvalid, err
+			}
+		case tTimestamp:
+			p.hasTS = true
+			var ts float64
+			// A float is enough to hold what we need for millisecond resolution.
+			if ts, err = parseFloat(yoloString(p.l.buf()[1:])); err != nil {
+				return EntryInvalid, fmt.Errorf("%w while parsing: %q", err, p.l.b[p.start:p.l.i])
+			}
+			if math.IsNaN(ts) || math.IsInf(ts, 0) {
+				return EntryInvalid, fmt.Errorf("invalid timestamp %f", ts)
+			}
+			p.ts = int64(ts * 1000)
+			switch t3 := p.nextToken(); t3 {
+			case tLinebreak:
+			case tComment:
+				if err := p.parseComment(); err != nil {
+					return EntryInvalid, err
+				}
+			default:
+				return EntryInvalid, p.parseError("expected next entry after timestamp", t3)
+			}
+		default:
+			return EntryInvalid, p.parseError("expected timestamp or # symbol", t2)
+		}
+		return EntrySeries, nil
 
 	default:
 		err = p.parseError("expected a valid start token", t)
@@ -359,7 +374,7 @@ func (p *OpenMetricsParser) Next() (Entry, error) {
 func (p *OpenMetricsParser) parseComment() error {
 	var err error
 	// Parse the labels.
-	p.eOffsets, err = p.parseLVals(p.eOffsets, true)
+	p.eOffsets, err = p.parseLVals(p.eOffsets)
 	if err != nil {
 		return err
 	}
@@ -400,47 +415,38 @@ func (p *OpenMetricsParser) parseComment() error {
 	return nil
 }
 
-func (p *OpenMetricsParser) parseLVals(offsets []int, isExemplar bool) ([]int, error) {
-	t := p.nextToken()
+func (p *OpenMetricsParser) parseLVals(offsets []int) ([]int, error) {
+	first := true
 	for {
-		curTStart := p.l.start
-		curTI := p.l.i
+		t := p.nextToken()
 		switch t {
 		case tBraceClose:
 			return offsets, nil
-		case tLName:
-		case tQString:
-		default:
-			return nil, p.parseError("expected label name", t)
-		}
-
-		t = p.nextToken()
-		// A quoted string followed by a comma or brace is a metric name. Set the
-		// offsets and continue processing. If this is an exemplar, this format
-		// is not allowed.
-		if t == tComma || t == tBraceClose {
-			if isExemplar {
+		case tComma:
+			if first {
+				return nil, p.parseError("expected label name or left brace", t)
+			}
+			t = p.nextToken()
+			if t != tLName {
 				return nil, p.parseError("expected label name", t)
 			}
-			if offsets[0] != -1 || offsets[1] != -1 {
-				return nil, fmt.Errorf("metric name already set while parsing: %q", p.l.b[p.start:p.l.i])
+		case tLName:
+			if !first {
+				return nil, p.parseError("expected comma", t)
 			}
-			offsets[0] = curTStart + 1
-			offsets[1] = curTI - 1
-			if t == tBraceClose {
-				return offsets, nil
+		default:
+			if first {
+				return nil, p.parseError("expected label name or left brace", t)
 			}
-			t = p.nextToken()
-			continue
-		}
-		// We have a label name, and it might be quoted.
-		if p.l.b[curTStart] == '"' {
-			curTStart++
-			curTI--
+			return nil, p.parseError("expected comma or left brace", t)
+
 		}
-		offsets = append(offsets, curTStart, curTI)
+		first = false
+		// t is now a label name.
+
+		offsets = append(offsets, p.l.start, p.l.i)
 
-		if t != tEqual {
+		if t := p.nextToken(); t != tEqual {
 			return nil, p.parseError("expected equal", t)
 		}
 		if t := p.nextToken(); t != tLValue {
@@ -453,62 +459,7 @@ func (p *OpenMetricsParser) parseLVals(offsets []int, isExemplar bool) ([]int, e
 		// The openMetricsLexer ensures the value string is quoted. Strip first
 		// and last character.
 		offsets = append(offsets, p.l.start+1, p.l.i-1)
-
-		// Free trailing commas are allowed.
-		t = p.nextToken()
-		if t == tComma {
-			t = p.nextToken()
-		} else if t != tBraceClose {
-			return nil, p.parseError("expected comma or brace close", t)
-		}
-	}
-}
-
-// parseMetricSuffix parses the end of the line after the metric name and
-// labels. It starts parsing with the provided token.
-func (p *OpenMetricsParser) parseMetricSuffix(t token) (Entry, error) {
-	if p.offsets[0] == -1 {
-		return EntryInvalid, fmt.Errorf("metric name not set while parsing: %q", p.l.b[p.start:p.l.i])
-	}
-
-	var err error
-	p.val, err = p.getFloatValue(t, "metric")
-	if err != nil {
-		return EntryInvalid, err
-	}
-
-	p.hasTS = false
-	switch t2 := p.nextToken(); t2 {
-	case tEOF:
-		return EntryInvalid, errors.New("data does not end with # EOF")
-	case tLinebreak:
-		break
-	case tComment:
-		if err := p.parseComment(); err != nil {
-			return EntryInvalid, err
-		}
-	case tTimestamp:
-		p.hasTS = true
-		var ts float64
-		// A float is enough to hold what we need for millisecond resolution.
-		if ts, err = parseFloat(yoloString(p.l.buf()[1:])); err != nil {
-			return EntryInvalid, fmt.Errorf("%w while parsing: %q", err, p.l.b[p.start:p.l.i])
-		}
-		if math.IsNaN(ts) || math.IsInf(ts, 0) {
-			return EntryInvalid, fmt.Errorf("invalid timestamp %f", ts)
-		}
-		p.ts = int64(ts * 1000)
-		switch t3 := p.nextToken(); t3 {
-		case tLinebreak:
-		case tComment:
-			if err := p.parseComment(); err != nil {
-				return EntryInvalid, err
-			}
-		default:
-			return EntryInvalid, p.parseError("expected next entry after timestamp", t3)
-		}
 	}
-	return EntrySeries, nil
 }
 
 func (p *OpenMetricsParser) getFloatValue(t token, after string) (float64, error) {
diff --git a/model/textparse/promlex.l b/model/textparse/promlex.l
index e9fa1fb71..c1bc8e776 100644
--- a/model/textparse/promlex.l
+++ b/model/textparse/promlex.l
@@ -66,15 +66,12 @@ C     [^\n]
 #                                     return l.consumeComment()
 <sComment>HELP[\t ]+                  l.state = sMeta1; return tHelp
 <sComment>TYPE[\t ]+                  l.state = sMeta1; return tType
-<sMeta1>\"(\\.|[^\\"])*\"             l.state = sMeta2; return tMName
 <sMeta1>{M}({M}|{D})*                 l.state = sMeta2; return tMName
 <sMeta2>{C}*                          l.state = sInit; return tText
 
 {M}({M}|{D})*                         l.state = sValue; return tMName
 <sValue>\{                            l.state = sLabels; return tBraceOpen
-\{                                    l.state = sLabels; return tBraceOpen
 <sLabels>{L}({L}|{D})*                return tLName
-<sLabels>\"(\\.|[^\\"])*\"            l.state = sLabels; return tQString
 <sLabels>\}                           l.state = sValue; return tBraceClose
 <sLabels>=                            l.state = sLValue; return tEqual
 <sLabels>,                            return tComma
diff --git a/model/textparse/promlex.l.go b/model/textparse/promlex.l.go
index a083e5549..4076aae61 100644
--- a/model/textparse/promlex.l.go
+++ b/model/textparse/promlex.l.go
@@ -51,19 +51,19 @@ yystate0:
 	case 0: // start condition: INITIAL
 		goto yystart1
 	case 1: // start condition: sComment
-		goto yystart9
+		goto yystart8
 	case 2: // start condition: sMeta1
-		goto yystart20
+		goto yystart19
 	case 3: // start condition: sMeta2
-		goto yystart25
+		goto yystart21
 	case 4: // start condition: sLabels
-		goto yystart28
+		goto yystart24
 	case 5: // start condition: sLValue
-		goto yystart36
+		goto yystart29
 	case 6: // start condition: sValue
-		goto yystart40
+		goto yystart33
 	case 7: // start condition: sTimestamp
-		goto yystart43
+		goto yystart36
 	}
 
 yystate1:
@@ -82,8 +82,6 @@ yystart1:
 		goto yystate3
 	case c == '\x00':
 		goto yystate2
-	case c == '{':
-		goto yystate8
 	}
 
 yystate2:
@@ -125,357 +123,297 @@ yystate7:
 	c = l.next()
 	switch {
 	default:
-		goto yyrule11
+		goto yyrule10
 	case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z':
 		goto yystate7
 	}
 
 yystate8:
 	c = l.next()
-	goto yyrule13
-
-yystate9:
-	c = l.next()
-yystart9:
+yystart8:
 	switch {
 	default:
 		goto yyabort
 	case c == 'H':
-		goto yystate10
+		goto yystate9
 	case c == 'T':
-		goto yystate15
+		goto yystate14
 	case c == '\t' || c == ' ':
 		goto yystate3
 	}
 
-yystate10:
+yystate9:
 	c = l.next()
 	switch {
 	default:
 		goto yyabort
 	case c == 'E':
-		goto yystate11
+		goto yystate10
 	}
 
-yystate11:
+yystate10:
 	c = l.next()
 	switch {
 	default:
 		goto yyabort
 	case c == 'L':
-		goto yystate12
+		goto yystate11
 	}
 
-yystate12:
+yystate11:
 	c = l.next()
 	switch {
 	default:
 		goto yyabort
 	case c == 'P':
-		goto yystate13
+		goto yystate12
 	}
 
-yystate13:
+yystate12:
 	c = l.next()
 	switch {
 	default:
 		goto yyabort
 	case c == '\t' || c == ' ':
-		goto yystate14
+		goto yystate13
 	}
 
-yystate14:
+yystate13:
 	c = l.next()
 	switch {
 	default:
 		goto yyrule6
 	case c == '\t' || c == ' ':
-		goto yystate14
+		goto yystate13
 	}
 
-yystate15:
+yystate14:
 	c = l.next()
 	switch {
 	default:
 		goto yyabort
 	case c == 'Y':
-		goto yystate16
+		goto yystate15
 	}
 
-yystate16:
+yystate15:
 	c = l.next()
 	switch {
 	default:
 		goto yyabort
 	case c == 'P':
-		goto yystate17
+		goto yystate16
 	}
 
-yystate17:
+yystate16:
 	c = l.next()
 	switch {
 	default:
 		goto yyabort
 	case c == 'E':
-		goto yystate18
+		goto yystate17
 	}
 
-yystate18:
+yystate17:
 	c = l.next()
 	switch {
 	default:
 		goto yyabort
 	case c == '\t' || c == ' ':
-		goto yystate19
+		goto yystate18
 	}
 
-yystate19:
+yystate18:
 	c = l.next()
 	switch {
 	default:
 		goto yyrule7
 	case c == '\t' || c == ' ':
-		goto yystate19
+		goto yystate18
 	}
 
-yystate20:
+yystate19:
 	c = l.next()
-yystart20:
+yystart19:
 	switch {
 	default:
 		goto yyabort
-	case c == '"':
-		goto yystate21
 	case c == ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z':
-		goto yystate24
+		goto yystate20
 	case c == '\t' || c == ' ':
 		goto yystate3
 	}
 
-yystate21:
-	c = l.next()
-	switch {
-	default:
-		goto yyabort
-	case c == '"':
-		goto yystate22
-	case c == '\\':
-		goto yystate23
-	case c >= '\x01' && c <= '!' || c >= '#' && c <= '[' || c >= ']' && c <= 'ÿ':
-		goto yystate21
-	}
-
-yystate22:
-	c = l.next()
-	goto yyrule8
-
-yystate23:
-	c = l.next()
-	switch {
-	default:
-		goto yyabort
-	case c >= '\x01' && c <= '\t' || c >= '\v' && c <= 'ÿ':
-		goto yystate21
-	}
-
-yystate24:
+yystate20:
 	c = l.next()
 	switch {
 	default:
-		goto yyrule9
+		goto yyrule8
 	case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z':
-		goto yystate24
+		goto yystate20
 	}
 
-yystate25:
+yystate21:
 	c = l.next()
-yystart25:
+yystart21:
 	switch {
 	default:
-		goto yyrule10
+		goto yyrule9
 	case c == '\t' || c == ' ':
-		goto yystate27
+		goto yystate23
 	case c >= '\x01' && c <= '\b' || c >= '\v' && c <= '\x1f' || c >= '!' && c <= 'ÿ':
-		goto yystate26
+		goto yystate22
 	}
 
-yystate26:
+yystate22:
 	c = l.next()
 	switch {
 	default:
-		goto yyrule10
+		goto yyrule9
 	case c >= '\x01' && c <= '\t' || c >= '\v' && c <= 'ÿ':
-		goto yystate26
+		goto yystate22
 	}
 
-yystate27:
+yystate23:
 	c = l.next()
 	switch {
 	default:
 		goto yyrule3
 	case c == '\t' || c == ' ':
-		goto yystate27
+		goto yystate23
 	case c >= '\x01' && c <= '\b' || c >= '\v' && c <= '\x1f' || c >= '!' && c <= 'ÿ':
-		goto yystate26
+		goto yystate22
 	}
 
-yystate28:
+yystate24:
 	c = l.next()
-yystart28:
+yystart24:
 	switch {
 	default:
 		goto yyabort
-	case c == '"':
-		goto yystate29
 	case c == ',':
-		goto yystate32
+		goto yystate25
 	case c == '=':
-		goto yystate33
+		goto yystate26
 	case c == '\t' || c == ' ':
 		goto yystate3
 	case c == '}':
-		goto yystate35
+		goto yystate28
 	case c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z':
-		goto yystate34
-	}
-
-yystate29:
-	c = l.next()
-	switch {
-	default:
-		goto yyabort
-	case c == '"':
-		goto yystate30
-	case c == '\\':
-		goto yystate31
-	case c >= '\x01' && c <= '!' || c >= '#' && c <= '[' || c >= ']' && c <= 'ÿ':
-		goto yystate29
+		goto yystate27
 	}
 
-yystate30:
+yystate25:
 	c = l.next()
 	goto yyrule15
 
-yystate31:
-	c = l.next()
-	switch {
-	default:
-		goto yyabort
-	case c >= '\x01' && c <= '\t' || c >= '\v' && c <= 'ÿ':
-		goto yystate29
-	}
-
-yystate32:
-	c = l.next()
-	goto yyrule18
-
-yystate33:
+yystate26:
 	c = l.next()
-	goto yyrule17
+	goto yyrule14
 
-yystate34:
+yystate27:
 	c = l.next()
 	switch {
 	default:
-		goto yyrule14
+		goto yyrule12
 	case c >= '0' && c <= '9' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z':
-		goto yystate34
+		goto yystate27
 	}
 
-yystate35:
+yystate28:
 	c = l.next()
-	goto yyrule16
+	goto yyrule13
 
-yystate36:
+yystate29:
 	c = l.next()
-yystart36:
+yystart29:
 	switch {
 	default:
 		goto yyabort
 	case c == '"':
-		goto yystate37
+		goto yystate30
 	case c == '\t' || c == ' ':
 		goto yystate3
 	}
 
-yystate37:
+yystate30:
 	c = l.next()
 	switch {
 	default:
 		goto yyabort
 	case c == '"':
-		goto yystate38
+		goto yystate31
 	case c == '\\':
-		goto yystate39
+		goto yystate32
 	case c >= '\x01' && c <= '!' || c >= '#' && c <= '[' || c >= ']' && c <= 'ÿ':
-		goto yystate37
+		goto yystate30
 	}
 
-yystate38:
+yystate31:
 	c = l.next()
-	goto yyrule19
+	goto yyrule16
 
-yystate39:
+yystate32:
 	c = l.next()
 	switch {
 	default:
 		goto yyabort
 	case c >= '\x01' && c <= '\t' || c >= '\v' && c <= 'ÿ':
-		goto yystate37
+		goto yystate30
 	}
 
-yystate40:
+yystate33:
 	c = l.next()
-yystart40:
+yystart33:
 	switch {
 	default:
 		goto yyabort
 	case c == '\t' || c == ' ':
 		goto yystate3
 	case c == '{':
-		goto yystate42
+		goto yystate35
 	case c >= '\x01' && c <= '\b' || c >= '\v' && c <= '\x1f' || c >= '!' && c <= 'z' || c >= '|' && c <= 'ÿ':
-		goto yystate41
+		goto yystate34
 	}
 
-yystate41:
+yystate34:
 	c = l.next()
 	switch {
 	default:
-		goto yyrule20
+		goto yyrule17
 	case c >= '\x01' && c <= '\b' || c >= '\v' && c <= '\x1f' || c >= '!' && c <= 'z' || c >= '|' && c <= 'ÿ':
-		goto yystate41
+		goto yystate34
 	}
 
-yystate42:
+yystate35:
 	c = l.next()
-	goto yyrule12
+	goto yyrule11
 
-yystate43:
+yystate36:
 	c = l.next()
-yystart43:
+yystart36:
 	switch {
 	default:
 		goto yyabort
 	case c == '\n':
-		goto yystate44
+		goto yystate37
 	case c == '\t' || c == ' ':
 		goto yystate3
 	case c >= '0' && c <= '9':
-		goto yystate45
+		goto yystate38
 	}
 
-yystate44:
+yystate37:
 	c = l.next()
-	goto yyrule22
+	goto yyrule19
 
-yystate45:
+yystate38:
 	c = l.next()
 	switch {
 	default:
-		goto yyrule21
+		goto yyrule18
 	case c >= '0' && c <= '9':
-		goto yystate45
+		goto yystate38
 	}
 
 yyrule1: // \0
@@ -513,85 +451,67 @@ yyrule7: // TYPE[\t ]+
 		return tType
 		goto yystate0
 	}
-yyrule8: // \"(\\.|[^\\"])*\"
-	{
-		l.state = sMeta2
-		return tMName
-		goto yystate0
-	}
-yyrule9: // {M}({M}|{D})*
+yyrule8: // {M}({M}|{D})*
 	{
 		l.state = sMeta2
 		return tMName
 		goto yystate0
 	}
-yyrule10: // {C}*
+yyrule9: // {C}*
 	{
 		l.state = sInit
 		return tText
 		goto yystate0
 	}
-yyrule11: // {M}({M}|{D})*
+yyrule10: // {M}({M}|{D})*
 	{
 		l.state = sValue
 		return tMName
 		goto yystate0
 	}
-yyrule12: // \{
+yyrule11: // \{
 	{
 		l.state = sLabels
 		return tBraceOpen
 		goto yystate0
 	}
-yyrule13: // \{
-	{
-		l.state = sLabels
-		return tBraceOpen
-		goto yystate0
-	}
-yyrule14: // {L}({L}|{D})*
+yyrule12: // {L}({L}|{D})*
 	{
 		return tLName
 	}
-yyrule15: // \"(\\.|[^\\"])*\"
-	{
-		l.state = sLabels
-		return tQString
-		goto yystate0
-	}
-yyrule16: // \}
+yyrule13: // \}
 	{
 		l.state = sValue
 		return tBraceClose
 		goto yystate0
 	}
-yyrule17: // =
+yyrule14: // =
 	{
 		l.state = sLValue
 		return tEqual
 		goto yystate0
 	}
-yyrule18: // ,
+yyrule15: // ,
 	{
 		return tComma
 	}
-yyrule19: // \"(\\.|[^\\"])*\"
+yyrule16: // \"(\\.|[^\\"])*\"
 	{
 		l.state = sLabels
 		return tLValue
 		goto yystate0
 	}
-yyrule20: // [^{ \t\n]+
+yyrule17: // [^{ \t\n]+
 	{
 		l.state = sTimestamp
 		return tValue
 		goto yystate0
 	}
-yyrule21: // {D}+
+yyrule18: // {D}+
 	{
 		return tTimestamp
 	}
-yyrule22: // \n
+yyrule19: // \n
 	if true { // avoid go vet determining the below panic will not be reached
 		l.state = sInit
 		return tLinebreak
@@ -600,7 +520,9 @@ yyrule22: // \n
 	panic("unreachable")
 
 yyabort: // no lexem recognized
+	//
 	// silence unused label errors for build and satisfy go vet reachability analysis
+	//
 	{
 		if false {
 			goto yyabort
@@ -612,25 +534,25 @@ yyabort: // no lexem recognized
 			goto yystate1
 		}
 		if false {
-			goto yystate9
+			goto yystate8
 		}
 		if false {
-			goto yystate20
+			goto yystate19
 		}
 		if false {
-			goto yystate25
+			goto yystate21
 		}
 		if false {
-			goto yystate28
+			goto yystate24
 		}
 		if false {
-			goto yystate36
+			goto yystate29
 		}
 		if false {
-			goto yystate40
+			goto yystate33
 		}
 		if false {
-			goto yystate43
+			goto yystate36
 		}
 	}
 
diff --git a/model/textparse/promparse.go b/model/textparse/promparse.go
index 1de783b0d..7123e52c3 100644
--- a/model/textparse/promparse.go
+++ b/model/textparse/promparse.go
@@ -57,7 +57,6 @@ const (
 	tComment
 	tBlank
 	tMName
-	tQString
 	tBraceOpen
 	tBraceClose
 	tLName
@@ -94,8 +93,6 @@ func (t token) String() string {
 		return "BLANK"
 	case tMName:
 		return "MNAME"
-	case tQString:
-		return "QSTRING"
 	case tBraceOpen:
 		return "BOPEN"
 	case tBraceClose:
@@ -156,12 +153,6 @@ type PromParser struct {
 	ts      int64
 	hasTS   bool
 	start   int
-	// offsets is a list of offsets into series that describe the positions
-	// of the metric name and label names and values for this series.
-	// p.offsets[0] is the start character of the metric name.
-	// p.offsets[1] is the end of the metric name.
-	// Subsequently, p.offsets is a pair of pair of offsets for the positions
-	// of the label name and value start and end characters.
 	offsets []int
 }
 
@@ -227,17 +218,20 @@ func (p *PromParser) Metric(l *labels.Labels) string {
 	s := string(p.series)
 
 	p.builder.Reset()
-	metricName := unreplace(s[p.offsets[0]-p.start : p.offsets[1]-p.start])
-	p.builder.Add(labels.MetricName, metricName)
+	p.builder.Add(labels.MetricName, s[:p.offsets[0]-p.start])
 
-	for i := 2; i < len(p.offsets); i += 4 {
+	for i := 1; i < len(p.offsets); i += 4 {
 		a := p.offsets[i] - p.start
 		b := p.offsets[i+1] - p.start
-		label := unreplace(s[a:b])
 		c := p.offsets[i+2] - p.start
 		d := p.offsets[i+3] - p.start
-		value := unreplace(s[c:d])
-		p.builder.Add(label, value)
+
+		value := s[c:d]
+		// Replacer causes allocations. Replace only when necessary.
+		if strings.IndexByte(s[c:d], byte('\\')) >= 0 {
+			value = lvalReplacer.Replace(value)
+		}
+		p.builder.Add(s[a:b], value)
 	}
 
 	p.builder.Sort()
@@ -295,13 +289,7 @@ func (p *PromParser) Next() (Entry, error) {
 	case tHelp, tType:
 		switch t2 := p.nextToken(); t2 {
 		case tMName:
-			mStart := p.l.start
-			mEnd := p.l.i
-			if p.l.b[mStart] == '"' && p.l.b[mEnd-1] == '"' {
-				mStart++
-				mEnd--
-			}
-			p.offsets = append(p.offsets, mStart, mEnd)
+			p.offsets = append(p.offsets, p.l.start, p.l.i)
 		default:
 			return EntryInvalid, p.parseError("expected metric name after "+t.String(), t2)
 		}
@@ -313,7 +301,7 @@ func (p *PromParser) Next() (Entry, error) {
 				p.text = []byte{}
 			}
 		default:
-			return EntryInvalid, fmt.Errorf("expected text in %s, got %v", t.String(), t2.String())
+			return EntryInvalid, fmt.Errorf("expected text in %s", t.String())
 		}
 		switch t {
 		case tType:
@@ -351,24 +339,12 @@ func (p *PromParser) Next() (Entry, error) {
 			return EntryInvalid, p.parseError("linebreak expected after comment", t)
 		}
 		return EntryComment, nil
-	case tBraceOpen:
-		// We found a brace, so make room for the eventual metric name. If these
-		// values aren't updated, then the metric name was not set inside the
-		// braces and we can return an error.
-		if len(p.offsets) == 0 {
-			p.offsets = []int{-1, -1}
-		}
-		if err := p.parseLVals(); err != nil {
-			return EntryInvalid, err
-		}
 
-		p.series = p.l.b[p.start:p.l.i]
-		return p.parseMetricSuffix(p.nextToken())
 	case tMName:
-		p.offsets = append(p.offsets, p.start, p.l.i)
+		p.offsets = append(p.offsets, p.l.i)
 		p.series = p.l.b[p.start:p.l.i]
+
 		t2 := p.nextToken()
-		// If there's a brace, consume and parse the label values.
 		if t2 == tBraceOpen {
 			if err := p.parseLVals(); err != nil {
 				return EntryInvalid, err
@@ -376,7 +352,32 @@ func (p *PromParser) Next() (Entry, error) {
 			p.series = p.l.b[p.start:p.l.i]
 			t2 = p.nextToken()
 		}
-		return p.parseMetricSuffix(t2)
+		if t2 != tValue {
+			return EntryInvalid, p.parseError("expected value after metric", t2)
+		}
+		if p.val, err = parseFloat(yoloString(p.l.buf())); err != nil {
+			return EntryInvalid, fmt.Errorf("%w while parsing: %q", err, p.l.b[p.start:p.l.i])
+		}
+		// Ensure canonical NaN value.
+		if math.IsNaN(p.val) {
+			p.val = math.Float64frombits(value.NormalNaN)
+		}
+		p.hasTS = false
+		switch t := p.nextToken(); t {
+		case tLinebreak:
+			break
+		case tTimestamp:
+			p.hasTS = true
+			if p.ts, err = strconv.ParseInt(yoloString(p.l.buf()), 10, 64); err != nil {
+				return EntryInvalid, fmt.Errorf("%w while parsing: %q", err, p.l.b[p.start:p.l.i])
+			}
+			if t2 := p.nextToken(); t2 != tLinebreak {
+				return EntryInvalid, p.parseError("expected next entry after timestamp", t2)
+			}
+		default:
+			return EntryInvalid, p.parseError("expected timestamp or new record", t)
+		}
+		return EntrySeries, nil
 
 	default:
 		err = p.parseError("expected a valid start token", t)
@@ -384,43 +385,19 @@ func (p *PromParser) Next() (Entry, error) {
 	return EntryInvalid, err
 }
 
-// parseLVals parses the contents inside the braces.
 func (p *PromParser) parseLVals() error {
 	t := p.nextToken()
 	for {
-		curTStart := p.l.start
-		curTI := p.l.i
 		switch t {
 		case tBraceClose:
 			return nil
 		case tLName:
-		case tQString:
 		default:
 			return p.parseError("expected label name", t)
 		}
+		p.offsets = append(p.offsets, p.l.start, p.l.i)
 
-		t = p.nextToken()
-		// A quoted string followed by a comma or brace is a metric name. Set the
-		// offsets and continue processing.
-		if t == tComma || t == tBraceClose {
-			if p.offsets[0] != -1 || p.offsets[1] != -1 {
-				return fmt.Errorf("metric name already set while parsing: %q", p.l.b[p.start:p.l.i])
-			}
-			p.offsets[0] = curTStart + 1
-			p.offsets[1] = curTI - 1
-			if t == tBraceClose {
-				return nil
-			}
-			t = p.nextToken()
-			continue
-		}
-		// We have a label name, and it might be quoted.
-		if p.l.b[curTStart] == '"' {
-			curTStart++
-			curTI--
-		}
-		p.offsets = append(p.offsets, curTStart, curTI)
-		if t != tEqual {
+		if t := p.nextToken(); t != tEqual {
 			return p.parseError("expected equal", t)
 		}
 		if t := p.nextToken(); t != tLValue {
@@ -434,51 +411,13 @@ func (p *PromParser) parseLVals() error {
 		// and last character.
 		p.offsets = append(p.offsets, p.l.start+1, p.l.i-1)
 
-		// Free trailing commas are allowed. NOTE: this allows spaces between label
-		// names, unlike in OpenMetrics. It is not clear if this is intended or an
-		// accidental bug.
+		// Free trailing commas are allowed.
 		if t = p.nextToken(); t == tComma {
 			t = p.nextToken()
 		}
 	}
 }
 
-// parseMetricSuffix parses the end of the line after the metric name and
-// labels. It starts parsing with the provided token.
-func (p *PromParser) parseMetricSuffix(t token) (Entry, error) {
-	if p.offsets[0] == -1 {
-		return EntryInvalid, fmt.Errorf("metric name not set while parsing: %q", p.l.b[p.start:p.l.i])
-	}
-	if t != tValue {
-		return EntryInvalid, p.parseError("expected value after metric", t)
-	}
-	var err error
-	if p.val, err = parseFloat(yoloString(p.l.buf())); err != nil {
-		return EntryInvalid, fmt.Errorf("%w while parsing: %q", err, p.l.b[p.start:p.l.i])
-	}
-	// Ensure canonical NaN value.
-	if math.IsNaN(p.val) {
-		p.val = math.Float64frombits(value.NormalNaN)
-	}
-	p.hasTS = false
-	switch t := p.nextToken(); t {
-	case tLinebreak:
-		break
-	case tTimestamp:
-		p.hasTS = true
-		if p.ts, err = strconv.ParseInt(yoloString(p.l.buf()), 10, 64); err != nil {
-			return EntryInvalid, fmt.Errorf("%w while parsing: %q", err, p.l.b[p.start:p.l.i])
-		}
-		if t2 := p.nextToken(); t2 != tLinebreak {
-			return EntryInvalid, p.parseError("expected next entry after timestamp", t2)
-		}
-	default:
-		return EntryInvalid, p.parseError("expected timestamp or new record", t)
-	}
-
-	return EntrySeries, nil
-}
-
 var lvalReplacer = strings.NewReplacer(
 	`\"`, "\"",
 	`\\`, "\\",
@@ -490,14 +429,6 @@ var helpReplacer = strings.NewReplacer(
 	`\n`, "\n",
 )
 
-func unreplace(s string) string {
-	// Replacer causes allocations. Replace only when necessary.
-	if strings.IndexByte(s, byte('\\')) >= 0 {
-		return lvalReplacer.Replace(s)
-	}
-	return s
-}
-
 func yoloString(b []byte) string {
 	return *((*string)(unsafe.Pointer(&b)))
 }
diff --git a/promql/parser/generated_parser.y b/promql/parser/generated_parser.y
index 841bd31c1..dce79f769 100644
--- a/promql/parser/generated_parser.y
+++ b/promql/parser/generated_parser.y
@@ -161,7 +161,7 @@ START_METRIC_SELECTOR
 // Type definitions for grammar rules.
 %type <matchers> label_match_list
 %type <matcher> label_matcher
-%type <item> aggregate_op grouping_label match_op maybe_label metric_identifier unary_op at_modifier_preprocessors string_identifier
+%type <item> aggregate_op grouping_label match_op maybe_label metric_identifier unary_op at_modifier_preprocessors
 %type <labels> label_set metric
 %type <lblList> label_set_list
 %type <label> label_set_item
@@ -582,13 +582,7 @@ label_match_list: label_match_list COMMA label_matcher
                 ;
 
 label_matcher   : IDENTIFIER match_op STRING
-                        { $$ = yylex.(*parser).newLabelMatcher($1, $2, $3); }
-                | string_identifier match_op STRING
-                        { $$ = yylex.(*parser).newLabelMatcher($1, $2, $3); }
-                | string_identifier
-                        { $$ = yylex.(*parser).newMetricNameMatcher($1); }
-                | string_identifier match_op error
-                        { yylex.(*parser).unexpected("label matching", "string"); $$ = nil}
+                        { $$ = yylex.(*parser).newLabelMatcher($1, $2, $3);  }
                 | IDENTIFIER match_op error
                         { yylex.(*parser).unexpected("label matching", "string"); $$ = nil}
                 | IDENTIFIER error
@@ -907,17 +901,7 @@ string_literal  : STRING
                                 PosRange: $1.PositionRange(),
                         }
                         }
-                ;
-
-string_identifier  : STRING
-                        {
-                        $$ = Item{
-                                Typ: METRIC_IDENTIFIER,
-                                Pos: $1.PositionRange().Start,
-                                Val: yylex.(*parser).unquoteString($1.Val),
-                        }
-                        }
-                ;
+                        ;
 
 /*
  * Wrappers for optional arguments.
diff --git a/promql/parser/generated_parser.y.go b/promql/parser/generated_parser.y.go
index 4fc4196e1..4057d9163 100644
--- a/promql/parser/generated_parser.y.go
+++ b/promql/parser/generated_parser.y.go
@@ -1,8 +1,12 @@
-// Code generated by goyacc -l -o promql/parser/generated_parser.y.go promql/parser/generated_parser.y. DO NOT EDIT.
+// Code generated by goyacc -o promql/parser/generated_parser.y.go promql/parser/generated_parser.y. DO NOT EDIT.
+
+//line promql/parser/generated_parser.y:15
 package parser
 
 import __yyfmt__ "fmt"
 
+//line promql/parser/generated_parser.y:15
+
 import (
 	"math"
 	"strconv"
@@ -14,6 +18,7 @@ import (
 	"github.com/prometheus/prometheus/promql/parser/posrange"
 )
 
+//line promql/parser/generated_parser.y:30
 type yySymType struct {
 	yys         int
 	node        Node
@@ -225,310 +230,312 @@ const yyEofCode = 1
 const yyErrCode = 2
 const yyInitialStackSize = 16
 
-var yyExca = [...]int{
+//line promql/parser/generated_parser.y:919
+
+//line yacctab:1
+var yyExca = [...]int16{
 	-1, 1,
 	1, -1,
 	-2, 0,
 	-1, 35,
-	1, 134,
-	10, 134,
-	24, 134,
+	1, 131,
+	10, 131,
+	24, 131,
 	-2, 0,
 	-1, 58,
+	2, 168,
+	15, 168,
+	75, 168,
+	81, 168,
+	-2, 97,
+	-1, 59,
+	2, 169,
+	15, 169,
+	75, 169,
+	81, 169,
+	-2, 98,
+	-1, 60,
+	2, 170,
+	15, 170,
+	75, 170,
+	81, 170,
+	-2, 100,
+	-1, 61,
 	2, 171,
 	15, 171,
 	75, 171,
 	81, 171,
-	-2, 100,
-	-1, 59,
+	-2, 101,
+	-1, 62,
 	2, 172,
 	15, 172,
 	75, 172,
 	81, 172,
-	-2, 101,
-	-1, 60,
+	-2, 102,
+	-1, 63,
 	2, 173,
 	15, 173,
 	75, 173,
 	81, 173,
-	-2, 103,
-	-1, 61,
+	-2, 107,
+	-1, 64,
 	2, 174,
 	15, 174,
 	75, 174,
 	81, 174,
-	-2, 104,
-	-1, 62,
+	-2, 109,
+	-1, 65,
 	2, 175,
 	15, 175,
 	75, 175,
 	81, 175,
-	-2, 105,
-	-1, 63,
+	-2, 111,
+	-1, 66,
 	2, 176,
 	15, 176,
 	75, 176,
 	81, 176,
-	-2, 110,
-	-1, 64,
+	-2, 112,
+	-1, 67,
 	2, 177,
 	15, 177,
 	75, 177,
 	81, 177,
-	-2, 112,
-	-1, 65,
+	-2, 113,
+	-1, 68,
 	2, 178,
 	15, 178,
 	75, 178,
 	81, 178,
 	-2, 114,
-	-1, 66,
+	-1, 69,
 	2, 179,
 	15, 179,
 	75, 179,
 	81, 179,
 	-2, 115,
-	-1, 67,
-	2, 180,
-	15, 180,
-	75, 180,
-	81, 180,
-	-2, 116,
-	-1, 68,
-	2, 181,
-	15, 181,
-	75, 181,
-	81, 181,
-	-2, 117,
-	-1, 69,
-	2, 182,
-	15, 182,
-	75, 182,
-	81, 182,
-	-2, 118,
-	-1, 195,
-	12, 230,
-	13, 230,
-	18, 230,
-	19, 230,
-	25, 230,
-	39, 230,
-	45, 230,
-	46, 230,
-	49, 230,
-	55, 230,
-	60, 230,
-	61, 230,
-	62, 230,
-	63, 230,
-	64, 230,
-	65, 230,
-	66, 230,
-	67, 230,
-	68, 230,
-	69, 230,
-	70, 230,
-	71, 230,
-	75, 230,
-	79, 230,
-	81, 230,
-	84, 230,
-	85, 230,
+	-1, 192,
+	12, 226,
+	13, 226,
+	18, 226,
+	19, 226,
+	25, 226,
+	39, 226,
+	45, 226,
+	46, 226,
+	49, 226,
+	55, 226,
+	60, 226,
+	61, 226,
+	62, 226,
+	63, 226,
+	64, 226,
+	65, 226,
+	66, 226,
+	67, 226,
+	68, 226,
+	69, 226,
+	70, 226,
+	71, 226,
+	75, 226,
+	79, 226,
+	81, 226,
+	84, 226,
+	85, 226,
 	-2, 0,
-	-1, 196,
-	12, 230,
-	13, 230,
-	18, 230,
-	19, 230,
-	25, 230,
-	39, 230,
-	45, 230,
-	46, 230,
-	49, 230,
-	55, 230,
-	60, 230,
-	61, 230,
-	62, 230,
-	63, 230,
-	64, 230,
-	65, 230,
-	66, 230,
-	67, 230,
-	68, 230,
-	69, 230,
-	70, 230,
-	71, 230,
-	75, 230,
-	79, 230,
-	81, 230,
-	84, 230,
-	85, 230,
+	-1, 193,
+	12, 226,
+	13, 226,
+	18, 226,
+	19, 226,
+	25, 226,
+	39, 226,
+	45, 226,
+	46, 226,
+	49, 226,
+	55, 226,
+	60, 226,
+	61, 226,
+	62, 226,
+	63, 226,
+	64, 226,
+	65, 226,
+	66, 226,
+	67, 226,
+	68, 226,
+	69, 226,
+	70, 226,
+	71, 226,
+	75, 226,
+	79, 226,
+	81, 226,
+	84, 226,
+	85, 226,
 	-2, 0,
-	-1, 217,
-	21, 228,
+	-1, 214,
+	21, 224,
 	-2, 0,
-	-1, 285,
-	21, 229,
+	-1, 280,
+	21, 225,
 	-2, 0,
 }
 
 const yyPrivate = 57344
 
-const yyLast = 742
-
-var yyAct = [...]int{
-	151, 322, 320, 268, 327, 148, 221, 37, 187, 144,
-	281, 280, 152, 113, 77, 173, 104, 102, 101, 6,
-	128, 223, 105, 193, 155, 194, 195, 196, 339, 262,
-	260, 233, 317, 316, 57, 100, 294, 239, 103, 146,
-	300, 313, 263, 156, 156, 283, 147, 338, 259, 123,
-	337, 106, 252, 311, 155, 299, 340, 301, 264, 157,
-	157, 108, 298, 109, 235, 236, 292, 251, 237, 107,
-	155, 292, 174, 191, 175, 96, 250, 99, 258, 224,
-	226, 228, 229, 230, 238, 240, 243, 244, 245, 246,
-	247, 110, 145, 225, 227, 231, 232, 234, 241, 242,
-	98, 257, 321, 248, 249, 2, 3, 4, 5, 218,
-	158, 104, 177, 217, 168, 162, 165, 105, 175, 160,
-	164, 161, 176, 178, 189, 213, 106, 328, 216, 256,
-	183, 179, 192, 163, 181, 100, 190, 197, 198, 199,
-	200, 201, 202, 203, 204, 205, 206, 207, 208, 209,
-	210, 211, 255, 182, 72, 212, 177, 214, 215, 33,
-	82, 84, 85, 7, 86, 87, 176, 178, 90, 91,
-	223, 93, 94, 95, 116, 96, 97, 99, 83, 147,
-	233, 286, 289, 116, 114, 254, 239, 288, 147, 172,
-	220, 124, 253, 114, 171, 310, 309, 117, 120, 261,
-	98, 112, 287, 119, 278, 279, 117, 170, 282, 10,
-	308, 159, 307, 235, 236, 312, 118, 237, 147, 74,
-	306, 305, 304, 303, 302, 250, 81, 285, 224, 226,
-	228, 229, 230, 238, 240, 243, 244, 245, 246, 247,
-	79, 79, 225, 227, 231, 232, 234, 241, 242, 48,
-	78, 78, 248, 249, 122, 73, 121, 150, 180, 76,
-	290, 291, 293, 56, 295, 8, 9, 9, 34, 35,
-	1, 284, 296, 297, 155, 129, 130, 131, 132, 133,
-	134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
-	47, 46, 45, 44, 156, 314, 315, 127, 43, 42,
-	41, 185, 319, 125, 166, 324, 325, 326, 188, 323,
-	157, 329, 191, 331, 330, 155, 40, 126, 332, 333,
-	100, 51, 72, 334, 53, 39, 38, 22, 52, 336,
-	49, 167, 186, 335, 54, 156, 265, 80, 341, 153,
-	154, 184, 219, 75, 115, 82, 84, 149, 70, 55,
-	222, 157, 50, 111, 18, 19, 93, 94, 20, 0,
-	96, 97, 99, 83, 71, 0, 0, 0, 0, 58,
-	59, 60, 61, 62, 63, 64, 65, 66, 67, 68,
-	69, 0, 0, 0, 13, 98, 0, 0, 24, 0,
-	30, 0, 0, 31, 32, 36, 100, 51, 72, 0,
-	53, 267, 0, 22, 52, 0, 0, 0, 266, 0,
-	54, 0, 270, 271, 269, 275, 277, 274, 276, 272,
-	273, 0, 84, 0, 70, 0, 0, 0, 0, 0,
-	18, 19, 93, 94, 20, 0, 96, 0, 99, 83,
-	71, 0, 0, 0, 0, 58, 59, 60, 61, 62,
-	63, 64, 65, 66, 67, 68, 69, 0, 0, 0,
-	13, 98, 0, 0, 24, 0, 30, 0, 0, 31,
-	32, 51, 72, 0, 53, 318, 0, 22, 52, 0,
-	0, 0, 0, 0, 54, 0, 270, 271, 269, 275,
-	277, 274, 276, 272, 273, 0, 0, 0, 70, 0,
-	0, 0, 0, 0, 18, 19, 0, 0, 20, 0,
-	0, 0, 17, 72, 71, 0, 0, 0, 22, 58,
-	59, 60, 61, 62, 63, 64, 65, 66, 67, 68,
-	69, 0, 0, 0, 13, 0, 0, 0, 24, 0,
-	30, 0, 0, 31, 32, 18, 19, 0, 0, 20,
-	0, 0, 0, 17, 33, 0, 0, 0, 0, 22,
-	11, 12, 14, 15, 16, 21, 23, 25, 26, 27,
-	28, 29, 0, 0, 0, 13, 0, 0, 0, 24,
-	0, 30, 0, 0, 31, 32, 18, 19, 0, 0,
-	20, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 11, 12, 14, 15, 16, 21, 23, 25, 26,
-	27, 28, 29, 100, 0, 0, 13, 0, 0, 0,
-	24, 169, 30, 0, 0, 31, 32, 0, 0, 0,
-	0, 0, 100, 0, 0, 0, 0, 0, 82, 84,
-	85, 0, 86, 87, 88, 89, 90, 91, 92, 93,
-	94, 95, 0, 96, 97, 99, 83, 82, 84, 85,
-	0, 86, 87, 88, 89, 90, 91, 92, 93, 94,
-	95, 0, 96, 97, 99, 83, 100, 0, 98, 0,
+const yyLast = 756
+
+var yyAct = [...]int16{
+	149, 317, 315, 263, 322, 146, 218, 184, 37, 142,
+	275, 276, 150, 113, 77, 101, 220, 102, 6, 104,
+	148, 190, 103, 191, 126, 105, 230, 192, 193, 153,
+	287, 334, 236, 312, 311, 106, 308, 153, 257, 255,
+	249, 289, 153, 254, 335, 121, 172, 144, 173, 154,
+	333, 258, 154, 332, 145, 248, 278, 154, 306, 232,
+	233, 153, 108, 234, 109, 155, 316, 259, 155, 107,
+	287, 247, 296, 155, 221, 223, 225, 226, 227, 235,
+	237, 240, 241, 242, 243, 244, 175, 100, 222, 224,
+	228, 229, 231, 238, 239, 104, 174, 176, 245, 246,
+	143, 105, 151, 152, 2, 3, 4, 5, 188, 57,
+	156, 295, 82, 84, 210, 166, 160, 163, 159, 158,
+	106, 323, 186, 93, 94, 100, 294, 96, 97, 99,
+	83, 189, 178, 293, 187, 100, 194, 195, 196, 197,
+	198, 199, 200, 201, 202, 203, 204, 205, 206, 207,
+	208, 84, 98, 209, 220, 211, 212, 122, 253, 180,
+	72, 93, 94, 33, 230, 96, 110, 99, 83, 215,
+	236, 284, 162, 214, 217, 96, 283, 99, 7, 281,
+	145, 252, 179, 251, 10, 161, 145, 170, 213, 115,
+	98, 282, 169, 307, 74, 305, 256, 232, 233, 114,
+	98, 234, 273, 274, 277, 168, 304, 250, 303, 247,
+	302, 301, 221, 223, 225, 226, 227, 235, 237, 240,
+	241, 242, 243, 244, 280, 300, 222, 224, 228, 229,
+	231, 238, 239, 157, 299, 298, 245, 246, 297, 81,
+	145, 127, 128, 129, 130, 131, 132, 133, 134, 135,
+	136, 137, 138, 139, 140, 141, 286, 288, 285, 290,
+	79, 182, 120, 34, 119, 48, 291, 292, 185, 262,
+	78, 73, 188, 8, 118, 153, 261, 35, 177, 117,
+	265, 266, 264, 270, 272, 269, 271, 267, 268, 115,
+	309, 310, 116, 1, 279, 154, 47, 314, 46, 114,
+	319, 320, 321, 45, 318, 44, 324, 112, 326, 325,
+	79, 155, 125, 327, 328, 43, 51, 72, 329, 53,
+	78, 42, 22, 52, 331, 41, 165, 56, 76, 54,
+	9, 9, 123, 336, 164, 40, 124, 39, 38, 49,
+	183, 330, 260, 70, 80, 181, 216, 75, 147, 18,
+	19, 55, 219, 20, 171, 50, 111, 0, 0, 71,
+	0, 0, 0, 0, 58, 59, 60, 61, 62, 63,
+	64, 65, 66, 67, 68, 69, 0, 0, 0, 13,
+	0, 0, 0, 24, 0, 30, 0, 0, 31, 32,
+	36, 0, 51, 72, 0, 53, 313, 0, 22, 52,
+	0, 0, 0, 0, 0, 54, 0, 265, 266, 264,
+	270, 272, 269, 271, 267, 268, 0, 0, 0, 70,
+	0, 0, 0, 0, 0, 18, 19, 0, 0, 20,
+	0, 0, 0, 0, 0, 71, 0, 0, 0, 0,
+	58, 59, 60, 61, 62, 63, 64, 65, 66, 67,
+	68, 69, 0, 0, 0, 13, 0, 0, 0, 24,
+	0, 30, 0, 0, 31, 32, 51, 72, 0, 53,
+	0, 0, 22, 52, 0, 0, 0, 0, 0, 54,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 98, 0, 0,
-	0, 82, 84, 85, 0, 86, 87, 88, 0, 90,
-	91, 92, 93, 94, 95, 0, 96, 97, 99, 83,
+	0, 0, 0, 70, 0, 0, 0, 0, 0, 18,
+	19, 0, 0, 20, 0, 0, 0, 17, 72, 71,
+	0, 0, 0, 22, 58, 59, 60, 61, 62, 63,
+	64, 65, 66, 67, 68, 69, 0, 0, 0, 13,
+	0, 0, 0, 24, 0, 30, 0, 0, 31, 32,
+	18, 19, 0, 0, 20, 0, 0, 0, 17, 33,
+	0, 0, 0, 0, 22, 11, 12, 14, 15, 16,
+	21, 23, 25, 26, 27, 28, 29, 0, 0, 0,
+	13, 0, 0, 0, 24, 0, 30, 0, 0, 31,
+	32, 18, 19, 0, 0, 20, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 11, 12, 14, 15,
+	16, 21, 23, 25, 26, 27, 28, 29, 100, 0,
+	0, 13, 0, 0, 0, 24, 167, 30, 0, 0,
+	31, 32, 0, 0, 0, 0, 0, 100, 0, 0,
+	0, 0, 0, 82, 84, 85, 0, 86, 87, 88,
+	89, 90, 91, 92, 93, 94, 95, 0, 96, 97,
+	99, 83, 82, 84, 85, 0, 86, 87, 88, 89,
+	90, 91, 92, 93, 94, 95, 0, 96, 97, 99,
+	83, 100, 0, 98, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	100, 0, 98, 0, 0, 0, 82, 84, 85, 0,
+	86, 87, 88, 0, 90, 91, 92, 93, 94, 95,
+	0, 96, 97, 99, 83, 82, 84, 85, 0, 86,
+	87, 0, 0, 90, 91, 0, 93, 94, 95, 0,
+	96, 97, 99, 83, 0, 0, 98, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 98,
+	0, 0, 0, 0, 0, 98,
 }
 
-var yyPact = [...]int{
-	17, 153, 541, 541, 385, 500, -1000, -1000, -1000, 146,
-	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
+var yyPact = [...]int16{
+	16, 168, 536, 536, 380, 495, -1000, -1000, -1000, 150,
 	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
-	-1000, -1000, -1000, 239, -1000, 224, -1000, 618, -1000, -1000,
 	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
-	36, 111, -1000, 459, -1000, 459, 141, -1000, -1000, -1000,
+	-1000, -1000, -1000, 308, -1000, 237, -1000, 613, -1000, -1000,
 	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
-	-1000, -1000, 181, -1000, -1000, 196, -1000, -1000, 252, -1000,
-	25, -1000, -54, -54, -54, -54, -54, -54, -54, -54,
-	-54, -54, -54, -54, -54, -54, -54, -54, 37, 255,
-	209, 111, -59, -1000, 118, 118, 309, -1000, 599, 21,
-	-1000, 187, -1000, -1000, 70, 114, -1000, -1000, -1000, 238,
-	-1000, 128, -1000, 296, 459, -1000, -55, -50, -1000, 459,
-	459, 459, 459, 459, 459, 459, 459, 459, 459, 459,
-	459, 459, 459, 459, -1000, 170, -1000, -1000, -1000, 110,
-	-1000, -1000, -1000, -1000, -1000, -1000, 51, 51, 107, -1000,
-	-1000, -1000, -1000, 168, -1000, -1000, 45, -1000, 618, -1000,
-	-1000, 172, -1000, 127, -1000, -1000, -1000, -1000, -1000, 76,
-	-1000, -1000, -1000, -1000, -1000, 22, 4, 3, -1000, -1000,
-	-1000, 384, 382, 118, 118, 118, 118, 21, 21, 306,
-	306, 306, 121, 662, 306, 306, 121, 21, 21, 306,
-	21, 382, -1000, 23, -1000, -1000, -1000, 179, -1000, 180,
+	20, 105, -1000, 454, -1000, 454, 147, -1000, -1000, -1000,
 	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
+	-1000, -1000, 287, -1000, -1000, 272, -1000, -1000, 260, -1000,
+	21, -1000, -50, -50, -50, -50, -50, -50, -50, -50,
+	-50, -50, -50, -50, -50, -50, -50, -50, 45, 18,
+	231, 105, -56, -1000, 170, 170, 304, -1000, 594, 121,
+	-1000, 185, -1000, -1000, 44, -1000, -1000, 258, -1000, 157,
+	-1000, 256, 454, -1000, -57, -49, -1000, 454, 454, 454,
+	454, 454, 454, 454, 454, 454, 454, 454, 454, 454,
+	454, 454, -1000, 171, -1000, -1000, -1000, 99, -1000, -1000,
+	-1000, -1000, -1000, -1000, 42, 42, 167, -1000, -1000, -1000,
+	-1000, 152, -1000, -1000, 33, -1000, 613, -1000, -1000, 187,
+	-1000, 156, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
+	-1000, -1000, 17, 13, 12, -1000, -1000, -1000, 252, 111,
+	170, 170, 170, 170, 121, 121, 73, 73, 73, 676,
+	657, 73, 73, 676, 121, 121, 73, 121, 111, -1000,
+	34, -1000, -1000, -1000, 177, -1000, 169, -1000, -1000, -1000,
 	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
 	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
-	-1000, -1000, 459, -1000, -1000, -1000, -1000, -1000, -1000, 52,
-	52, 10, 52, 57, 57, 38, 40, -1000, -1000, 218,
-	217, 216, 215, 214, 206, 204, 190, 189, -1000, -1000,
-	-1000, -1000, -1000, -1000, 32, 213, -1000, -1000, 19, -1000,
-	618, -1000, -1000, -1000, 52, -1000, 7, 6, 458, -1000,
-	-1000, -1000, 47, 5, 51, 51, 51, 113, 47, 113,
-	47, -1000, -1000, -1000, -1000, -1000, 52, 52, -1000, -1000,
-	-1000, 52, -1000, -1000, -1000, -1000, -1000, -1000, 51, -1000,
-	-1000, -1000, -1000, -1000, -1000, 26, -1000, 35, -1000, -1000,
-	-1000, -1000,
+	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 454,
+	-1000, -1000, -1000, -1000, 51, 51, 15, 51, 92, 92,
+	109, 55, -1000, -1000, 232, 229, 228, 219, 205, 204,
+	202, 200, 189, -1000, -1000, -1000, -1000, -1000, -1000, 37,
+	191, -1000, -1000, 14, -1000, 613, -1000, -1000, -1000, 51,
+	-1000, 8, 7, 379, -1000, -1000, -1000, 11, 10, 42,
+	42, 42, 107, 11, 107, 11, -1000, -1000, -1000, -1000,
+	-1000, 51, 51, -1000, -1000, -1000, 51, -1000, -1000, -1000,
+	-1000, -1000, -1000, 42, -1000, -1000, -1000, -1000, -1000, -1000,
+	29, -1000, 23, -1000, -1000, -1000, -1000,
 }
 
-var yyPgo = [...]int{
-	0, 353, 13, 352, 6, 15, 350, 263, 349, 347,
-	344, 209, 265, 343, 14, 342, 10, 11, 341, 337,
-	8, 336, 3, 4, 333, 2, 1, 0, 332, 12,
-	5, 330, 326, 18, 191, 325, 317, 7, 316, 304,
-	17, 303, 34, 300, 299, 298, 297, 293, 292, 291,
-	290, 249, 9, 271, 270, 268,
+var yyPgo = [...]int16{
+	0, 356, 13, 355, 6, 354, 352, 327, 351, 348,
+	184, 273, 347, 14, 346, 11, 10, 345, 344, 7,
+	342, 3, 4, 341, 2, 1, 0, 340, 12, 5,
+	339, 338, 15, 157, 337, 336, 8, 335, 334, 17,
+	332, 109, 325, 321, 315, 312, 305, 303, 298, 296,
+	265, 9, 294, 293, 263,
 }
 
-var yyR1 = [...]int{
-	0, 54, 54, 54, 54, 54, 54, 54, 37, 37,
-	37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
-	32, 32, 32, 32, 33, 33, 35, 35, 35, 35,
-	35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
-	35, 35, 34, 36, 36, 46, 46, 41, 41, 41,
-	41, 16, 16, 16, 16, 15, 15, 15, 4, 4,
-	38, 40, 40, 39, 39, 39, 47, 45, 45, 45,
-	31, 31, 31, 9, 9, 43, 49, 49, 49, 49,
-	49, 50, 51, 51, 51, 42, 42, 42, 1, 1,
-	1, 2, 2, 2, 2, 2, 2, 2, 12, 12,
+var yyR1 = [...]int8{
+	0, 53, 53, 53, 53, 53, 53, 53, 36, 36,
+	36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
+	31, 31, 31, 31, 32, 32, 34, 34, 34, 34,
+	34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+	34, 34, 33, 35, 35, 45, 45, 40, 40, 40,
+	40, 15, 15, 15, 15, 14, 14, 14, 4, 4,
+	37, 39, 39, 38, 38, 38, 46, 44, 44, 44,
+	30, 30, 30, 9, 9, 42, 48, 48, 48, 48,
+	48, 49, 50, 50, 50, 41, 41, 41, 1, 1,
+	1, 2, 2, 2, 2, 11, 11, 7, 7, 7,
 	7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
-	7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
-	7, 7, 11, 11, 11, 11, 13, 13, 13, 14,
-	14, 14, 14, 55, 19, 19, 19, 19, 18, 18,
-	18, 18, 18, 18, 18, 18, 18, 28, 28, 28,
-	20, 20, 20, 20, 21, 21, 21, 22, 22, 22,
-	22, 22, 22, 22, 22, 22, 23, 23, 24, 24,
-	24, 3, 3, 3, 3, 3, 3, 3, 3, 3,
-	3, 3, 3, 6, 6, 6, 6, 6, 6, 6,
+	7, 7, 7, 7, 7, 7, 7, 7, 7, 10,
+	10, 10, 10, 12, 12, 12, 13, 13, 13, 13,
+	54, 18, 18, 18, 18, 17, 17, 17, 17, 17,
+	17, 17, 17, 17, 27, 27, 27, 19, 19, 19,
+	19, 20, 20, 20, 21, 21, 21, 21, 21, 21,
+	21, 21, 21, 22, 22, 23, 23, 23, 3, 3,
+	3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
 	6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
 	6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
-	8, 8, 5, 5, 5, 5, 44, 27, 29, 29,
-	30, 30, 26, 25, 25, 52, 48, 10, 53, 53,
-	17, 17,
+	6, 6, 6, 6, 6, 6, 6, 8, 8, 5,
+	5, 5, 5, 43, 26, 28, 28, 29, 29, 25,
+	24, 24, 51, 47, 52, 52, 16, 16,
 }
 
-var yyR2 = [...]int{
+var yyR2 = [...]int8{
 	0, 2, 2, 2, 2, 2, 2, 1, 1, 1,
 	1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
 	3, 3, 2, 2, 2, 2, 4, 4, 4, 4,
@@ -538,104 +545,101 @@ var yyR2 = [...]int{
 	2, 3, 2, 3, 1, 2, 3, 3, 4, 3,
 	3, 5, 3, 1, 1, 4, 6, 6, 5, 4,
 	3, 2, 2, 1, 1, 3, 4, 2, 3, 1,
-	2, 3, 3, 1, 3, 3, 2, 1, 2, 1,
+	2, 3, 3, 2, 1, 2, 1, 1, 1, 1,
 	1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+	1, 1, 1, 1, 1, 1, 1, 1, 1, 3,
+	4, 2, 0, 3, 1, 2, 3, 3, 2, 1,
+	2, 0, 3, 2, 1, 1, 3, 1, 3, 4,
+	1, 3, 5, 5, 1, 1, 1, 4, 3, 3,
+	2, 3, 1, 2, 3, 3, 3, 3, 3, 3,
+	3, 3, 3, 4, 3, 3, 1, 2, 1, 1,
 	1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-	1, 1, 3, 4, 2, 0, 3, 1, 2, 3,
-	3, 2, 1, 2, 0, 3, 2, 1, 1, 3,
-	1, 3, 4, 1, 3, 5, 5, 1, 1, 1,
-	4, 3, 3, 2, 3, 1, 2, 3, 3, 3,
-	3, 3, 3, 3, 3, 3, 4, 3, 3, 1,
-	2, 1, 1, 1, 1, 1, 1, 1, 1, 1,
 	1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
 	1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
 	1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-	1, 1, 1, 1, 1, 1, 1, 1, 2, 2,
-	1, 1, 1, 2, 1, 1, 1, 1, 0, 1,
-	0, 1,
+	1, 1, 1, 1, 1, 2, 2, 1, 1, 1,
+	2, 1, 1, 1, 0, 1, 0, 1,
 }
 
-var yyChk = [...]int{
-	-1000, -54, 88, 89, 90, 91, 2, 10, -12, -7,
-	-11, 60, 61, 75, 62, 63, 64, 12, 45, 46,
+var yyChk = [...]int16{
+	-1000, -53, 88, 89, 90, 91, 2, 10, -11, -7,
+	-10, 60, 61, 75, 62, 63, 64, 12, 45, 46,
 	49, 65, 18, 66, 79, 67, 68, 69, 70, 71,
-	81, 84, 85, 13, -55, -12, 10, -37, -32, -35,
-	-38, -43, -44, -45, -47, -48, -49, -50, -51, -31,
-	-3, 12, 19, 15, 25, -8, -7, -42, 60, 61,
+	81, 84, 85, 13, -54, -11, 10, -36, -31, -34,
+	-37, -42, -43, -44, -46, -47, -48, -49, -50, -30,
+	-3, 12, 19, 15, 25, -8, -7, -41, 60, 61,
 	62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
-	39, 55, 13, -51, -11, -13, 20, -14, 12, 2,
-	-19, 2, 39, 57, 40, 41, 43, 44, 45, 46,
+	39, 55, 13, -50, -10, -12, 20, -13, 12, 2,
+	-18, 2, 39, 57, 40, 41, 43, 44, 45, 46,
 	47, 48, 49, 50, 51, 52, 54, 55, 79, 56,
-	14, -33, -40, 2, 75, 81, 15, -40, -37, -37,
-	-42, -1, 20, -2, 12, -10, 2, 25, 20, 7,
-	2, 4, 2, 24, -34, -41, -36, -46, 74, -34,
-	-34, -34, -34, -34, -34, -34, -34, -34, -34, -34,
-	-34, -34, -34, -34, -52, 55, 2, 9, -30, -9,
-	2, -27, -29, 84, 85, 19, 39, 55, -52, 2,
-	-40, -33, -16, 15, 2, -16, -39, 22, -37, 22,
-	20, 7, 2, -5, 2, 4, 52, 42, 53, -5,
-	20, -14, 25, 2, -18, 5, -28, -20, 12, -27,
-	-29, 16, -37, 78, 80, 76, 77, -37, -37, -37,
-	-37, -37, -37, -37, -37, -37, -37, -37, -37, -37,
-	-37, -37, -52, 15, -27, -27, 21, 6, 2, -15,
-	22, -4, -6, 2, 60, 74, 61, 75, 62, 63,
-	64, 76, 77, 12, 78, 45, 46, 49, 65, 18,
-	66, 79, 80, 67, 68, 69, 70, 71, 84, 85,
-	57, 22, 7, 20, -2, 25, 2, 25, 2, 26,
-	26, -29, 26, 39, 55, -21, 24, 17, -22, 30,
-	28, 29, 35, 36, 33, 31, 34, 32, -16, -16,
-	-17, -16, -17, 22, -53, -52, 2, 22, 7, 2,
-	-37, -26, 19, -26, 26, -26, -20, -20, 24, 17,
-	2, 17, 6, 6, 6, 6, 6, 6, 6, 6,
-	6, 21, 2, 22, -4, -26, 26, 26, 17, -22,
-	-25, 55, -26, -30, -27, -27, -27, -23, 14, -25,
-	-23, -25, -26, -26, -26, -24, -27, 24, 21, 2,
-	21, -27,
+	14, -32, -39, 2, 75, 81, 15, -39, -36, -36,
+	-41, -1, 20, -2, 12, 2, 20, 7, 2, 4,
+	2, 24, -33, -40, -35, -45, 74, -33, -33, -33,
+	-33, -33, -33, -33, -33, -33, -33, -33, -33, -33,
+	-33, -33, -51, 55, 2, 9, -29, -9, 2, -26,
+	-28, 84, 85, 19, 39, 55, -51, 2, -39, -32,
+	-15, 15, 2, -15, -38, 22, -36, 22, 20, 7,
+	2, -5, 2, 4, 52, 42, 53, 20, -13, 25,
+	2, -17, 5, -27, -19, 12, -26, -28, 16, -36,
+	78, 80, 76, 77, -36, -36, -36, -36, -36, -36,
+	-36, -36, -36, -36, -36, -36, -36, -36, -36, -51,
+	15, -26, -26, 21, 6, 2, -14, 22, -4, -6,
+	2, 60, 74, 61, 75, 62, 63, 64, 76, 77,
+	12, 78, 45, 46, 49, 65, 18, 66, 79, 80,
+	67, 68, 69, 70, 71, 84, 85, 57, 22, 7,
+	20, -2, 25, 2, 26, 26, -28, 26, 39, 55,
+	-20, 24, 17, -21, 30, 28, 29, 35, 36, 33,
+	31, 34, 32, -15, -15, -16, -15, -16, 22, -52,
+	-51, 2, 22, 7, 2, -36, -25, 19, -25, 26,
+	-25, -19, -19, 24, 17, 2, 17, 6, 6, 6,
+	6, 6, 6, 6, 6, 6, 21, 2, 22, -4,
+	-25, 26, 26, 17, -21, -24, 55, -25, -29, -26,
+	-26, -26, -22, 14, -24, -22, -24, -25, -25, -25,
+	-23, -26, 24, 21, 2, 21, -26,
 }
 
-var yyDef = [...]int{
-	0, -2, 125, 125, 0, 0, 7, 6, 1, 125,
-	99, 100, 101, 102, 103, 104, 105, 106, 107, 108,
-	109, 110, 111, 112, 113, 114, 115, 116, 117, 118,
-	119, 120, 121, 0, 2, -2, 3, 4, 8, 9,
+var yyDef = [...]int16{
+	0, -2, 122, 122, 0, 0, 7, 6, 1, 122,
+	96, 97, 98, 99, 100, 101, 102, 103, 104, 105,
+	106, 107, 108, 109, 110, 111, 112, 113, 114, 115,
+	116, 117, 118, 0, 2, -2, 3, 4, 8, 9,
 	10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
-	0, 106, 216, 0, 226, 0, 83, 84, -2, -2,
+	0, 103, 213, 0, 223, 0, 83, 84, -2, -2,
 	-2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
-	210, 211, 0, 5, 98, 0, 124, 127, 0, 132,
-	133, 137, 43, 43, 43, 43, 43, 43, 43, 43,
+	207, 208, 0, 5, 95, 0, 121, 124, 0, 129,
+	130, 134, 43, 43, 43, 43, 43, 43, 43, 43,
 	43, 43, 43, 43, 43, 43, 43, 43, 0, 0,
 	0, 0, 22, 23, 0, 0, 0, 60, 0, 81,
-	82, 0, 87, 89, 0, 93, 97, 227, 122, 0,
-	128, 0, 131, 136, 0, 42, 47, 48, 44, 0,
+	82, 0, 87, 89, 0, 94, 119, 0, 125, 0,
+	128, 133, 0, 42, 47, 48, 44, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 67, 0, 69, 225, 70, 0,
-	72, 220, 221, 73, 74, 217, 0, 0, 0, 80,
-	20, 21, 24, 0, 54, 25, 0, 62, 64, 66,
-	85, 0, 90, 0, 96, 212, 213, 214, 215, 0,
-	123, 126, 129, 130, 135, 138, 140, 143, 147, 148,
-	149, 0, 26, 0, 0, -2, -2, 27, 28, 29,
-	30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
-	40, 41, 68, 0, 218, 219, 75, -2, 79, 0,
-	53, 56, 58, 59, 183, 184, 185, 186, 187, 188,
+	0, 0, 67, 0, 69, 222, 70, 0, 72, 217,
+	218, 73, 74, 214, 0, 0, 0, 80, 20, 21,
+	24, 0, 54, 25, 0, 62, 64, 66, 85, 0,
+	90, 0, 93, 209, 210, 211, 212, 120, 123, 126,
+	127, 132, 135, 137, 140, 144, 145, 146, 0, 26,
+	0, 0, -2, -2, 27, 28, 29, 30, 31, 32,
+	33, 34, 35, 36, 37, 38, 39, 40, 41, 68,
+	0, 215, 216, 75, -2, 79, 0, 53, 56, 58,
+	59, 180, 181, 182, 183, 184, 185, 186, 187, 188,
 	189, 190, 191, 192, 193, 194, 195, 196, 197, 198,
-	199, 200, 201, 202, 203, 204, 205, 206, 207, 208,
-	209, 61, 65, 86, 88, 91, 95, 92, 94, 0,
-	0, 0, 0, 0, 0, 0, 0, 153, 155, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 45, 46,
-	49, 231, 50, 71, 0, -2, 78, 51, 0, 57,
-	63, 139, 222, 141, 0, 144, 0, 0, 0, 151,
-	156, 152, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 76, 77, 52, 55, 142, 0, 0, 150, 154,
-	157, 0, 224, 158, 159, 160, 161, 162, 0, 163,
-	164, 165, 145, 146, 223, 0, 169, 0, 167, 170,
-	166, 168,
+	199, 200, 201, 202, 203, 204, 205, 206, 61, 65,
+	86, 88, 91, 92, 0, 0, 0, 0, 0, 0,
+	0, 0, 150, 152, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 45, 46, 49, 227, 50, 71, 0,
+	-2, 78, 51, 0, 57, 63, 136, 219, 138, 0,
+	141, 0, 0, 0, 148, 153, 149, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 76, 77, 52, 55,
+	139, 0, 0, 147, 151, 154, 0, 221, 155, 156,
+	157, 158, 159, 0, 160, 161, 162, 142, 143, 220,
+	0, 166, 0, 164, 167, 163, 165,
 }
 
-var yyTok1 = [...]int{
+var yyTok1 = [...]int8{
 	1,
 }
 
-var yyTok2 = [...]int{
+var yyTok2 = [...]int8{
 	2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
 	12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
 	22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
@@ -648,7 +652,7 @@ var yyTok2 = [...]int{
 	92,
 }
 
-var yyTok3 = [...]int{
+var yyTok3 = [...]int8{
 	0,
 }
 
@@ -658,6 +662,8 @@ var yyErrorMessages = [...]struct {
 	msg   string
 }{}
 
+//line yaccpar:1
+
 /*	parser for yacc output	*/
 
 var (
@@ -728,9 +734,9 @@ func yyErrorMessage(state, lookAhead int) string {
 	expected := make([]int, 0, 4)
 
 	// Look for shiftable tokens.
-	base := yyPact[state]
+	base := int(yyPact[state])
 	for tok := TOKSTART; tok-1 < len(yyToknames); tok++ {
-		if n := base + tok; n >= 0 && n < yyLast && yyChk[yyAct[n]] == tok {
+		if n := base + tok; n >= 0 && n < yyLast && int(yyChk[int(yyAct[n])]) == tok {
 			if len(expected) == cap(expected) {
 				return res
 			}
@@ -740,13 +746,13 @@ func yyErrorMessage(state, lookAhead int) string {
 
 	if yyDef[state] == -2 {
 		i := 0
-		for yyExca[i] != -1 || yyExca[i+1] != state {
+		for yyExca[i] != -1 || int(yyExca[i+1]) != state {
 			i += 2
 		}
 
 		// Look for tokens that we accept or reduce.
 		for i += 2; yyExca[i] >= 0; i += 2 {
-			tok := yyExca[i]
+			tok := int(yyExca[i])
 			if tok < TOKSTART || yyExca[i+1] == 0 {
 				continue
 			}
@@ -777,30 +783,30 @@ func yylex1(lex yyLexer, lval *yySymType) (char, token int) {
 	token = 0
 	char = lex.Lex(lval)
 	if char <= 0 {
-		token = yyTok1[0]
+		token = int(yyTok1[0])
 		goto out
 	}
 	if char < len(yyTok1) {
-		token = yyTok1[char]
+		token = int(yyTok1[char])
 		goto out
 	}
 	if char >= yyPrivate {
 		if char < yyPrivate+len(yyTok2) {
-			token = yyTok2[char-yyPrivate]
+			token = int(yyTok2[char-yyPrivate])
 			goto out
 		}
 	}
 	for i := 0; i < len(yyTok3); i += 2 {
-		token = yyTok3[i+0]
+		token = int(yyTok3[i+0])
 		if token == char {
-			token = yyTok3[i+1]
+			token = int(yyTok3[i+1])
 			goto out
 		}
 	}
 
 out:
 	if token == 0 {
-		token = yyTok2[1] /* unknown char */
+		token = int(yyTok2[1]) /* unknown char */
 	}
 	if yyDebug >= 3 {
 		__yyfmt__.Printf("lex %s(%d)\n", yyTokname(token), uint(char))
@@ -855,7 +861,7 @@ yystack:
 	yyS[yyp].yys = yystate
 
 yynewstate:
-	yyn = yyPact[yystate]
+	yyn = int(yyPact[yystate])
 	if yyn <= yyFlag {
 		goto yydefault /* simple state */
 	}
@@ -866,8 +872,8 @@ yynewstate:
 	if yyn < 0 || yyn >= yyLast {
 		goto yydefault
 	}
-	yyn = yyAct[yyn]
-	if yyChk[yyn] == yytoken { /* valid shift */
+	yyn = int(yyAct[yyn])
+	if int(yyChk[yyn]) == yytoken { /* valid shift */
 		yyrcvr.char = -1
 		yytoken = -1
 		yyVAL = yyrcvr.lval
@@ -880,7 +886,7 @@ yynewstate:
 
 yydefault:
 	/* default state action */
-	yyn = yyDef[yystate]
+	yyn = int(yyDef[yystate])
 	if yyn == -2 {
 		if yyrcvr.char < 0 {
 			yyrcvr.char, yytoken = yylex1(yylex, &yyrcvr.lval)
@@ -889,18 +895,18 @@ yydefault:
 		/* look through exception table */
 		xi := 0
 		for {
-			if yyExca[xi+0] == -1 && yyExca[xi+1] == yystate {
+			if yyExca[xi+0] == -1 && int(yyExca[xi+1]) == yystate {
 				break
 			}
 			xi += 2
 		}
 		for xi += 2; ; xi += 2 {
-			yyn = yyExca[xi+0]
+			yyn = int(yyExca[xi+0])
 			if yyn < 0 || yyn == yytoken {
 				break
 			}
 		}
-		yyn = yyExca[xi+1]
+		yyn = int(yyExca[xi+1])
 		if yyn < 0 {
 			goto ret0
 		}
@@ -922,10 +928,10 @@ yydefault:
 
 			/* find a state where "error" is a legal shift action */
 			for yyp >= 0 {
-				yyn = yyPact[yyS[yyp].yys] + yyErrCode
+				yyn = int(yyPact[yyS[yyp].yys]) + yyErrCode
 				if yyn >= 0 && yyn < yyLast {
-					yystate = yyAct[yyn] /* simulate a shift of "error" */
-					if yyChk[yystate] == yyErrCode {
+					yystate = int(yyAct[yyn]) /* simulate a shift of "error" */
+					if int(yyChk[yystate]) == yyErrCode {
 						goto yystack
 					}
 				}
@@ -961,7 +967,7 @@ yydefault:
 	yypt := yyp
 	_ = yypt // guard against "declared and not used"
 
-	yyp -= yyR2[yyn]
+	yyp -= int(yyR2[yyn])
 	// yyp is now the index of $0. Perform the default action. Iff the
 	// reduced production is ε, $1 is possibly out of range.
 	if yyp+1 >= len(yyS) {
@@ -972,16 +978,16 @@ yydefault:
 	yyVAL = yyS[yyp+1]
 
 	/* consult goto table to find next state */
-	yyn = yyR1[yyn]
-	yyg := yyPgo[yyn]
+	yyn = int(yyR1[yyn])
+	yyg := int(yyPgo[yyn])
 	yyj := yyg + yyS[yyp].yys + 1
 
 	if yyj >= yyLast {
-		yystate = yyAct[yyg]
+		yystate = int(yyAct[yyg])
 	} else {
-		yystate = yyAct[yyj]
-		if yyChk[yystate] != -yyn {
-			yystate = yyAct[yyg]
+		yystate = int(yyAct[yyj])
+		if int(yyChk[yystate]) != -yyn {
+			yystate = int(yyAct[yyg])
 		}
 	}
 	// dummy call; replaced with literal code
@@ -989,52 +995,62 @@ yydefault:
 
 	case 1:
 		yyDollar = yyS[yypt-2 : yypt+1]
+//line promql/parser/generated_parser.y:200
 		{
 			yylex.(*parser).generatedParserResult = yyDollar[2].labels
 		}
 	case 3:
 		yyDollar = yyS[yypt-2 : yypt+1]
+//line promql/parser/generated_parser.y:203
 		{
 			yylex.(*parser).addParseErrf(posrange.PositionRange{}, "no expression found in input")
 		}
 	case 4:
 		yyDollar = yyS[yypt-2 : yypt+1]
+//line promql/parser/generated_parser.y:205
 		{
 			yylex.(*parser).generatedParserResult = yyDollar[2].node
 		}
 	case 5:
 		yyDollar = yyS[yypt-2 : yypt+1]
+//line promql/parser/generated_parser.y:207
 		{
 			yylex.(*parser).generatedParserResult = yyDollar[2].node
 		}
 	case 7:
 		yyDollar = yyS[yypt-1 : yypt+1]
+//line promql/parser/generated_parser.y:210
 		{
 			yylex.(*parser).unexpected("", "")
 		}
 	case 20:
 		yyDollar = yyS[yypt-3 : yypt+1]
+//line promql/parser/generated_parser.y:233
 		{
 			yyVAL.node = yylex.(*parser).newAggregateExpr(yyDollar[1].item, yyDollar[2].node, yyDollar[3].node)
 		}
 	case 21:
 		yyDollar = yyS[yypt-3 : yypt+1]
+//line promql/parser/generated_parser.y:235
 		{
 			yyVAL.node = yylex.(*parser).newAggregateExpr(yyDollar[1].item, yyDollar[3].node, yyDollar[2].node)
 		}
 	case 22:
 		yyDollar = yyS[yypt-2 : yypt+1]
+//line promql/parser/generated_parser.y:237
 		{
 			yyVAL.node = yylex.(*parser).newAggregateExpr(yyDollar[1].item, &AggregateExpr{}, yyDollar[2].node)
 		}
 	case 23:
 		yyDollar = yyS[yypt-2 : yypt+1]
+//line promql/parser/generated_parser.y:239
 		{
 			yylex.(*parser).unexpected("aggregation", "")
 			yyVAL.node = yylex.(*parser).newAggregateExpr(yyDollar[1].item, &AggregateExpr{}, Expressions{})
 		}
 	case 24:
 		yyDollar = yyS[yypt-2 : yypt+1]
+//line promql/parser/generated_parser.y:247
 		{
 			yyVAL.node = &AggregateExpr{
 				Grouping: yyDollar[2].strings,
@@ -1042,6 +1058,7 @@ yydefault:
 		}
 	case 25:
 		yyDollar = yyS[yypt-2 : yypt+1]
+//line promql/parser/generated_parser.y:253
 		{
 			yyVAL.node = &AggregateExpr{
 				Grouping: yyDollar[2].strings,
@@ -1050,86 +1067,103 @@ yydefault:
 		}
 	case 26:
 		yyDollar = yyS[yypt-4 : yypt+1]
+//line promql/parser/generated_parser.y:266
 		{
 			yyVAL.node = yylex.(*parser).newBinaryExpression(yyDollar[1].node, yyDollar[2].item, yyDollar[3].node, yyDollar[4].node)
 		}
 	case 27:
 		yyDollar = yyS[yypt-4 : yypt+1]
+//line promql/parser/generated_parser.y:267
 		{
 			yyVAL.node = yylex.(*parser).newBinaryExpression(yyDollar[1].node, yyDollar[2].item, yyDollar[3].node, yyDollar[4].node)
 		}
 	case 28:
 		yyDollar = yyS[yypt-4 : yypt+1]
+//line promql/parser/generated_parser.y:268
 		{
 			yyVAL.node = yylex.(*parser).newBinaryExpression(yyDollar[1].node, yyDollar[2].item, yyDollar[3].node, yyDollar[4].node)
 		}
 	case 29:
 		yyDollar = yyS[yypt-4 : yypt+1]
+//line promql/parser/generated_parser.y:269
 		{
 			yyVAL.node = yylex.(*parser).newBinaryExpression(yyDollar[1].node, yyDollar[2].item, yyDollar[3].node, yyDollar[4].node)
 		}
 	case 30:
 		yyDollar = yyS[yypt-4 : yypt+1]
+//line promql/parser/generated_parser.y:270
 		{
 			yyVAL.node = yylex.(*parser).newBinaryExpression(yyDollar[1].node, yyDollar[2].item, yyDollar[3].node, yyDollar[4].node)
 		}
 	case 31:
 		yyDollar = yyS[yypt-4 : yypt+1]
+//line promql/parser/generated_parser.y:271
 		{
 			yyVAL.node = yylex.(*parser).newBinaryExpression(yyDollar[1].node, yyDollar[2].item, yyDollar[3].node, yyDollar[4].node)
 		}
 	case 32:
 		yyDollar = yyS[yypt-4 : yypt+1]
+//line promql/parser/generated_parser.y:272
 		{
 			yyVAL.node = yylex.(*parser).newBinaryExpression(yyDollar[1].node, yyDollar[2].item, yyDollar[3].node, yyDollar[4].node)
 		}
 	case 33:
 		yyDollar = yyS[yypt-4 : yypt+1]
+//line promql/parser/generated_parser.y:273
 		{
 			yyVAL.node = yylex.(*parser).newBinaryExpression(yyDollar[1].node, yyDollar[2].item, yyDollar[3].node, yyDollar[4].node)
 		}
 	case 34:
 		yyDollar = yyS[yypt-4 : yypt+1]
+//line promql/parser/generated_parser.y:274
 		{
 			yyVAL.node = yylex.(*parser).newBinaryExpression(yyDollar[1].node, yyDollar[2].item, yyDollar[3].node, yyDollar[4].node)
 		}
 	case 35:
 		yyDollar = yyS[yypt-4 : yypt+1]
+//line promql/parser/generated_parser.y:275
 		{
 			yyVAL.node = yylex.(*parser).newBinaryExpression(yyDollar[1].node, yyDollar[2].item, yyDollar[3].node, yyDollar[4].node)
 		}
 	case 36:
 		yyDollar = yyS[yypt-4 : yypt+1]
+//line promql/parser/generated_parser.y:276
 		{
 			yyVAL.node = yylex.(*parser).newBinaryExpression(yyDollar[1].node, yyDollar[2].item, yyDollar[3].node, yyDollar[4].node)
 		}
 	case 37:
 		yyDollar = yyS[yypt-4 : yypt+1]
+//line promql/parser/generated_parser.y:277
 		{
 			yyVAL.node = yylex.(*parser).newBinaryExpression(yyDollar[1].node, yyDollar[2].item, yyDollar[3].node, yyDollar[4].node)
 		}
 	case 38:
 		yyDollar = yyS[yypt-4 : yypt+1]
+//line promql/parser/generated_parser.y:278
 		{
 			yyVAL.node = yylex.(*parser).newBinaryExpression(yyDollar[1].node, yyDollar[2].item, yyDollar[3].node, yyDollar[4].node)
 		}
 	case 39:
 		yyDollar = yyS[yypt-4 : yypt+1]
+//line promql/parser/generated_parser.y:279
 		{
 			yyVAL.node = yylex.(*parser).newBinaryExpression(yyDollar[1].node, yyDollar[2].item, yyDollar[3].node, yyDollar[4].node)
 		}
 	case 40:
 		yyDollar = yyS[yypt-4 : yypt+1]
+//line promql/parser/generated_parser.y:280
 		{
 			yyVAL.node = yylex.(*parser).newBinaryExpression(yyDollar[1].node, yyDollar[2].item, yyDollar[3].node, yyDollar[4].node)
 		}
 	case 41:
 		yyDollar = yyS[yypt-4 : yypt+1]
+//line promql/parser/generated_parser.y:281
 		{
 			yyVAL.node = yylex.(*parser).newBinaryExpression(yyDollar[1].node, yyDollar[2].item, yyDollar[3].node, yyDollar[4].node)
 		}
 	case 43:
 		yyDollar = yyS[yypt-0 : yypt+1]
+//line promql/parser/generated_parser.y:289
 		{
 			yyVAL.node = &BinaryExpr{
 				VectorMatching: &VectorMatching{Card: CardOneToOne},
@@ -1137,6 +1171,7 @@ yydefault:
 		}
 	case 44:
 		yyDollar = yyS[yypt-1 : yypt+1]
+//line promql/parser/generated_parser.y:294
 		{
 			yyVAL.node = &BinaryExpr{
 				VectorMatching: &VectorMatching{Card: CardOneToOne},
@@ -1145,12 +1180,14 @@ yydefault:
 		}
 	case 45:
 		yyDollar = yyS[yypt-3 : yypt+1]
+//line promql/parser/generated_parser.y:302
 		{
 			yyVAL.node = yyDollar[1].node
 			yyVAL.node.(*BinaryExpr).VectorMatching.MatchingLabels = yyDollar[3].strings
 		}
 	case 46:
 		yyDollar = yyS[yypt-3 : yypt+1]
+//line promql/parser/generated_parser.y:307
 		{
 			yyVAL.node = yyDollar[1].node
 			yyVAL.node.(*BinaryExpr).VectorMatching.MatchingLabels = yyDollar[3].strings
@@ -1158,6 +1195,7 @@ yydefault:
 		}
 	case 49:
 		yyDollar = yyS[yypt-3 : yypt+1]
+//line promql/parser/generated_parser.y:317
 		{
 			yyVAL.node = yyDollar[1].node
 			yyVAL.node.(*BinaryExpr).VectorMatching.Card = CardManyToOne
@@ -1165,6 +1203,7 @@ yydefault:
 		}
 	case 50:
 		yyDollar = yyS[yypt-3 : yypt+1]
+//line promql/parser/generated_parser.y:323
 		{
 			yyVAL.node = yyDollar[1].node
 			yyVAL.node.(*BinaryExpr).VectorMatching.Card = CardOneToMany
@@ -1172,43 +1211,51 @@ yydefault:
 		}
 	case 51:
 		yyDollar = yyS[yypt-3 : yypt+1]
+//line promql/parser/generated_parser.y:332
 		{
 			yyVAL.strings = yyDollar[2].strings
 		}
 	case 52:
 		yyDollar = yyS[yypt-4 : yypt+1]
+//line promql/parser/generated_parser.y:334
 		{
 			yyVAL.strings = yyDollar[2].strings
 		}
 	case 53:
 		yyDollar = yyS[yypt-2 : yypt+1]
+//line promql/parser/generated_parser.y:336
 		{
 			yyVAL.strings = []string{}
 		}
 	case 54:
 		yyDollar = yyS[yypt-1 : yypt+1]
+//line promql/parser/generated_parser.y:338
 		{
 			yylex.(*parser).unexpected("grouping opts", "\"(\"")
 			yyVAL.strings = nil
 		}
 	case 55:
 		yyDollar = yyS[yypt-3 : yypt+1]
+//line promql/parser/generated_parser.y:344
 		{
 			yyVAL.strings = append(yyDollar[1].strings, yyDollar[3].item.Val)
 		}
 	case 56:
 		yyDollar = yyS[yypt-1 : yypt+1]
+//line promql/parser/generated_parser.y:346
 		{
 			yyVAL.strings = []string{yyDollar[1].item.Val}
 		}
 	case 57:
 		yyDollar = yyS[yypt-2 : yypt+1]
+//line promql/parser/generated_parser.y:348
 		{
 			yylex.(*parser).unexpected("grouping opts", "\",\" or \")\"")
 			yyVAL.strings = yyDollar[1].strings
 		}
 	case 58:
 		yyDollar = yyS[yypt-1 : yypt+1]
+//line promql/parser/generated_parser.y:352
 		{
 			if !isLabel(yyDollar[1].item.Val) {
 				yylex.(*parser).unexpected("grouping opts", "label")
@@ -1217,12 +1264,14 @@ yydefault:
 		}
 	case 59:
 		yyDollar = yyS[yypt-1 : yypt+1]
+//line promql/parser/generated_parser.y:359
 		{
 			yylex.(*parser).unexpected("grouping opts", "label")
 			yyVAL.item = Item{}
 		}
 	case 60:
 		yyDollar = yyS[yypt-2 : yypt+1]
+//line promql/parser/generated_parser.y:367
 		{
 			fn, exist := getFunction(yyDollar[1].item.Val, yylex.(*parser).functions)
 			if !exist {
@@ -1242,73 +1291,86 @@ yydefault:
 		}
 	case 61:
 		yyDollar = yyS[yypt-3 : yypt+1]
+//line promql/parser/generated_parser.y:387
 		{
 			yyVAL.node = yyDollar[2].node
 		}
 	case 62:
 		yyDollar = yyS[yypt-2 : yypt+1]
+//line promql/parser/generated_parser.y:389
 		{
 			yyVAL.node = Expressions{}
 		}
 	case 63:
 		yyDollar = yyS[yypt-3 : yypt+1]
+//line promql/parser/generated_parser.y:393
 		{
 			yyVAL.node = append(yyDollar[1].node.(Expressions), yyDollar[3].node.(Expr))
 		}
 	case 64:
 		yyDollar = yyS[yypt-1 : yypt+1]
+//line promql/parser/generated_parser.y:395
 		{
 			yyVAL.node = Expressions{yyDollar[1].node.(Expr)}
 		}
 	case 65:
 		yyDollar = yyS[yypt-2 : yypt+1]
+//line promql/parser/generated_parser.y:397
 		{
 			yylex.(*parser).addParseErrf(yyDollar[2].item.PositionRange(), "trailing commas not allowed in function call args")
 			yyVAL.node = yyDollar[1].node
 		}
 	case 66:
 		yyDollar = yyS[yypt-3 : yypt+1]
+//line promql/parser/generated_parser.y:408
 		{
 			yyVAL.node = &ParenExpr{Expr: yyDollar[2].node.(Expr), PosRange: mergeRanges(&yyDollar[1].item, &yyDollar[3].item)}
 		}
 	case 67:
 		yyDollar = yyS[yypt-3 : yypt+1]
+//line promql/parser/generated_parser.y:416
 		{
 			yylex.(*parser).addOffset(yyDollar[1].node, yyDollar[3].duration)
 			yyVAL.node = yyDollar[1].node
 		}
 	case 68:
 		yyDollar = yyS[yypt-4 : yypt+1]
+//line promql/parser/generated_parser.y:421
 		{
 			yylex.(*parser).addOffset(yyDollar[1].node, -yyDollar[4].duration)
 			yyVAL.node = yyDollar[1].node
 		}
 	case 69:
 		yyDollar = yyS[yypt-3 : yypt+1]
+//line promql/parser/generated_parser.y:426
 		{
 			yylex.(*parser).unexpected("offset", "duration")
 			yyVAL.node = yyDollar[1].node
 		}
 	case 70:
 		yyDollar = yyS[yypt-3 : yypt+1]
+//line promql/parser/generated_parser.y:433
 		{
 			yylex.(*parser).setTimestamp(yyDollar[1].node, yyDollar[3].float)
 			yyVAL.node = yyDollar[1].node
 		}
 	case 71:
 		yyDollar = yyS[yypt-5 : yypt+1]
+//line promql/parser/generated_parser.y:438
 		{
 			yylex.(*parser).setAtModifierPreprocessor(yyDollar[1].node, yyDollar[3].item)
 			yyVAL.node = yyDollar[1].node
 		}
 	case 72:
 		yyDollar = yyS[yypt-3 : yypt+1]
+//line promql/parser/generated_parser.y:443
 		{
 			yylex.(*parser).unexpected("@", "timestamp")
 			yyVAL.node = yyDollar[1].node
 		}
 	case 75:
 		yyDollar = yyS[yypt-4 : yypt+1]
+//line promql/parser/generated_parser.y:453
 		{
 			var errMsg string
 			vs, ok := yyDollar[1].node.(*VectorSelector)
@@ -1333,6 +1395,7 @@ yydefault:
 		}
 	case 76:
 		yyDollar = yyS[yypt-6 : yypt+1]
+//line promql/parser/generated_parser.y:478
 		{
 			yyVAL.node = &SubqueryExpr{
 				Expr:  yyDollar[1].node.(Expr),
@@ -1344,30 +1407,35 @@ yydefault:
 		}
 	case 77:
 		yyDollar = yyS[yypt-6 : yypt+1]
+//line promql/parser/generated_parser.y:488
 		{
 			yylex.(*parser).unexpected("subquery selector", "\"]\"")
 			yyVAL.node = yyDollar[1].node
 		}
 	case 78:
 		yyDollar = yyS[yypt-5 : yypt+1]
+//line promql/parser/generated_parser.y:490
 		{
 			yylex.(*parser).unexpected("subquery selector", "duration or \"]\"")
 			yyVAL.node = yyDollar[1].node
 		}
 	case 79:
 		yyDollar = yyS[yypt-4 : yypt+1]
+//line promql/parser/generated_parser.y:492
 		{
 			yylex.(*parser).unexpected("subquery or range", "\":\" or \"]\"")
 			yyVAL.node = yyDollar[1].node
 		}
 	case 80:
 		yyDollar = yyS[yypt-3 : yypt+1]
+//line promql/parser/generated_parser.y:494
 		{
 			yylex.(*parser).unexpected("subquery selector", "duration")
 			yyVAL.node = yyDollar[1].node
 		}
 	case 81:
 		yyDollar = yyS[yypt-2 : yypt+1]
+//line promql/parser/generated_parser.y:504
 		{
 			if nl, ok := yyDollar[2].node.(*NumberLiteral); ok {
 				if yyDollar[1].item.Typ == SUB {
@@ -1381,6 +1449,7 @@ yydefault:
 		}
 	case 82:
 		yyDollar = yyS[yypt-2 : yypt+1]
+//line promql/parser/generated_parser.y:522
 		{
 			vs := yyDollar[2].node.(*VectorSelector)
 			vs.PosRange = mergeRanges(&yyDollar[1].item, vs)
@@ -1390,6 +1459,7 @@ yydefault:
 		}
 	case 83:
 		yyDollar = yyS[yypt-1 : yypt+1]
+//line promql/parser/generated_parser.y:530
 		{
 			vs := &VectorSelector{
 				Name:          yyDollar[1].item.Val,
@@ -1401,6 +1471,7 @@ yydefault:
 		}
 	case 84:
 		yyDollar = yyS[yypt-1 : yypt+1]
+//line promql/parser/generated_parser.y:540
 		{
 			vs := yyDollar[1].node.(*VectorSelector)
 			yylex.(*parser).assembleVectorSelector(vs)
@@ -1408,6 +1479,7 @@ yydefault:
 		}
 	case 85:
 		yyDollar = yyS[yypt-3 : yypt+1]
+//line promql/parser/generated_parser.y:548
 		{
 			yyVAL.node = &VectorSelector{
 				LabelMatchers: yyDollar[2].matchers,
@@ -1416,6 +1488,7 @@ yydefault:
 		}
 	case 86:
 		yyDollar = yyS[yypt-4 : yypt+1]
+//line promql/parser/generated_parser.y:555
 		{
 			yyVAL.node = &VectorSelector{
 				LabelMatchers: yyDollar[2].matchers,
@@ -1424,6 +1497,7 @@ yydefault:
 		}
 	case 87:
 		yyDollar = yyS[yypt-2 : yypt+1]
+//line promql/parser/generated_parser.y:562
 		{
 			yyVAL.node = &VectorSelector{
 				LabelMatchers: []*labels.Matcher{},
@@ -1432,6 +1506,7 @@ yydefault:
 		}
 	case 88:
 		yyDollar = yyS[yypt-3 : yypt+1]
+//line promql/parser/generated_parser.y:571
 		{
 			if yyDollar[1].matchers != nil {
 				yyVAL.matchers = append(yyDollar[1].matchers, yyDollar[3].matcher)
@@ -1441,174 +1516,186 @@ yydefault:
 		}
 	case 89:
 		yyDollar = yyS[yypt-1 : yypt+1]
+//line promql/parser/generated_parser.y:579
 		{
 			yyVAL.matchers = []*labels.Matcher{yyDollar[1].matcher}
 		}
 	case 90:
 		yyDollar = yyS[yypt-2 : yypt+1]
+//line promql/parser/generated_parser.y:581
 		{
 			yylex.(*parser).unexpected("label matching", "\",\" or \"}\"")
 			yyVAL.matchers = yyDollar[1].matchers
 		}
 	case 91:
 		yyDollar = yyS[yypt-3 : yypt+1]
+//line promql/parser/generated_parser.y:585
 		{
 			yyVAL.matcher = yylex.(*parser).newLabelMatcher(yyDollar[1].item, yyDollar[2].item, yyDollar[3].item)
 		}
 	case 92:
 		yyDollar = yyS[yypt-3 : yypt+1]
-		{
-			yyVAL.matcher = yylex.(*parser).newLabelMatcher(yyDollar[1].item, yyDollar[2].item, yyDollar[3].item)
-		}
-	case 93:
-		yyDollar = yyS[yypt-1 : yypt+1]
-		{
-			yyVAL.matcher = yylex.(*parser).newMetricNameMatcher(yyDollar[1].item)
-		}
-	case 94:
-		yyDollar = yyS[yypt-3 : yypt+1]
+//line promql/parser/generated_parser.y:587
 		{
 			yylex.(*parser).unexpected("label matching", "string")
 			yyVAL.matcher = nil
 		}
-	case 95:
-		yyDollar = yyS[yypt-3 : yypt+1]
-		{
-			yylex.(*parser).unexpected("label matching", "string")
-			yyVAL.matcher = nil
-		}
-	case 96:
+	case 93:
 		yyDollar = yyS[yypt-2 : yypt+1]
+//line promql/parser/generated_parser.y:589
 		{
 			yylex.(*parser).unexpected("label matching", "label matching operator")
 			yyVAL.matcher = nil
 		}
-	case 97:
+	case 94:
 		yyDollar = yyS[yypt-1 : yypt+1]
+//line promql/parser/generated_parser.y:591
 		{
 			yylex.(*parser).unexpected("label matching", "identifier or \"}\"")
 			yyVAL.matcher = nil
 		}
-	case 98:
+	case 95:
 		yyDollar = yyS[yypt-2 : yypt+1]
+//line promql/parser/generated_parser.y:599
 		{
 			b := labels.NewBuilder(yyDollar[2].labels)
 			b.Set(labels.MetricName, yyDollar[1].item.Val)
 			yyVAL.labels = b.Labels()
 		}
-	case 99:
+	case 96:
 		yyDollar = yyS[yypt-1 : yypt+1]
+//line promql/parser/generated_parser.y:601
 		{
 			yyVAL.labels = yyDollar[1].labels
 		}
-	case 122:
+	case 119:
 		yyDollar = yyS[yypt-3 : yypt+1]
+//line promql/parser/generated_parser.y:608
 		{
 			yyVAL.labels = labels.New(yyDollar[2].lblList...)
 		}
-	case 123:
+	case 120:
 		yyDollar = yyS[yypt-4 : yypt+1]
+//line promql/parser/generated_parser.y:610
 		{
 			yyVAL.labels = labels.New(yyDollar[2].lblList...)
 		}
-	case 124:
+	case 121:
 		yyDollar = yyS[yypt-2 : yypt+1]
+//line promql/parser/generated_parser.y:612
 		{
 			yyVAL.labels = labels.New()
 		}
-	case 125:
+	case 122:
 		yyDollar = yyS[yypt-0 : yypt+1]
+//line promql/parser/generated_parser.y:614
 		{
 			yyVAL.labels = labels.New()
 		}
-	case 126:
+	case 123:
 		yyDollar = yyS[yypt-3 : yypt+1]
+//line promql/parser/generated_parser.y:618
 		{
 			yyVAL.lblList = append(yyDollar[1].lblList, yyDollar[3].label)
 		}
-	case 127:
+	case 124:
 		yyDollar = yyS[yypt-1 : yypt+1]
+//line promql/parser/generated_parser.y:620
 		{
 			yyVAL.lblList = []labels.Label{yyDollar[1].label}
 		}
-	case 128:
+	case 125:
 		yyDollar = yyS[yypt-2 : yypt+1]
+//line promql/parser/generated_parser.y:622
 		{
 			yylex.(*parser).unexpected("label set", "\",\" or \"}\"")
 			yyVAL.lblList = yyDollar[1].lblList
 		}
-	case 129:
+	case 126:
 		yyDollar = yyS[yypt-3 : yypt+1]
+//line promql/parser/generated_parser.y:627
 		{
 			yyVAL.label = labels.Label{Name: yyDollar[1].item.Val, Value: yylex.(*parser).unquoteString(yyDollar[3].item.Val)}
 		}
-	case 130:
+	case 127:
 		yyDollar = yyS[yypt-3 : yypt+1]
+//line promql/parser/generated_parser.y:629
 		{
 			yylex.(*parser).unexpected("label set", "string")
 			yyVAL.label = labels.Label{}
 		}
-	case 131:
+	case 128:
 		yyDollar = yyS[yypt-2 : yypt+1]
+//line promql/parser/generated_parser.y:631
 		{
 			yylex.(*parser).unexpected("label set", "\"=\"")
 			yyVAL.label = labels.Label{}
 		}
-	case 132:
+	case 129:
 		yyDollar = yyS[yypt-1 : yypt+1]
+//line promql/parser/generated_parser.y:633
 		{
 			yylex.(*parser).unexpected("label set", "identifier or \"}\"")
 			yyVAL.label = labels.Label{}
 		}
-	case 133:
+	case 130:
 		yyDollar = yyS[yypt-2 : yypt+1]
+//line promql/parser/generated_parser.y:644
 		{
 			yylex.(*parser).generatedParserResult = &seriesDescription{
 				labels: yyDollar[1].labels,
 				values: yyDollar[2].series,
 			}
 		}
-	case 134:
+	case 131:
 		yyDollar = yyS[yypt-0 : yypt+1]
+//line promql/parser/generated_parser.y:653
 		{
 			yyVAL.series = []SequenceValue{}
 		}
-	case 135:
+	case 132:
 		yyDollar = yyS[yypt-3 : yypt+1]
+//line promql/parser/generated_parser.y:655
 		{
 			yyVAL.series = append(yyDollar[1].series, yyDollar[3].series...)
 		}
-	case 136:
+	case 133:
 		yyDollar = yyS[yypt-2 : yypt+1]
+//line promql/parser/generated_parser.y:657
 		{
 			yyVAL.series = yyDollar[1].series
 		}
-	case 137:
+	case 134:
 		yyDollar = yyS[yypt-1 : yypt+1]
+//line promql/parser/generated_parser.y:659
 		{
 			yylex.(*parser).unexpected("series values", "")
 			yyVAL.series = nil
 		}
-	case 138:
+	case 135:
 		yyDollar = yyS[yypt-1 : yypt+1]
+//line promql/parser/generated_parser.y:663
 		{
 			yyVAL.series = []SequenceValue{{Omitted: true}}
 		}
-	case 139:
+	case 136:
 		yyDollar = yyS[yypt-3 : yypt+1]
+//line promql/parser/generated_parser.y:665
 		{
 			yyVAL.series = []SequenceValue{}
 			for i := uint64(0); i < yyDollar[3].uint; i++ {
 				yyVAL.series = append(yyVAL.series, SequenceValue{Omitted: true})
 			}
 		}
-	case 140:
+	case 137:
 		yyDollar = yyS[yypt-1 : yypt+1]
+//line promql/parser/generated_parser.y:672
 		{
 			yyVAL.series = []SequenceValue{{Value: yyDollar[1].float}}
 		}
-	case 141:
+	case 138:
 		yyDollar = yyS[yypt-3 : yypt+1]
+//line promql/parser/generated_parser.y:674
 		{
 			yyVAL.series = []SequenceValue{}
 			// Add an additional value for time 0, which we ignore in tests.
@@ -1616,8 +1703,9 @@ yydefault:
 				yyVAL.series = append(yyVAL.series, SequenceValue{Value: yyDollar[1].float})
 			}
 		}
-	case 142:
+	case 139:
 		yyDollar = yyS[yypt-4 : yypt+1]
+//line promql/parser/generated_parser.y:682
 		{
 			yyVAL.series = []SequenceValue{}
 			// Add an additional value for time 0, which we ignore in tests.
@@ -1626,13 +1714,15 @@ yydefault:
 				yyDollar[1].float += yyDollar[2].float
 			}
 		}
-	case 143:
+	case 140:
 		yyDollar = yyS[yypt-1 : yypt+1]
+//line promql/parser/generated_parser.y:692
 		{
 			yyVAL.series = []SequenceValue{{Histogram: yyDollar[1].histogram}}
 		}
-	case 144:
+	case 141:
 		yyDollar = yyS[yypt-3 : yypt+1]
+//line promql/parser/generated_parser.y:696
 		{
 			yyVAL.series = []SequenceValue{}
 			// Add an additional value for time 0, which we ignore in tests.
@@ -1641,8 +1731,9 @@ yydefault:
 				//$1 += $2
 			}
 		}
-	case 145:
+	case 142:
 		yyDollar = yyS[yypt-5 : yypt+1]
+//line promql/parser/generated_parser.y:705
 		{
 			val, err := yylex.(*parser).histogramsIncreaseSeries(yyDollar[1].histogram, yyDollar[3].histogram, yyDollar[5].uint)
 			if err != nil {
@@ -1650,8 +1741,9 @@ yydefault:
 			}
 			yyVAL.series = val
 		}
-	case 146:
+	case 143:
 		yyDollar = yyS[yypt-5 : yypt+1]
+//line promql/parser/generated_parser.y:713
 		{
 			val, err := yylex.(*parser).histogramsDecreaseSeries(yyDollar[1].histogram, yyDollar[3].histogram, yyDollar[5].uint)
 			if err != nil {
@@ -1659,150 +1751,176 @@ yydefault:
 			}
 			yyVAL.series = val
 		}
-	case 147:
+	case 144:
 		yyDollar = yyS[yypt-1 : yypt+1]
+//line promql/parser/generated_parser.y:723
 		{
 			if yyDollar[1].item.Val != "stale" {
 				yylex.(*parser).unexpected("series values", "number or \"stale\"")
 			}
 			yyVAL.float = math.Float64frombits(value.StaleNaN)
 		}
-	case 150:
+	case 147:
 		yyDollar = yyS[yypt-4 : yypt+1]
+//line promql/parser/generated_parser.y:735
 		{
 			yyVAL.histogram = yylex.(*parser).buildHistogramFromMap(&yyDollar[2].descriptors)
 		}
-	case 151:
+	case 148:
 		yyDollar = yyS[yypt-3 : yypt+1]
+//line promql/parser/generated_parser.y:739
 		{
 			yyVAL.histogram = yylex.(*parser).buildHistogramFromMap(&yyDollar[2].descriptors)
 		}
-	case 152:
+	case 149:
 		yyDollar = yyS[yypt-3 : yypt+1]
+//line promql/parser/generated_parser.y:743
 		{
 			m := yylex.(*parser).newMap()
 			yyVAL.histogram = yylex.(*parser).buildHistogramFromMap(&m)
 		}
-	case 153:
+	case 150:
 		yyDollar = yyS[yypt-2 : yypt+1]
+//line promql/parser/generated_parser.y:748
 		{
 			m := yylex.(*parser).newMap()
 			yyVAL.histogram = yylex.(*parser).buildHistogramFromMap(&m)
 		}
-	case 154:
+	case 151:
 		yyDollar = yyS[yypt-3 : yypt+1]
+//line promql/parser/generated_parser.y:756
 		{
 			yyVAL.descriptors = *(yylex.(*parser).mergeMaps(&yyDollar[1].descriptors, &yyDollar[3].descriptors))
 		}
-	case 155:
+	case 152:
 		yyDollar = yyS[yypt-1 : yypt+1]
+//line promql/parser/generated_parser.y:760
 		{
 			yyVAL.descriptors = yyDollar[1].descriptors
 		}
-	case 156:
+	case 153:
 		yyDollar = yyS[yypt-2 : yypt+1]
+//line promql/parser/generated_parser.y:763
 		{
 			yylex.(*parser).unexpected("histogram description", "histogram description key, e.g. buckets:[5 10 7]")
 		}
-	case 157:
+	case 154:
 		yyDollar = yyS[yypt-3 : yypt+1]
+//line promql/parser/generated_parser.y:770
 		{
 			yyVAL.descriptors = yylex.(*parser).newMap()
 			yyVAL.descriptors["schema"] = yyDollar[3].int
 		}
-	case 158:
+	case 155:
 		yyDollar = yyS[yypt-3 : yypt+1]
+//line promql/parser/generated_parser.y:775
 		{
 			yyVAL.descriptors = yylex.(*parser).newMap()
 			yyVAL.descriptors["sum"] = yyDollar[3].float
 		}
-	case 159:
+	case 156:
 		yyDollar = yyS[yypt-3 : yypt+1]
+//line promql/parser/generated_parser.y:780
 		{
 			yyVAL.descriptors = yylex.(*parser).newMap()
 			yyVAL.descriptors["count"] = yyDollar[3].float
 		}
-	case 160:
+	case 157:
 		yyDollar = yyS[yypt-3 : yypt+1]
+//line promql/parser/generated_parser.y:785
 		{
 			yyVAL.descriptors = yylex.(*parser).newMap()
 			yyVAL.descriptors["z_bucket"] = yyDollar[3].float
 		}
-	case 161:
+	case 158:
 		yyDollar = yyS[yypt-3 : yypt+1]
+//line promql/parser/generated_parser.y:790
 		{
 			yyVAL.descriptors = yylex.(*parser).newMap()
 			yyVAL.descriptors["z_bucket_w"] = yyDollar[3].float
 		}
-	case 162:
+	case 159:
 		yyDollar = yyS[yypt-3 : yypt+1]
+//line promql/parser/generated_parser.y:795
 		{
 			yyVAL.descriptors = yylex.(*parser).newMap()
 			yyVAL.descriptors["buckets"] = yyDollar[3].bucket_set
 		}
-	case 163:
+	case 160:
 		yyDollar = yyS[yypt-3 : yypt+1]
+//line promql/parser/generated_parser.y:800
 		{
 			yyVAL.descriptors = yylex.(*parser).newMap()
 			yyVAL.descriptors["offset"] = yyDollar[3].int
 		}
-	case 164:
+	case 161:
 		yyDollar = yyS[yypt-3 : yypt+1]
+//line promql/parser/generated_parser.y:805
 		{
 			yyVAL.descriptors = yylex.(*parser).newMap()
 			yyVAL.descriptors["n_buckets"] = yyDollar[3].bucket_set
 		}
-	case 165:
+	case 162:
 		yyDollar = yyS[yypt-3 : yypt+1]
+//line promql/parser/generated_parser.y:810
 		{
 			yyVAL.descriptors = yylex.(*parser).newMap()
 			yyVAL.descriptors["n_offset"] = yyDollar[3].int
 		}
-	case 166:
+	case 163:
 		yyDollar = yyS[yypt-4 : yypt+1]
+//line promql/parser/generated_parser.y:817
 		{
 			yyVAL.bucket_set = yyDollar[2].bucket_set
 		}
-	case 167:
+	case 164:
 		yyDollar = yyS[yypt-3 : yypt+1]
+//line promql/parser/generated_parser.y:821
 		{
 			yyVAL.bucket_set = yyDollar[2].bucket_set
 		}
-	case 168:
+	case 165:
 		yyDollar = yyS[yypt-3 : yypt+1]
+//line promql/parser/generated_parser.y:827
 		{
 			yyVAL.bucket_set = append(yyDollar[1].bucket_set, yyDollar[3].float)
 		}
-	case 169:
+	case 166:
 		yyDollar = yyS[yypt-1 : yypt+1]
+//line promql/parser/generated_parser.y:831
 		{
 			yyVAL.bucket_set = []float64{yyDollar[1].float}
 		}
-	case 216:
+	case 213:
 		yyDollar = yyS[yypt-1 : yypt+1]
+//line promql/parser/generated_parser.y:856
 		{
 			yyVAL.node = &NumberLiteral{
 				Val:      yylex.(*parser).number(yyDollar[1].item.Val),
 				PosRange: yyDollar[1].item.PositionRange(),
 			}
 		}
-	case 217:
+	case 214:
 		yyDollar = yyS[yypt-1 : yypt+1]
+//line promql/parser/generated_parser.y:864
 		{
 			yyVAL.float = yylex.(*parser).number(yyDollar[1].item.Val)
 		}
-	case 218:
+	case 215:
 		yyDollar = yyS[yypt-2 : yypt+1]
+//line promql/parser/generated_parser.y:866
 		{
 			yyVAL.float = yyDollar[2].float
 		}
-	case 219:
+	case 216:
 		yyDollar = yyS[yypt-2 : yypt+1]
+//line promql/parser/generated_parser.y:867
 		{
 			yyVAL.float = -yyDollar[2].float
 		}
-	case 222:
+	case 219:
 		yyDollar = yyS[yypt-1 : yypt+1]
+//line promql/parser/generated_parser.y:873
 		{
 			var err error
 			yyVAL.uint, err = strconv.ParseUint(yyDollar[1].item.Val, 10, 64)
@@ -1810,18 +1928,21 @@ yydefault:
 				yylex.(*parser).addParseErrf(yyDollar[1].item.PositionRange(), "invalid repetition in series values: %s", err)
 			}
 		}
-	case 223:
+	case 220:
 		yyDollar = yyS[yypt-2 : yypt+1]
+//line promql/parser/generated_parser.y:882
 		{
 			yyVAL.int = -int64(yyDollar[2].uint)
 		}
-	case 224:
+	case 221:
 		yyDollar = yyS[yypt-1 : yypt+1]
+//line promql/parser/generated_parser.y:883
 		{
 			yyVAL.int = int64(yyDollar[1].uint)
 		}
-	case 225:
+	case 222:
 		yyDollar = yyS[yypt-1 : yypt+1]
+//line promql/parser/generated_parser.y:887
 		{
 			var err error
 			yyVAL.duration, err = parseDuration(yyDollar[1].item.Val)
@@ -1829,30 +1950,24 @@ yydefault:
 				yylex.(*parser).addParseErr(yyDollar[1].item.PositionRange(), err)
 			}
 		}
-	case 226:
+	case 223:
 		yyDollar = yyS[yypt-1 : yypt+1]
+//line promql/parser/generated_parser.y:898
 		{
 			yyVAL.node = &StringLiteral{
 				Val:      yylex.(*parser).unquoteString(yyDollar[1].item.Val),
 				PosRange: yyDollar[1].item.PositionRange(),
 			}
 		}
-	case 227:
-		yyDollar = yyS[yypt-1 : yypt+1]
-		{
-			yyVAL.item = Item{
-				Typ: METRIC_IDENTIFIER,
-				Pos: yyDollar[1].item.PositionRange().Start,
-				Val: yylex.(*parser).unquoteString(yyDollar[1].item.Val),
-			}
-		}
-	case 228:
+	case 224:
 		yyDollar = yyS[yypt-0 : yypt+1]
+//line promql/parser/generated_parser.y:911
 		{
 			yyVAL.duration = 0
 		}
-	case 230:
+	case 226:
 		yyDollar = yyS[yypt-0 : yypt+1]
+//line promql/parser/generated_parser.y:915
 		{
 			yyVAL.strings = nil
 		}
diff --git a/promql/parser/parse.go b/promql/parser/parse.go
index 6a05e4a79..c2a42ed15 100644
--- a/promql/parser/parse.go
+++ b/promql/parser/parse.go
@@ -417,8 +417,6 @@ func (p *parser) newBinaryExpression(lhs Node, op Item, modifiers, rhs Node) *Bi
 }
 
 func (p *parser) assembleVectorSelector(vs *VectorSelector) {
-	// If the metric name was set outside the braces, add a matcher for it.
-	// If the metric name was inside the braces we don't need to do anything.
 	if vs.Name != "" {
 		nameMatcher, err := labels.NewMatcher(labels.MatchEqual, labels.MetricName, vs.Name)
 		if err != nil {
@@ -791,18 +789,6 @@ func (p *parser) checkAST(node Node) (typ ValueType) {
 			// Skip the check for non-empty matchers because an explicit
 			// metric name is a non-empty matcher.
 			break
-		} else {
-			// We also have to make sure a metric name was not set twice inside the
-			// braces.
-			foundMetricName := ""
-			for _, m := range n.LabelMatchers {
-				if m != nil && m.Name == labels.MetricName {
-					if foundMetricName != "" {
-						p.addParseErrf(n.PositionRange(), "metric name must not be set twice: %q or %q", foundMetricName, m.Value)
-					}
-					foundMetricName = m.Value
-				}
-			}
 		}
 
 		// A Vector selector must contain at least one non-empty matcher to prevent
@@ -886,15 +872,6 @@ func (p *parser) newLabelMatcher(label, operator, value Item) *labels.Matcher {
 	return m
 }
 
-func (p *parser) newMetricNameMatcher(value Item) *labels.Matcher {
-	m, err := labels.NewMatcher(labels.MatchEqual, labels.MetricName, value.Val)
-	if err != nil {
-		p.addParseErr(value.PositionRange(), err)
-	}
-
-	return m
-}
-
 // addOffset is used to set the offset in the generated parser.
 func (p *parser) addOffset(e Node, offset time.Duration) {
 	var orgoffsetp *time.Duration
diff --git a/storage/remote/write_handler.go b/storage/remote/write_handler.go
index 783cbde82..971f7b457 100644
--- a/storage/remote/write_handler.go
+++ b/storage/remote/write_handler.go
@@ -81,7 +81,7 @@ func (h *writeHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 	w.WriteHeader(http.StatusNoContent)
 }
 
-// checkAppendExemplarError modifies the AppendExemplar's returned error based on the error cause.
+// checkAppendExemplarError modifies the AppendExamplar's returned error based on the error cause.
 func (h *writeHandler) checkAppendExemplarError(err error, e exemplar.Exemplar, outOfOrderErrs *int) error {
 	unwrappedErr := errors.Unwrap(err)
 	if unwrappedErr == nil {
diff --git a/web/federate.go b/web/federate.go
index e0bfc6ee2..62e8c97b7 100644
--- a/web/federate.go
+++ b/web/federate.go
@@ -189,9 +189,8 @@ Loop:
 	)
 	for _, s := range vec {
 		isHistogram := s.H != nil
-		formatType := format.FormatType()
 		if isHistogram &&
-			formatType != expfmt.TypeProtoDelim && formatType != expfmt.TypeProtoText && formatType != expfmt.TypeProtoCompact {
+			format != expfmt.FmtProtoDelim && format != expfmt.FmtProtoText && format != expfmt.FmtProtoCompact {
 			// Can't serve the native histogram.
 			// TODO(codesome): Serve them when other protocols get the native histogram support.
 			continue


Test patch:
diff --git a/discovery/kubernetes/endpointslice_test.go b/discovery/kubernetes/endpointslice_test.go
index f23c9e655..a6579b954 100644
--- a/discovery/kubernetes/endpointslice_test.go
+++ b/discovery/kubernetes/endpointslice_test.go
@@ -18,6 +18,7 @@ import (
 	"testing"
 
 	"github.com/prometheus/common/model"
+	"github.com/stretchr/testify/require"
 	corev1 "k8s.io/api/core/v1"
 	v1 "k8s.io/api/discovery/v1"
 	"k8s.io/api/discovery/v1beta1"
@@ -1405,3 +1406,41 @@ func TestEndpointSliceDiscoveryEmptyPodStatus(t *testing.T) {
 		expectedRes:      map[string]*targetgroup.Group{},
 	}.Run(t)
 }
+
+// TestEndpointSliceInfIndexersCount makes sure that RoleEndpointSlice discovery
+// sets up indexing for the main Kube informer only when needed.
+// See: https://github.com/prometheus/prometheus/pull/13554#discussion_r1490965817
+func TestEndpointSliceInfIndexersCount(t *testing.T) {
+	tests := []struct {
+		name             string
+		withNodeMetadata bool
+	}{
+		{"with node metadata", true},
+		{"without node metadata", false},
+	}
+
+	for _, tc := range tests {
+		t.Run(tc.name, func(t *testing.T) {
+			var (
+				n                    *Discovery
+				mainInfIndexersCount int
+			)
+			if tc.withNodeMetadata {
+				mainInfIndexersCount = 1
+				n, _ = makeDiscoveryWithMetadata(RoleEndpointSlice, NamespaceDiscovery{}, AttachMetadataConfig{Node: true})
+			} else {
+				n, _ = makeDiscovery(RoleEndpointSlice, NamespaceDiscovery{})
+			}
+
+			k8sDiscoveryTest{
+				discovery: n,
+				afterStart: func() {
+					n.RLock()
+					defer n.RUnlock()
+					require.Len(t, n.discoverers, 1)
+					require.Len(t, n.discoverers[0].(*EndpointSlice).endpointSliceInf.GetIndexer().GetIndexers(), mainInfIndexersCount)
+				},
+			}.Run(t)
+		})
+	}
+}
diff --git a/discovery/kubernetes/kubernetes_test.go b/discovery/kubernetes/kubernetes_test.go
index f1f8070e8..e3dd09300 100644
--- a/discovery/kubernetes/kubernetes_test.go
+++ b/discovery/kubernetes/kubernetes_test.go
@@ -128,7 +128,7 @@ func (d k8sDiscoveryTest) Run(t *testing.T) {
 	}
 
 	resChan := make(chan map[string]*targetgroup.Group)
-	go readResultWithTimeout(t, ch, d.expectedMaxItems, time.Second, resChan)
+	go readResultWithTimeout(t, ctx, ch, d.expectedMaxItems, time.Second, resChan)
 
 	dd, ok := d.discovery.(hasSynced)
 	require.True(t, ok, "discoverer does not implement hasSynced interface")
@@ -141,13 +141,18 @@ func (d k8sDiscoveryTest) Run(t *testing.T) {
 	if d.expectedRes != nil {
 		res := <-resChan
 		requireTargetGroups(t, d.expectedRes, res)
+	} else {
+		// Stop readResultWithTimeout and wait for it.
+		cancel()
+		<-resChan
 	}
 }
 
 // readResultWithTimeout reads all targetgroups from channel with timeout.
 // It merges targetgroups by source and sends the result to result channel.
-func readResultWithTimeout(t *testing.T, ch <-chan []*targetgroup.Group, max int, timeout time.Duration, resChan chan<- map[string]*targetgroup.Group) {
+func readResultWithTimeout(t *testing.T, ctx context.Context, ch <-chan []*targetgroup.Group, max int, stopAfter time.Duration, resChan chan<- map[string]*targetgroup.Group) {
 	res := make(map[string]*targetgroup.Group)
+	timeout := time.After(stopAfter)
 Loop:
 	for {
 		select {
@@ -162,12 +167,15 @@ Loop:
 				// Reached max target groups we may get, break fast.
 				break Loop
 			}
-		case <-time.After(timeout):
+		case <-timeout:
 			// Because we use queue, an object that is created then
 			// deleted or updated may be processed only once.
 			// So possibly we may skip events, timed out here.
 			t.Logf("timed out, got %d (max: %d) items, some events are skipped", len(res), max)
 			break Loop
+		case <-ctx.Done():
+			t.Logf("stopped, got %d (max: %d) items", len(res), max)
+			break Loop
 		}
 	}
 
diff --git a/model/textparse/openmetricsparse_test.go b/model/textparse/openmetricsparse_test.go
index d128761e3..29f31664f 100644
--- a/model/textparse/openmetricsparse_test.go
+++ b/model/textparse/openmetricsparse_test.go
@@ -301,137 +301,6 @@ foo_total 17.0 1520879607.789 # {id="counter-test"} 5`
 	require.Len(t, exp, i)
 }
 
-func TestUTF8OpenMetricsParse(t *testing.T) {
-	oldValidationScheme := model.NameValidationScheme
-	model.NameValidationScheme = model.UTF8Validation
-	defer func() {
-		model.NameValidationScheme = oldValidationScheme
-	}()
-
-	input := `# HELP "go.gc_duration_seconds" A summary of the GC invocation durations.
-# TYPE "go.gc_duration_seconds" summary
-# UNIT "go.gc_duration_seconds" seconds
-{"go.gc_duration_seconds",quantile="0"} 4.9351e-05
-{"go.gc_duration_seconds",quantile="0.25"} 7.424100000000001e-05
-{"go.gc_duration_seconds",quantile="0.5",a="b"} 8.3835e-05
-{"http.status",q="0.9",a="b"} 8.3835e-05
-{"http.status",q="0.9",a="b"} 8.3835e-05
-{q="0.9","http.status",a="b"} 8.3835e-05
-{"go.gc_duration_seconds_sum"} 0.004304266
-{"Heizölrückstoßabdämpfung 10€ metric with \"interesting\" {character\nchoices}","strange©™\n'quoted' \"name\""="6"} 10.0`
-
-	input += "\n# EOF\n"
-
-	exp := []struct {
-		lset    labels.Labels
-		m       string
-		t       *int64
-		v       float64
-		typ     model.MetricType
-		help    string
-		unit    string
-		comment string
-		e       *exemplar.Exemplar
-	}{
-		{
-			m:    "go.gc_duration_seconds",
-			help: "A summary of the GC invocation durations.",
-		}, {
-			m:   "go.gc_duration_seconds",
-			typ: model.MetricTypeSummary,
-		}, {
-			m:    "go.gc_duration_seconds",
-			unit: "seconds",
-		}, {
-			m:    `{"go.gc_duration_seconds",quantile="0"}`,
-			v:    4.9351e-05,
-			lset: labels.FromStrings("__name__", "go.gc_duration_seconds", "quantile", "0"),
-		}, {
-			m:    `{"go.gc_duration_seconds",quantile="0.25"}`,
-			v:    7.424100000000001e-05,
-			lset: labels.FromStrings("__name__", "go.gc_duration_seconds", "quantile", "0.25"),
-		}, {
-			m:    `{"go.gc_duration_seconds",quantile="0.5",a="b"}`,
-			v:    8.3835e-05,
-			lset: labels.FromStrings("__name__", "go.gc_duration_seconds", "quantile", "0.5", "a", "b"),
-		}, {
-			m:    `{"http.status",q="0.9",a="b"}`,
-			v:    8.3835e-05,
-			lset: labels.FromStrings("__name__", "http.status", "q", "0.9", "a", "b"),
-		}, {
-			m:    `{"http.status",q="0.9",a="b"}`,
-			v:    8.3835e-05,
-			lset: labels.FromStrings("__name__", "http.status", "q", "0.9", "a", "b"),
-		}, {
-			m:    `{q="0.9","http.status",a="b"}`,
-			v:    8.3835e-05,
-			lset: labels.FromStrings("__name__", "http.status", "q", "0.9", "a", "b"),
-		}, {
-			m:    `{"go.gc_duration_seconds_sum"}`,
-			v:    0.004304266,
-			lset: labels.FromStrings("__name__", "go.gc_duration_seconds_sum"),
-		}, {
-			m: `{"Heizölrückstoßabdämpfung 10€ metric with \"interesting\" {character\nchoices}","strange©™\n'quoted' \"name\""="6"}`,
-			v: 10.0,
-			lset: labels.FromStrings("__name__", `Heizölrückstoßabdämpfung 10€ metric with "interesting" {character
-choices}`, "strange©™\n'quoted' \"name\"", "6"),
-		},
-	}
-
-	p := NewOpenMetricsParser([]byte(input))
-	i := 0
-
-	var res labels.Labels
-
-	for {
-		et, err := p.Next()
-		if errors.Is(err, io.EOF) {
-			break
-		}
-		require.NoError(t, err)
-
-		switch et {
-		case EntrySeries:
-			m, ts, v := p.Series()
-
-			var e exemplar.Exemplar
-			p.Metric(&res)
-			found := p.Exemplar(&e)
-			require.Equal(t, exp[i].m, string(m))
-			require.Equal(t, exp[i].t, ts)
-			require.Equal(t, exp[i].v, v)
-			require.Equal(t, exp[i].lset, res)
-			if exp[i].e == nil {
-				require.False(t, found)
-			} else {
-				require.True(t, found)
-				require.Equal(t, *exp[i].e, e)
-			}
-
-		case EntryType:
-			m, typ := p.Type()
-			require.Equal(t, exp[i].m, string(m))
-			require.Equal(t, exp[i].typ, typ)
-
-		case EntryHelp:
-			m, h := p.Help()
-			require.Equal(t, exp[i].m, string(m))
-			require.Equal(t, exp[i].help, string(h))
-
-		case EntryUnit:
-			m, u := p.Unit()
-			require.Equal(t, exp[i].m, string(m))
-			require.Equal(t, exp[i].unit, string(u))
-
-		case EntryComment:
-			require.Equal(t, exp[i].comment, string(p.Comment()))
-		}
-
-		i++
-	}
-	require.Len(t, exp, i)
-}
-
 func TestOpenMetricsParseErrors(t *testing.T) {
 	cases := []struct {
 		input string
@@ -588,13 +457,17 @@ func TestOpenMetricsParseErrors(t *testing.T) {
 			input: "a{b='c'} 1\n# EOF\n",
 			err:   "expected label value, got \"'\" (\"INVALID\") while parsing: \"a{b='\"",
 		},
+		{
+			input: "a{b=\"c\",} 1\n# EOF\n",
+			err:   "expected label name, got \"} \" (\"BCLOSE\") while parsing: \"a{b=\\\"c\\\",} \"",
+		},
 		{
 			input: "a{,b=\"c\"} 1\n# EOF\n",
-			err:   "expected label name, got \",b\" (\"COMMA\") while parsing: \"a{,b\"",
+			err:   "expected label name or left brace, got \",b\" (\"COMMA\") while parsing: \"a{,b\"",
 		},
 		{
 			input: "a{b=\"c\"d=\"e\"} 1\n# EOF\n",
-			err:   "expected comma or brace close, got \"d=\" (\"LNAME\") while parsing: \"a{b=\\\"c\\\"d=\"",
+			err:   "expected comma, got \"d=\" (\"LNAME\") while parsing: \"a{b=\\\"c\\\"d=\"",
 		},
 		{
 			input: "a{b=\"c\",,d=\"e\"} 1\n# EOF\n",
@@ -606,24 +479,12 @@ func TestOpenMetricsParseErrors(t *testing.T) {
 		},
 		{
 			input: "a{\xff=\"foo\"} 1\n# EOF\n",
-			err:   "expected label name, got \"\\xff\" (\"INVALID\") while parsing: \"a{\\xff\"",
+			err:   "expected label name or left brace, got \"\\xff\" (\"INVALID\") while parsing: \"a{\\xff\"",
 		},
 		{
 			input: "a{b=\"\xff\"} 1\n# EOF\n",
 			err:   "invalid UTF-8 label value: \"\\\"\\xff\\\"\"",
 		},
-		{
-			input: `{"a","b = "c"}
-# EOF
-`,
-			err: "expected equal, got \"c\\\"\" (\"LNAME\") while parsing: \"{\\\"a\\\",\\\"b = \\\"c\\\"\"",
-		},
-		{
-			input: `{"a",b\nc="d"} 1
-# EOF
-`,
-			err: "expected equal, got \"\\\\\" (\"INVALID\") while parsing: \"{\\\"a\\\",b\\\\\"",
-		},
 		{
 			input: "a true\n",
 			err:   "strconv.ParseFloat: parsing \"true\": invalid syntax while parsing: \"a true\"",
@@ -634,7 +495,7 @@ func TestOpenMetricsParseErrors(t *testing.T) {
 		},
 		{
 			input: "empty_label_name{=\"\"} 0\n# EOF\n",
-			err:   "expected label name, got \"=\\\"\" (\"EQUAL\") while parsing: \"empty_label_name{=\\\"\"",
+			err:   "expected label name or left brace, got \"=\\\"\" (\"EQUAL\") while parsing: \"empty_label_name{=\\\"\"",
 		},
 		{
 			input: "foo 1_2\n\n# EOF\n",
@@ -664,14 +525,6 @@ func TestOpenMetricsParseErrors(t *testing.T) {
 			input: `custom_metric_total 1 # {aa="bb"}`,
 			err:   "expected value after exemplar labels, got \"}\" (\"EOF\") while parsing: \"custom_metric_total 1 # {aa=\\\"bb\\\"}\"",
 		},
-		{
-			input: `custom_metric_total 1 # {bb}`,
-			err:   "expected label name, got \"}\" (\"BCLOSE\") while parsing: \"custom_metric_total 1 # {bb}\"",
-		},
-		{
-			input: `custom_metric_total 1 # {bb, a="dd"}`,
-			err:   "expected label name, got \", \" (\"COMMA\") while parsing: \"custom_metric_total 1 # {bb, \"",
-		},
 		{
 			input: `custom_metric_total 1 # {aa="bb",,cc="dd"} 1`,
 			err:   "expected label name, got \",c\" (\"COMMA\") while parsing: \"custom_metric_total 1 # {aa=\\\"bb\\\",,c\"",
@@ -698,7 +551,7 @@ func TestOpenMetricsParseErrors(t *testing.T) {
 		},
 		{
 			input: `{b="c",} 1`,
-			err:   "metric name not set while parsing: \"{b=\\\"c\\\",} 1\"",
+			err:   "expected a valid start token, got \"{\" (\"INVALID\") while parsing: \"{\"",
 		},
 		{
 			input: `a 1 NaN`,
diff --git a/model/textparse/promparse_test.go b/model/textparse/promparse_test.go
index d82bfe598..ccd7ef9cc 100644
--- a/model/textparse/promparse_test.go
+++ b/model/textparse/promparse_test.go
@@ -48,7 +48,6 @@ go_gc_duration_seconds{ quantile="1.0", a="b" } 8.3835e-05
 go_gc_duration_seconds { quantile="1.0", a="b" } 8.3835e-05
 go_gc_duration_seconds { quantile= "1.0", a= "b", } 8.3835e-05
 go_gc_duration_seconds { quantile = "1.0", a = "b" } 8.3835e-05
-go_gc_duration_seconds { quantile = "2.0" a = "b" } 8.3835e-05
 go_gc_duration_seconds_count 99
 some:aggregate:rate5m{a_b="c"}	1
 # HELP go_goroutines Number of goroutines that currently exist.
@@ -131,11 +130,6 @@ testmetric{label="\"bar\""} 1`
 			m:    `go_gc_duration_seconds { quantile = "1.0", a = "b" }`,
 			v:    8.3835e-05,
 			lset: labels.FromStrings("__name__", "go_gc_duration_seconds", "quantile", "1.0", "a", "b"),
-		}, {
-			// NOTE: Unlike OpenMetrics, Promparse allows spaces between label terms. This appears to be unintended and should probably be fixed.
-			m:    `go_gc_duration_seconds { quantile = "2.0" a = "b" }`,
-			v:    8.3835e-05,
-			lset: labels.FromStrings("__name__", "go_gc_duration_seconds", "quantile", "2.0", "a", "b"),
 		}, {
 			m:    `go_gc_duration_seconds_count`,
 			v:    99,
@@ -219,132 +213,6 @@ testmetric{label="\"bar\""} 1`
 	require.Len(t, exp, i)
 }
 
-func TestUTF8PromParse(t *testing.T) {
-	oldValidationScheme := model.NameValidationScheme
-	model.NameValidationScheme = model.UTF8Validation
-	defer func() {
-		model.NameValidationScheme = oldValidationScheme
-	}()
-
-	input := `# HELP "go.gc_duration_seconds" A summary of the GC invocation durations.
-# 	TYPE "go.gc_duration_seconds" summary
-{"go.gc_duration_seconds",quantile="0"} 4.9351e-05
-{"go.gc_duration_seconds",quantile="0.25",} 7.424100000000001e-05
-{"go.gc_duration_seconds",quantile="0.5",a="b"} 8.3835e-05
-{"go.gc_duration_seconds",quantile="0.8", a="b"} 8.3835e-05
-{"go.gc_duration_seconds", quantile="0.9", a="b"} 8.3835e-05
-{"go.gc_duration_seconds", quantile="1.0", a="b" } 8.3835e-05
-{ "go.gc_duration_seconds", quantile="1.0", a="b" } 8.3835e-05
-{ "go.gc_duration_seconds", quantile= "1.0", a= "b", } 8.3835e-05
-{ "go.gc_duration_seconds", quantile = "1.0", a = "b" } 8.3835e-05
-{"go.gc_duration_seconds_count"} 99
-{"Heizölrückstoßabdämpfung 10€ metric with \"interesting\" {character\nchoices}","strange©™\n'quoted' \"name\""="6"} 10.0`
-
-	exp := []struct {
-		lset    labels.Labels
-		m       string
-		t       *int64
-		v       float64
-		typ     model.MetricType
-		help    string
-		comment string
-	}{
-		{
-			m:    "go.gc_duration_seconds",
-			help: "A summary of the GC invocation durations.",
-		}, {
-			m:   "go.gc_duration_seconds",
-			typ: model.MetricTypeSummary,
-		}, {
-			m:    `{"go.gc_duration_seconds",quantile="0"}`,
-			v:    4.9351e-05,
-			lset: labels.FromStrings("__name__", "go.gc_duration_seconds", "quantile", "0"),
-		}, {
-			m:    `{"go.gc_duration_seconds",quantile="0.25",}`,
-			v:    7.424100000000001e-05,
-			lset: labels.FromStrings("__name__", "go.gc_duration_seconds", "quantile", "0.25"),
-		}, {
-			m:    `{"go.gc_duration_seconds",quantile="0.5",a="b"}`,
-			v:    8.3835e-05,
-			lset: labels.FromStrings("__name__", "go.gc_duration_seconds", "quantile", "0.5", "a", "b"),
-		}, {
-			m:    `{"go.gc_duration_seconds",quantile="0.8", a="b"}`,
-			v:    8.3835e-05,
-			lset: labels.FromStrings("__name__", "go.gc_duration_seconds", "quantile", "0.8", "a", "b"),
-		}, {
-			m:    `{"go.gc_duration_seconds", quantile="0.9", a="b"}`,
-			v:    8.3835e-05,
-			lset: labels.FromStrings("__name__", "go.gc_duration_seconds", "quantile", "0.9", "a", "b"),
-		}, {
-			m:    `{"go.gc_duration_seconds", quantile="1.0", a="b" }`,
-			v:    8.3835e-05,
-			lset: labels.FromStrings("__name__", "go.gc_duration_seconds", "quantile", "1.0", "a", "b"),
-		}, {
-			m:    `{ "go.gc_duration_seconds", quantile="1.0", a="b" }`,
-			v:    8.3835e-05,
-			lset: labels.FromStrings("__name__", "go.gc_duration_seconds", "quantile", "1.0", "a", "b"),
-		}, {
-			m:    `{ "go.gc_duration_seconds", quantile= "1.0", a= "b", }`,
-			v:    8.3835e-05,
-			lset: labels.FromStrings("__name__", "go.gc_duration_seconds", "quantile", "1.0", "a", "b"),
-		}, {
-			m:    `{ "go.gc_duration_seconds", quantile = "1.0", a = "b" }`,
-			v:    8.3835e-05,
-			lset: labels.FromStrings("__name__", "go.gc_duration_seconds", "quantile", "1.0", "a", "b"),
-		}, {
-			m:    `{"go.gc_duration_seconds_count"}`,
-			v:    99,
-			lset: labels.FromStrings("__name__", "go.gc_duration_seconds_count"),
-		}, {
-			m: `{"Heizölrückstoßabdämpfung 10€ metric with \"interesting\" {character\nchoices}","strange©™\n'quoted' \"name\""="6"}`,
-			v: 10.0,
-			lset: labels.FromStrings("__name__", `Heizölrückstoßabdämpfung 10€ metric with "interesting" {character
-choices}`, "strange©™\n'quoted' \"name\"", "6"),
-		},
-	}
-
-	p := NewPromParser([]byte(input))
-	i := 0
-
-	var res labels.Labels
-
-	for {
-		et, err := p.Next()
-		if errors.Is(err, io.EOF) {
-			break
-		}
-		require.NoError(t, err)
-
-		switch et {
-		case EntrySeries:
-			m, ts, v := p.Series()
-
-			p.Metric(&res)
-
-			require.Equal(t, exp[i].m, string(m))
-			require.Equal(t, exp[i].t, ts)
-			require.Equal(t, exp[i].v, v)
-			require.Equal(t, exp[i].lset, res)
-
-		case EntryType:
-			m, typ := p.Type()
-			require.Equal(t, exp[i].m, string(m))
-			require.Equal(t, exp[i].typ, typ)
-
-		case EntryHelp:
-			m, h := p.Help()
-			require.Equal(t, exp[i].m, string(m))
-			require.Equal(t, exp[i].help, string(h))
-
-		case EntryComment:
-			require.Equal(t, exp[i].comment, string(p.Comment()))
-		}
-
-		i++
-	}
-	require.Len(t, exp, i)
-}
-
 func TestPromParseErrors(t *testing.T) {
 	cases := []struct {
 		input string
@@ -370,14 +238,6 @@ func TestPromParseErrors(t *testing.T) {
 			input: "a{b=\"\xff\"} 1\n",
 			err:   "invalid UTF-8 label value: \"\\\"\\xff\\\"\"",
 		},
-		{
-			input: `{"a", "b = "c"}`,
-			err:   "expected equal, got \"c\\\"\" (\"LNAME\") while parsing: \"{\\\"a\\\", \\\"b = \\\"c\\\"\"",
-		},
-		{
-			input: `{"a",b\nc="d"} 1`,
-			err:   "expected equal, got \"\\\\\" (\"INVALID\") while parsing: \"{\\\"a\\\",b\\\\\"",
-		},
 		{
 			input: "a true\n",
 			err:   "strconv.ParseFloat: parsing \"true\": invalid syntax while parsing: \"a true\"",
@@ -408,7 +268,7 @@ func TestPromParseErrors(t *testing.T) {
 		},
 		{
 			input: `{a="ok"} 1`,
-			err:   "metric name not set while parsing: \"{a=\\\"ok\\\"} 1\"",
+			err:   "expected a valid start token, got \"{\" (\"INVALID\") while parsing: \"{\"",
 		},
 		{
 			input: "# TYPE #\n#EOF\n",
diff --git a/promql/parser/parse_test.go b/promql/parser/parse_test.go
index 2d5f59da0..fbf9672f3 100644
--- a/promql/parser/parse_test.go
+++ b/promql/parser/parse_test.go
@@ -474,22 +474,6 @@ var testExpr = []struct {
 			StartPos: 1,
 		},
 	},
-	{
-		input: ` +{"some_metric"}`,
-		expected: &UnaryExpr{
-			Op: ADD,
-			Expr: &VectorSelector{
-				LabelMatchers: []*labels.Matcher{
-					MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "some_metric"),
-				},
-				PosRange: posrange.PositionRange{
-					Start: 2,
-					End:   17,
-				},
-			},
-			StartPos: 1,
-		},
-	},
 	{
 		input:  "",
 		fail:   true,
@@ -1718,33 +1702,6 @@ var testExpr = []struct {
 			},
 		},
 	},
-	{
-		input: `{"foo"}`,
-		expected: &VectorSelector{
-			// When a metric is named inside the braces, the Name field is not set.
-			LabelMatchers: []*labels.Matcher{
-				MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"),
-			},
-			PosRange: posrange.PositionRange{
-				Start: 0,
-				End:   7,
-			},
-		},
-	},
-	{
-		input: `{"foo", a="bc"}`,
-		expected: &VectorSelector{
-			// When a metric is named inside the braces, the Name field is not set.
-			LabelMatchers: []*labels.Matcher{
-				MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"),
-				MustLabelMatcher(labels.MatchEqual, "a", "bc"),
-			},
-			PosRange: posrange.PositionRange{
-				Start: 0,
-				End:   15,
-			},
-		},
-	},
 	{
 		input: `foo{NaN='bc'}`,
 		expected: &VectorSelector{
@@ -1790,23 +1747,6 @@ var testExpr = []struct {
 			},
 		},
 	},
-	{
-		// Metric name in the middle of selector list is fine.
-		input: `{a="b", foo!="bar", "foo", test=~"test", bar!~"baz"}`,
-		expected: &VectorSelector{
-			LabelMatchers: []*labels.Matcher{
-				MustLabelMatcher(labels.MatchEqual, "a", "b"),
-				MustLabelMatcher(labels.MatchNotEqual, "foo", "bar"),
-				MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"),
-				MustLabelMatcher(labels.MatchRegexp, "test", "test"),
-				MustLabelMatcher(labels.MatchNotRegexp, "bar", "baz"),
-			},
-			PosRange: posrange.PositionRange{
-				Start: 0,
-				End:   52,
-			},
-		},
-	},
 	{
 		input: `foo{a="b", foo!="bar", test=~"test", bar!~"baz",}`,
 		expected: &VectorSelector{
@@ -1931,11 +1871,6 @@ var testExpr = []struct {
 		fail:   true,
 		errMsg: `unexpected identifier "lol" in label matching, expected "," or "}"`,
 	},
-	{
-		input:  `foo{"a"=}`,
-		fail:   true,
-		errMsg: `unexpected "}" in label matching, expected string`,
-	},
 	// Test matrix selector.
 	{
 		input: "test[5s]",
diff --git a/scrape/scrape_test.go b/scrape/scrape_test.go
index badeee2d1..c95ca3741 100644
--- a/scrape/scrape_test.go
+++ b/scrape/scrape_test.go
@@ -1332,7 +1332,7 @@ func TestScrapeLoopAppend(t *testing.T) {
 			// Honor Labels should ignore labels with the same name.
 			title:           "Honor Labels",
 			honorLabels:     true,
-			scrapeLabels:    `metric{n1="1", n2="2"} 0`,
+			scrapeLabels:    `metric{n1="1" n2="2"} 0`,
 			discoveryLabels: []string{"n1", "0"},
 			expLset:         labels.FromStrings("__name__", "metric", "n1", "1", "n2", "2"),
 			expValue:        0,
@@ -1406,7 +1406,7 @@ func TestScrapeLoopAppendForConflictingPrefixedLabels(t *testing.T) {
 		},
 		"One target label collides with existing label, plus existing label already with prefix 'exported": {
 			targetLabels:  []string{"foo", "3"},
-			exposedLabels: `metric{foo="1", exported_foo="2"} 0`,
+			exposedLabels: `metric{foo="1" exported_foo="2"} 0`,
 			expected:      []string{"__name__", "metric", "exported_exported_foo", "1", "exported_foo", "2", "foo", "3"},
 		},
 		"One target label collides with existing label, both already with prefix 'exported'": {
@@ -1416,7 +1416,7 @@ func TestScrapeLoopAppendForConflictingPrefixedLabels(t *testing.T) {
 		},
 		"Two target labels collide with existing labels, both with and without prefix 'exported'": {
 			targetLabels:  []string{"foo", "3", "exported_foo", "4"},
-			exposedLabels: `metric{foo="1", exported_foo="2"} 0`,
+			exposedLabels: `metric{foo="1" exported_foo="2"} 0`,
 			expected: []string{
 				"__name__", "metric", "exported_exported_foo", "1", "exported_exported_exported_foo",
 				"2", "exported_foo", "4", "foo", "3",
@@ -1424,7 +1424,7 @@ func TestScrapeLoopAppendForConflictingPrefixedLabels(t *testing.T) {
 		},
 		"Extreme example": {
 			targetLabels:  []string{"foo", "0", "exported_exported_foo", "1", "exported_exported_exported_foo", "2"},
-			exposedLabels: `metric{foo="3", exported_foo="4", exported_exported_exported_foo="5"} 0`,
+			exposedLabels: `metric{foo="3" exported_foo="4" exported_exported_exported_foo="5"} 0`,
 			expected: []string{
 				"__name__", "metric",
 				"exported_exported_exported_exported_exported_foo", "5",