From 6dc36d0c3efee1d9f468632eb8d451a81c756e8b Mon Sep 17 00:00:00 2001 From: Julius Volz Date: Fri, 13 Dec 2013 19:20:42 +0100 Subject: [PATCH] Don't keep extra labels in aggregations by default. MIN/MAX/SUM/AVG/COUNT aggregations will now by default drop all labels that are not specifically part of a BY-clause, even if a label value is the same within all timeseries of an aggregation group. The old behavior of keeping extra labels may still be switched on by adding KEEPING_EXTRA to the end of an aggregation statement: sum(http_requests) by (job, method) keeping_extra I'm open to better syntax/naming suggestions. Change-Id: I21d3fe7af9e98552ce3dffa3ce7c0a4ba4c0b4a4 --- rules/ast/ast.go | 32 +- rules/helpers.go | 4 +- rules/lexer.l | 1 + rules/lexer.l.go | 1117 +++++++++++++++++++++++++++---------------- rules/parser.y | 14 +- rules/parser.y.go | 137 +++--- rules/rules_test.go | 16 + 7 files changed, 824 insertions(+), 497 deletions(-) diff --git a/rules/ast/ast.go b/rules/ast/ast.go index 3f7be901d..d72b8c04a 100644 --- a/rules/ast/ast.go +++ b/rules/ast/ast.go @@ -164,9 +164,10 @@ type ( // A vector aggregation with vector return type. VectorAggregation struct { - aggrType AggrType - groupBy clientmodel.LabelNames - vector VectorNode + aggrType AggrType + groupBy clientmodel.LabelNames + keepExtraLabels bool + vector VectorNode } // An arithmetic expression of vector type. @@ -367,7 +368,10 @@ func (node *VectorAggregation) Eval(timestamp clientmodel.Timestamp, view *viewA for _, sample := range vector { groupingKey := node.labelsToGroupingKey(sample.Metric) if groupedResult, ok := result[groupingKey]; ok { - groupedResult.labels = labelIntersection(groupedResult.labels, sample.Metric) + if node.keepExtraLabels { + groupedResult.labels = labelIntersection(groupedResult.labels, sample.Metric) + } + switch node.aggrType { case SUM: groupedResult.value += sample.Value @@ -388,8 +392,17 @@ func (node *VectorAggregation) Eval(timestamp clientmodel.Timestamp, view *viewA panic("Unknown aggregation type") } } else { + m := clientmodel.Metric{} + if node.keepExtraLabels { + m = sample.Metric + } else { + m[clientmodel.MetricNameLabel] = sample.Metric[clientmodel.MetricNameLabel] + for _, l := range node.groupBy { + m[l] = sample.Metric[l] + } + } result[groupingKey] = &groupedAggregation{ - labels: sample.Metric, + labels: m, value: sample.Value, groupCount: 1, } @@ -644,11 +657,12 @@ func NewVectorLiteral(labels clientmodel.LabelSet) *VectorLiteral { } } -func NewVectorAggregation(aggrType AggrType, vector VectorNode, groupBy clientmodel.LabelNames) *VectorAggregation { +func NewVectorAggregation(aggrType AggrType, vector VectorNode, groupBy clientmodel.LabelNames, keepExtraLabels bool) *VectorAggregation { return &VectorAggregation{ - aggrType: aggrType, - groupBy: groupBy, - vector: vector, + aggrType: aggrType, + groupBy: groupBy, + keepExtraLabels: keepExtraLabels, + vector: vector, } } diff --git a/rules/helpers.go b/rules/helpers.go index 86f3e53ea..0017378e7 100644 --- a/rules/helpers.go +++ b/rules/helpers.go @@ -54,7 +54,7 @@ func NewFunctionCall(name string, args []ast.Node) (ast.Node, error) { return functionCall, nil } -func NewVectorAggregation(aggrTypeStr string, vector ast.Node, groupBy clientmodel.LabelNames) (*ast.VectorAggregation, error) { +func NewVectorAggregation(aggrTypeStr string, vector ast.Node, groupBy clientmodel.LabelNames, keepExtraLabels bool) (*ast.VectorAggregation, error) { if _, ok := vector.(ast.VectorNode); !ok { return nil, fmt.Errorf("Operand of %v aggregation must be of vector type", aggrTypeStr) } @@ -69,7 +69,7 @@ func NewVectorAggregation(aggrTypeStr string, vector ast.Node, groupBy clientmod if !ok { return nil, fmt.Errorf("Unknown aggregation type '%v'", aggrTypeStr) } - return ast.NewVectorAggregation(aggrType, vector.(ast.VectorNode), groupBy), nil + return ast.NewVectorAggregation(aggrType, vector.(ast.VectorNode), groupBy, keepExtraLabels), nil } func NewArithExpr(opTypeStr string, lhs ast.Node, rhs ast.Node) (ast.Node, error) { diff --git a/rules/lexer.l b/rules/lexer.l index 4a22066f7..c289bd765 100644 --- a/rules/lexer.l +++ b/rules/lexer.l @@ -78,6 +78,7 @@ DESCRIPTION|description return DESCRIPTION PERMANENT|permanent return PERMANENT BY|by return GROUP_OP +KEEPING_EXTRA|keeping_extra return KEEPING_EXTRA AVG|SUM|MAX|MIN|COUNT lval.str = lexer.token(); return AGGR_OP avg|sum|max|min|count lval.str = strings.ToUpper(lexer.token()); return AGGR_OP \<|>|AND|OR|and|or lval.str = strings.ToUpper(lexer.token()); return CMP_OP diff --git a/rules/lexer.l.go b/rules/lexer.l.go index 60f03e778..af880e6ad 100644 --- a/rules/lexer.l.go +++ b/rules/lexer.l.go @@ -58,7 +58,7 @@ panic(fmt.Errorf(`invalid start condition %d`, yyt)) case 0: // start condition: INITIAL goto yystart1 case 1: // start condition: S_COMMENTS -goto yystart127 +goto yystart152 } goto yystate1 // silence unused label error @@ -82,7 +82,7 @@ case c == '-': goto yystate14 case c == '/': goto yystate17 -case c == ':' || c == 'E' || c == 'G' || c == 'H' || c >= 'J' && c <= 'L' || c == 'N' || c == 'Q' || c == 'R' || c >= 'T' && c <= 'V' || c >= 'X' && c <= 'Z' || c == '_' || c == 'e' || c == 'g' || c == 'h' || c >= 'j' && c <= 'l' || c == 'n' || c == 'q' || c == 'r' || c >= 't' && c <= 'v' || c >= 'x' && c <= 'z': +case c == ':' || c == 'E' || c == 'G' || c == 'H' || c == 'J' || c == 'L' || c == 'N' || c == 'Q' || c == 'R' || c >= 'T' && c <= 'V' || c >= 'X' && c <= 'Z' || c == '_' || c == 'e' || c == 'g' || c == 'h' || c == 'j' || c == 'l' || c == 'n' || c == 'q' || c == 'r' || c >= 't' && c <= 'v' || c >= 'x' && c <= 'z': goto yystate23 case c == '<' || c == '>': goto yystate24 @@ -100,49 +100,53 @@ case c == 'F': goto yystate52 case c == 'I': goto yystate55 -case c == 'M': +case c == 'K': goto yystate57 -case c == 'O': -goto yystate60 -case c == 'P': -goto yystate61 -case c == 'S': +case c == 'M': goto yystate70 +case c == 'O': +goto yystate73 +case c == 'P': +goto yystate74 +case c == 'S': +goto yystate83 case c == 'W': -goto yystate77 +goto yystate90 case c == '\'': goto yystate9 case c == '\t' || c == '\n' || c == '\r' || c == ' ': goto yystate2 case c == 'a': -goto yystate81 +goto yystate94 case c == 'b': -goto yystate88 +goto yystate101 case c == 'c': -goto yystate89 +goto yystate102 case c == 'd': -goto yystate93 -case c == 'f': -goto yystate103 -case c == 'i': -goto yystate105 -case c == 'm': goto yystate106 -case c == 'o': -goto yystate109 -case c == 'p': -goto yystate110 -case c == 's': +case c == 'f': +goto yystate116 +case c == 'i': goto yystate118 +case c == 'k': +goto yystate119 +case c == 'm': +goto yystate131 +case c == 'o': +goto yystate134 +case c == 'p': +goto yystate135 +case c == 's': +goto yystate143 case c == 'w': -goto yystate124 +goto yystate149 case c >= '0' && c <= '9': goto yystate21 } yystate2: c = lexer.getChar() -goto yyrule25 +goto yyrule26 yystate3: c = lexer.getChar() @@ -155,7 +159,7 @@ goto yystate4 yystate4: c = lexer.getChar() -goto yyrule16 +goto yyrule17 yystate5: c = lexer.getChar() @@ -172,7 +176,7 @@ goto yystate5 yystate6: c = lexer.getChar() -goto yyrule22 +goto yyrule23 yystate7: c = lexer.getChar() @@ -185,7 +189,7 @@ goto yystate5 yystate8: c = lexer.getChar() -goto yyrule18 +goto yyrule19 yystate9: c = lexer.getChar() @@ -202,7 +206,7 @@ goto yystate9 yystate10: c = lexer.getChar() -goto yyrule23 +goto yyrule24 yystate11: c = lexer.getChar() @@ -215,17 +219,17 @@ goto yystate9 yystate12: c = lexer.getChar() -goto yyrule24 +goto yyrule25 yystate13: c = lexer.getChar() -goto yyrule17 +goto yyrule18 yystate14: c = lexer.getChar() switch { default: -goto yyrule17 +goto yyrule18 case c >= '0' && c <= '9': goto yystate15 } @@ -234,7 +238,7 @@ yystate15: c = lexer.getChar() switch { default: -goto yyrule21 +goto yyrule22 case c == '.': goto yystate16 case c >= '0' && c <= '9': @@ -245,7 +249,7 @@ yystate16: c = lexer.getChar() switch { default: -goto yyrule21 +goto yyrule22 case c >= '0' && c <= '9': goto yystate16 } @@ -254,7 +258,7 @@ yystate17: c = lexer.getChar() switch { default: -goto yyrule18 +goto yyrule19 case c == '*': goto yystate18 case c == '/': @@ -284,7 +288,7 @@ yystate21: c = lexer.getChar() switch { default: -goto yyrule21 +goto yyrule22 case c == '.': goto yystate16 case c == 'd' || c == 'h' || c == 'm' || c == 's' || c == 'w' || c == 'y': @@ -295,13 +299,13 @@ goto yystate21 yystate22: c = lexer.getChar() -goto yyrule19 +goto yyrule20 yystate23: c = lexer.getChar() switch { default: -goto yyrule20 +goto yyrule21 case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z': goto yystate23 } @@ -310,7 +314,7 @@ yystate24: c = lexer.getChar() switch { default: -goto yyrule15 +goto yyrule16 case c == '=': goto yystate4 } @@ -319,7 +323,7 @@ yystate25: c = lexer.getChar() switch { default: -goto yyrule24 +goto yyrule25 case c == '=': goto yystate4 } @@ -328,7 +332,7 @@ yystate26: c = lexer.getChar() switch { default: -goto yyrule20 +goto yyrule21 case c == 'L': goto yystate27 case c == 'N': @@ -343,7 +347,7 @@ yystate27: c = lexer.getChar() switch { default: -goto yyrule20 +goto yyrule21 case c == 'E': goto yystate28 case c >= '0' && c <= ':' || c >= 'A' && c <= 'D' || c >= 'F' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z': @@ -354,7 +358,7 @@ yystate28: c = lexer.getChar() switch { default: -goto yyrule20 +goto yyrule21 case c == 'R': goto yystate29 case c >= '0' && c <= ':' || c >= 'A' && c <= 'Q' || c >= 'S' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z': @@ -365,7 +369,7 @@ yystate29: c = lexer.getChar() switch { default: -goto yyrule20 +goto yyrule21 case c == 'T': goto yystate30 case c >= '0' && c <= ':' || c >= 'A' && c <= 'S' || c >= 'U' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z': @@ -385,7 +389,7 @@ yystate31: c = lexer.getChar() switch { default: -goto yyrule20 +goto yyrule21 case c == 'D': goto yystate32 case c >= '0' && c <= ':' || c >= 'A' && c <= 'C' || c >= 'E' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z': @@ -396,7 +400,7 @@ yystate32: c = lexer.getChar() switch { default: -goto yyrule15 +goto yyrule16 case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z': goto yystate23 } @@ -405,7 +409,7 @@ yystate33: c = lexer.getChar() switch { default: -goto yyrule20 +goto yyrule21 case c == 'G': goto yystate34 case c >= '0' && c <= ':' || c >= 'A' && c <= 'F' || c >= 'H' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z': @@ -416,7 +420,7 @@ yystate34: c = lexer.getChar() switch { default: -goto yyrule13 +goto yyrule14 case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z': goto yystate23 } @@ -425,7 +429,7 @@ yystate35: c = lexer.getChar() switch { default: -goto yyrule20 +goto yyrule21 case c == 'Y': goto yystate36 case c >= '0' && c <= ':' || c >= 'A' && c <= 'X' || c == 'Z' || c == '_' || c >= 'a' && c <= 'z': @@ -445,7 +449,7 @@ yystate37: c = lexer.getChar() switch { default: -goto yyrule20 +goto yyrule21 case c == 'O': goto yystate38 case c >= '0' && c <= ':' || c >= 'A' && c <= 'N' || c >= 'P' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z': @@ -456,7 +460,7 @@ yystate38: c = lexer.getChar() switch { default: -goto yyrule20 +goto yyrule21 case c == 'U': goto yystate39 case c >= '0' && c <= ':' || c >= 'A' && c <= 'T' || c >= 'V' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z': @@ -467,7 +471,7 @@ yystate39: c = lexer.getChar() switch { default: -goto yyrule20 +goto yyrule21 case c == 'N': goto yystate40 case c >= '0' && c <= ':' || c >= 'A' && c <= 'M' || c >= 'O' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z': @@ -478,7 +482,7 @@ yystate40: c = lexer.getChar() switch { default: -goto yyrule20 +goto yyrule21 case c == 'T': goto yystate34 case c >= '0' && c <= ':' || c >= 'A' && c <= 'S' || c >= 'U' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z': @@ -489,7 +493,7 @@ yystate41: c = lexer.getChar() switch { default: -goto yyrule20 +goto yyrule21 case c == 'E': goto yystate42 case c >= '0' && c <= ':' || c >= 'A' && c <= 'D' || c >= 'F' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z': @@ -500,7 +504,7 @@ yystate42: c = lexer.getChar() switch { default: -goto yyrule20 +goto yyrule21 case c == 'S': goto yystate43 case c >= '0' && c <= ':' || c >= 'A' && c <= 'R' || c >= 'T' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z': @@ -511,7 +515,7 @@ yystate43: c = lexer.getChar() switch { default: -goto yyrule20 +goto yyrule21 case c == 'C': goto yystate44 case c >= '0' && c <= ':' || c == 'A' || c == 'B' || c >= 'D' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z': @@ -522,7 +526,7 @@ yystate44: c = lexer.getChar() switch { default: -goto yyrule20 +goto yyrule21 case c == 'R': goto yystate45 case c >= '0' && c <= ':' || c >= 'A' && c <= 'Q' || c >= 'S' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z': @@ -533,7 +537,7 @@ yystate45: c = lexer.getChar() switch { default: -goto yyrule20 +goto yyrule21 case c == 'I': goto yystate46 case c >= '0' && c <= ':' || c >= 'A' && c <= 'H' || c >= 'J' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z': @@ -544,7 +548,7 @@ yystate46: c = lexer.getChar() switch { default: -goto yyrule20 +goto yyrule21 case c == 'P': goto yystate47 case c >= '0' && c <= ':' || c >= 'A' && c <= 'O' || c >= 'Q' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z': @@ -555,7 +559,7 @@ yystate47: c = lexer.getChar() switch { default: -goto yyrule20 +goto yyrule21 case c == 'T': goto yystate48 case c >= '0' && c <= ':' || c >= 'A' && c <= 'S' || c >= 'U' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z': @@ -566,7 +570,7 @@ yystate48: c = lexer.getChar() switch { default: -goto yyrule20 +goto yyrule21 case c == 'I': goto yystate49 case c >= '0' && c <= ':' || c >= 'A' && c <= 'H' || c >= 'J' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z': @@ -577,7 +581,7 @@ yystate49: c = lexer.getChar() switch { default: -goto yyrule20 +goto yyrule21 case c == 'O': goto yystate50 case c >= '0' && c <= ':' || c >= 'A' && c <= 'N' || c >= 'P' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z': @@ -588,7 +592,7 @@ yystate50: c = lexer.getChar() switch { default: -goto yyrule20 +goto yyrule21 case c == 'N': goto yystate51 case c >= '0' && c <= ':' || c >= 'A' && c <= 'M' || c >= 'O' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z': @@ -608,7 +612,7 @@ yystate52: c = lexer.getChar() switch { default: -goto yyrule20 +goto yyrule21 case c == 'O': goto yystate53 case c >= '0' && c <= ':' || c >= 'A' && c <= 'N' || c >= 'P' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z': @@ -619,7 +623,7 @@ yystate53: c = lexer.getChar() switch { default: -goto yyrule20 +goto yyrule21 case c == 'R': goto yystate54 case c >= '0' && c <= ':' || c >= 'A' && c <= 'Q' || c >= 'S' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z': @@ -639,7 +643,7 @@ yystate55: c = lexer.getChar() switch { default: -goto yyrule20 +goto yyrule21 case c == 'F': goto yystate56 case c >= '0' && c <= ':' || c >= 'A' && c <= 'E' || c >= 'G' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z': @@ -659,12 +663,10 @@ yystate57: c = lexer.getChar() switch { default: -goto yyrule20 -case c == 'A': +goto yyrule21 +case c == 'E': goto yystate58 -case c == 'I': -goto yystate59 -case c >= '0' && c <= ':' || c >= 'B' && c <= 'H' || c >= 'J' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z': +case c >= '0' && c <= ':' || c >= 'A' && c <= 'D' || c >= 'F' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z': goto yystate23 } @@ -672,10 +674,10 @@ yystate58: c = lexer.getChar() switch { default: -goto yyrule20 -case c == 'X': -goto yystate34 -case c >= '0' && c <= ':' || c >= 'A' && c <= 'W' || c == 'Y' || c == 'Z' || c == '_' || c >= 'a' && c <= 'z': +goto yyrule21 +case c == 'E': +goto yystate59 +case c >= '0' && c <= ':' || c >= 'A' && c <= 'D' || c >= 'F' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z': goto yystate23 } @@ -683,10 +685,10 @@ yystate59: c = lexer.getChar() switch { default: -goto yyrule20 -case c == 'N': -goto yystate34 -case c >= '0' && c <= ':' || c >= 'A' && c <= 'M' || c >= 'O' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z': +goto yyrule21 +case c == 'P': +goto yystate60 +case c >= '0' && c <= ':' || c >= 'A' && c <= 'O' || c >= 'Q' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z': goto yystate23 } @@ -694,10 +696,10 @@ yystate60: c = lexer.getChar() switch { default: -goto yyrule20 -case c == 'R': -goto yystate32 -case c >= '0' && c <= ':' || c >= 'A' && c <= 'Q' || c >= 'S' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z': +goto yyrule21 +case c == 'I': +goto yystate61 +case c >= '0' && c <= ':' || c >= 'A' && c <= 'H' || c >= 'J' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z': goto yystate23 } @@ -705,10 +707,10 @@ yystate61: c = lexer.getChar() switch { default: -goto yyrule20 -case c == 'E': +goto yyrule21 +case c == 'N': goto yystate62 -case c >= '0' && c <= ':' || c >= 'A' && c <= 'D' || c >= 'F' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z': +case c >= '0' && c <= ':' || c >= 'A' && c <= 'M' || c >= 'O' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z': goto yystate23 } @@ -716,10 +718,10 @@ yystate62: c = lexer.getChar() switch { default: -goto yyrule20 -case c == 'R': +goto yyrule21 +case c == 'G': goto yystate63 -case c >= '0' && c <= ':' || c >= 'A' && c <= 'Q' || c >= 'S' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z': +case c >= '0' && c <= ':' || c >= 'A' && c <= 'F' || c >= 'H' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z': goto yystate23 } @@ -727,10 +729,10 @@ yystate63: c = lexer.getChar() switch { default: -goto yyrule20 -case c == 'M': +goto yyrule21 +case c == '_': goto yystate64 -case c >= '0' && c <= ':' || c >= 'A' && c <= 'L' || c >= 'N' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z': +case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c >= 'a' && c <= 'z': goto yystate23 } @@ -738,10 +740,10 @@ yystate64: c = lexer.getChar() switch { default: -goto yyrule20 -case c == 'A': +goto yyrule21 +case c == 'E': goto yystate65 -case c >= '0' && c <= ':' || c >= 'B' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z': +case c >= '0' && c <= ':' || c >= 'A' && c <= 'D' || c >= 'F' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z': goto yystate23 } @@ -749,10 +751,10 @@ yystate65: c = lexer.getChar() switch { default: -goto yyrule20 -case c == 'N': +goto yyrule21 +case c == 'X': goto yystate66 -case c >= '0' && c <= ':' || c >= 'A' && c <= 'M' || c >= 'O' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z': +case c >= '0' && c <= ':' || c >= 'A' && c <= 'W' || c == 'Y' || c == 'Z' || c == '_' || c >= 'a' && c <= 'z': goto yystate23 } @@ -760,10 +762,10 @@ yystate66: c = lexer.getChar() switch { default: -goto yyrule20 -case c == 'E': +goto yyrule21 +case c == 'T': goto yystate67 -case c >= '0' && c <= ':' || c >= 'A' && c <= 'D' || c >= 'F' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z': +case c >= '0' && c <= ':' || c >= 'A' && c <= 'S' || c >= 'U' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z': goto yystate23 } @@ -771,10 +773,10 @@ yystate67: c = lexer.getChar() switch { default: -goto yyrule20 -case c == 'N': +goto yyrule21 +case c == 'R': goto yystate68 -case c >= '0' && c <= ':' || c >= 'A' && c <= 'M' || c >= 'O' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z': +case c >= '0' && c <= ':' || c >= 'A' && c <= 'Q' || c >= 'S' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z': goto yystate23 } @@ -782,10 +784,10 @@ yystate68: c = lexer.getChar() switch { default: -goto yyrule20 -case c == 'T': +goto yyrule21 +case c == 'A': goto yystate69 -case c >= '0' && c <= ':' || c >= 'A' && c <= 'S' || c >= 'U' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z': +case c >= '0' && c <= ':' || c >= 'B' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z': goto yystate23 } @@ -793,7 +795,7 @@ yystate69: c = lexer.getChar() switch { default: -goto yyrule11 +goto yyrule13 case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z': goto yystate23 } @@ -802,10 +804,12 @@ yystate70: c = lexer.getChar() switch { default: -goto yyrule20 -case c == 'U': +goto yyrule21 +case c == 'A': goto yystate71 -case c >= '0' && c <= ':' || c >= 'A' && c <= 'T' || c >= 'V' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z': +case c == 'I': +goto yystate72 +case c >= '0' && c <= ':' || c >= 'B' && c <= 'H' || c >= 'J' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z': goto yystate23 } @@ -813,10 +817,10 @@ yystate71: c = lexer.getChar() switch { default: -goto yyrule20 -case c == 'M': -goto yystate72 -case c >= '0' && c <= ':' || c >= 'A' && c <= 'L' || c >= 'N' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z': +goto yyrule21 +case c == 'X': +goto yystate34 +case c >= '0' && c <= ':' || c >= 'A' && c <= 'W' || c == 'Y' || c == 'Z' || c == '_' || c >= 'a' && c <= 'z': goto yystate23 } @@ -824,10 +828,10 @@ yystate72: c = lexer.getChar() switch { default: -goto yyrule13 -case c == 'M': -goto yystate73 -case c >= '0' && c <= ':' || c >= 'A' && c <= 'L' || c >= 'N' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z': +goto yyrule21 +case c == 'N': +goto yystate34 +case c >= '0' && c <= ':' || c >= 'A' && c <= 'M' || c >= 'O' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z': goto yystate23 } @@ -835,10 +839,10 @@ yystate73: c = lexer.getChar() switch { default: -goto yyrule20 -case c == 'A': -goto yystate74 -case c >= '0' && c <= ':' || c >= 'B' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z': +goto yyrule21 +case c == 'R': +goto yystate32 +case c >= '0' && c <= ':' || c >= 'A' && c <= 'Q' || c >= 'S' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z': goto yystate23 } @@ -846,10 +850,10 @@ yystate74: c = lexer.getChar() switch { default: -goto yyrule20 -case c == 'R': +goto yyrule21 +case c == 'E': goto yystate75 -case c >= '0' && c <= ':' || c >= 'A' && c <= 'Q' || c >= 'S' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z': +case c >= '0' && c <= ':' || c >= 'A' && c <= 'D' || c >= 'F' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z': goto yystate23 } @@ -857,10 +861,10 @@ yystate75: c = lexer.getChar() switch { default: -goto yyrule20 -case c == 'Y': +goto yyrule21 +case c == 'R': goto yystate76 -case c >= '0' && c <= ':' || c >= 'A' && c <= 'X' || c == 'Z' || c == '_' || c >= 'a' && c <= 'z': +case c >= '0' && c <= ':' || c >= 'A' && c <= 'Q' || c >= 'S' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z': goto yystate23 } @@ -868,45 +872,186 @@ yystate76: c = lexer.getChar() switch { default: +goto yyrule21 +case c == 'M': +goto yystate77 +case c >= '0' && c <= ':' || c >= 'A' && c <= 'L' || c >= 'N' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z': +goto yystate23 +} + +yystate77: +c = lexer.getChar() +switch { +default: +goto yyrule21 +case c == 'A': +goto yystate78 +case c >= '0' && c <= ':' || c >= 'B' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z': +goto yystate23 +} + +yystate78: +c = lexer.getChar() +switch { +default: +goto yyrule21 +case c == 'N': +goto yystate79 +case c >= '0' && c <= ':' || c >= 'A' && c <= 'M' || c >= 'O' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z': +goto yystate23 +} + +yystate79: +c = lexer.getChar() +switch { +default: +goto yyrule21 +case c == 'E': +goto yystate80 +case c >= '0' && c <= ':' || c >= 'A' && c <= 'D' || c >= 'F' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z': +goto yystate23 +} + +yystate80: +c = lexer.getChar() +switch { +default: +goto yyrule21 +case c == 'N': +goto yystate81 +case c >= '0' && c <= ':' || c >= 'A' && c <= 'M' || c >= 'O' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z': +goto yystate23 +} + +yystate81: +c = lexer.getChar() +switch { +default: +goto yyrule21 +case c == 'T': +goto yystate82 +case c >= '0' && c <= ':' || c >= 'A' && c <= 'S' || c >= 'U' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z': +goto yystate23 +} + +yystate82: +c = lexer.getChar() +switch { +default: +goto yyrule11 +case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z': +goto yystate23 +} + +yystate83: +c = lexer.getChar() +switch { +default: +goto yyrule21 +case c == 'U': +goto yystate84 +case c >= '0' && c <= ':' || c >= 'A' && c <= 'T' || c >= 'V' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z': +goto yystate23 +} + +yystate84: +c = lexer.getChar() +switch { +default: +goto yyrule21 +case c == 'M': +goto yystate85 +case c >= '0' && c <= ':' || c >= 'A' && c <= 'L' || c >= 'N' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z': +goto yystate23 +} + +yystate85: +c = lexer.getChar() +switch { +default: +goto yyrule14 +case c == 'M': +goto yystate86 +case c >= '0' && c <= ':' || c >= 'A' && c <= 'L' || c >= 'N' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z': +goto yystate23 +} + +yystate86: +c = lexer.getChar() +switch { +default: +goto yyrule21 +case c == 'A': +goto yystate87 +case c >= '0' && c <= ':' || c >= 'B' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z': +goto yystate23 +} + +yystate87: +c = lexer.getChar() +switch { +default: +goto yyrule21 +case c == 'R': +goto yystate88 +case c >= '0' && c <= ':' || c >= 'A' && c <= 'Q' || c >= 'S' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z': +goto yystate23 +} + +yystate88: +c = lexer.getChar() +switch { +default: +goto yyrule21 +case c == 'Y': +goto yystate89 +case c >= '0' && c <= ':' || c >= 'A' && c <= 'X' || c == 'Z' || c == '_' || c >= 'a' && c <= 'z': +goto yystate23 +} + +yystate89: +c = lexer.getChar() +switch { +default: goto yyrule9 case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z': goto yystate23 } -yystate77: +yystate90: c = lexer.getChar() switch { default: -goto yyrule20 +goto yyrule21 case c == 'I': -goto yystate78 +goto yystate91 case c >= '0' && c <= ':' || c >= 'A' && c <= 'H' || c >= 'J' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z': goto yystate23 } -yystate78: +yystate91: c = lexer.getChar() switch { default: -goto yyrule20 +goto yyrule21 case c == 'T': -goto yystate79 +goto yystate92 case c >= '0' && c <= ':' || c >= 'A' && c <= 'S' || c >= 'U' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z': goto yystate23 } -yystate79: +yystate92: c = lexer.getChar() switch { default: -goto yyrule20 +goto yyrule21 case c == 'H': -goto yystate80 +goto yystate93 case c >= '0' && c <= ':' || c >= 'A' && c <= 'G' || c >= 'I' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z': goto yystate23 } -yystate80: +yystate93: c = lexer.getChar() switch { default: @@ -915,159 +1060,18 @@ case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c < goto yystate23 } -yystate81: -c = lexer.getChar() -switch { -default: -goto yyrule20 -case c == 'l': -goto yystate82 -case c == 'n': -goto yystate85 -case c == 'v': -goto yystate86 -case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'k' || c == 'm' || c >= 'o' && c <= 'u' || c >= 'w' && c <= 'z': -goto yystate23 -} - -yystate82: -c = lexer.getChar() -switch { -default: -goto yyrule20 -case c == 'e': -goto yystate83 -case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'd' || c >= 'f' && c <= 'z': -goto yystate23 -} - -yystate83: -c = lexer.getChar() -switch { -default: -goto yyrule20 -case c == 'r': -goto yystate84 -case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'q' || c >= 's' && c <= 'z': -goto yystate23 -} - -yystate84: -c = lexer.getChar() -switch { -default: -goto yyrule20 -case c == 't': -goto yystate30 -case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 's' || c >= 'u' && c <= 'z': -goto yystate23 -} - -yystate85: -c = lexer.getChar() -switch { -default: -goto yyrule20 -case c == 'd': -goto yystate32 -case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'c' || c >= 'e' && c <= 'z': -goto yystate23 -} - -yystate86: -c = lexer.getChar() -switch { -default: -goto yyrule20 -case c == 'g': -goto yystate87 -case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'f' || c >= 'h' && c <= 'z': -goto yystate23 -} - -yystate87: -c = lexer.getChar() -switch { -default: -goto yyrule14 -case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z': -goto yystate23 -} - -yystate88: -c = lexer.getChar() -switch { -default: -goto yyrule20 -case c == 'y': -goto yystate36 -case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'x' || c == 'z': -goto yystate23 -} - -yystate89: -c = lexer.getChar() -switch { -default: -goto yyrule20 -case c == 'o': -goto yystate90 -case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'n' || c >= 'p' && c <= 'z': -goto yystate23 -} - -yystate90: -c = lexer.getChar() -switch { -default: -goto yyrule20 -case c == 'u': -goto yystate91 -case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 't' || c >= 'v' && c <= 'z': -goto yystate23 -} - -yystate91: -c = lexer.getChar() -switch { -default: -goto yyrule20 -case c == 'n': -goto yystate92 -case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'm' || c >= 'o' && c <= 'z': -goto yystate23 -} - -yystate92: -c = lexer.getChar() -switch { -default: -goto yyrule20 -case c == 't': -goto yystate87 -case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 's' || c >= 'u' && c <= 'z': -goto yystate23 -} - -yystate93: -c = lexer.getChar() -switch { -default: -goto yyrule20 -case c == 'e': -goto yystate94 -case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'd' || c >= 'f' && c <= 'z': -goto yystate23 -} - yystate94: c = lexer.getChar() switch { default: -goto yyrule20 -case c == 's': +goto yyrule21 +case c == 'l': goto yystate95 -case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'r' || c >= 't' && c <= 'z': +case c == 'n': +goto yystate98 +case c == 'v': +goto yystate99 +case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'k' || c == 'm' || c >= 'o' && c <= 'u' || c >= 'w' && c <= 'z': goto yystate23 } @@ -1075,10 +1079,10 @@ yystate95: c = lexer.getChar() switch { default: -goto yyrule20 -case c == 'c': +goto yyrule21 +case c == 'e': goto yystate96 -case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c == 'a' || c == 'b' || c >= 'd' && c <= 'z': +case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'd' || c >= 'f' && c <= 'z': goto yystate23 } @@ -1086,7 +1090,7 @@ yystate96: c = lexer.getChar() switch { default: -goto yyrule20 +goto yyrule21 case c == 'r': goto yystate97 case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'q' || c >= 's' && c <= 'z': @@ -1097,10 +1101,10 @@ yystate97: c = lexer.getChar() switch { default: -goto yyrule20 -case c == 'i': -goto yystate98 -case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'h' || c >= 'j' && c <= 'z': +goto yyrule21 +case c == 't': +goto yystate30 +case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 's' || c >= 'u' && c <= 'z': goto yystate23 } @@ -1108,10 +1112,10 @@ yystate98: c = lexer.getChar() switch { default: -goto yyrule20 -case c == 'p': -goto yystate99 -case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'o' || c >= 'q' && c <= 'z': +goto yyrule21 +case c == 'd': +goto yystate32 +case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'c' || c >= 'e' && c <= 'z': goto yystate23 } @@ -1119,10 +1123,10 @@ yystate99: c = lexer.getChar() switch { default: -goto yyrule20 -case c == 't': +goto yyrule21 +case c == 'g': goto yystate100 -case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 's' || c >= 'u' && c <= 'z': +case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'f' || c >= 'h' && c <= 'z': goto yystate23 } @@ -1130,10 +1134,8 @@ yystate100: c = lexer.getChar() switch { default: -goto yyrule20 -case c == 'i': -goto yystate101 -case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'h' || c >= 'j' && c <= 'z': +goto yyrule15 +case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'z': goto yystate23 } @@ -1141,10 +1143,10 @@ yystate101: c = lexer.getChar() switch { default: -goto yyrule20 -case c == 'o': -goto yystate102 -case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'n' || c >= 'p' && c <= 'z': +goto yyrule21 +case c == 'y': +goto yystate36 +case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'x' || c == 'z': goto yystate23 } @@ -1152,10 +1154,10 @@ yystate102: c = lexer.getChar() switch { default: -goto yyrule20 -case c == 'n': -goto yystate51 -case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'm' || c >= 'o' && c <= 'z': +goto yyrule21 +case c == 'o': +goto yystate103 +case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'n' || c >= 'p' && c <= 'z': goto yystate23 } @@ -1163,10 +1165,10 @@ yystate103: c = lexer.getChar() switch { default: -goto yyrule20 -case c == 'o': +goto yyrule21 +case c == 'u': goto yystate104 -case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'n' || c >= 'p' && c <= 'z': +case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 't' || c >= 'v' && c <= 'z': goto yystate23 } @@ -1174,10 +1176,10 @@ yystate104: c = lexer.getChar() switch { default: -goto yyrule20 -case c == 'r': -goto yystate54 -case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'q' || c >= 's' && c <= 'z': +goto yyrule21 +case c == 'n': +goto yystate105 +case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'm' || c >= 'o' && c <= 'z': goto yystate23 } @@ -1185,10 +1187,10 @@ yystate105: c = lexer.getChar() switch { default: -goto yyrule20 -case c == 'f': -goto yystate56 -case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'e' || c >= 'g' && c <= 'z': +goto yyrule21 +case c == 't': +goto yystate100 +case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 's' || c >= 'u' && c <= 'z': goto yystate23 } @@ -1196,12 +1198,10 @@ yystate106: c = lexer.getChar() switch { default: -goto yyrule20 -case c == 'a': +goto yyrule21 +case c == 'e': goto yystate107 -case c == 'i': -goto yystate108 -case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'b' && c <= 'h' || c >= 'j' && c <= 'z': +case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'd' || c >= 'f' && c <= 'z': goto yystate23 } @@ -1209,10 +1209,10 @@ yystate107: c = lexer.getChar() switch { default: -goto yyrule20 -case c == 'x': -goto yystate87 -case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'w' || c == 'y' || c == 'z': +goto yyrule21 +case c == 's': +goto yystate108 +case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'r' || c >= 't' && c <= 'z': goto yystate23 } @@ -1220,10 +1220,10 @@ yystate108: c = lexer.getChar() switch { default: -goto yyrule20 -case c == 'n': -goto yystate87 -case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'm' || c >= 'o' && c <= 'z': +goto yyrule21 +case c == 'c': +goto yystate109 +case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c == 'a' || c == 'b' || c >= 'd' && c <= 'z': goto yystate23 } @@ -1231,9 +1231,9 @@ yystate109: c = lexer.getChar() switch { default: -goto yyrule20 +goto yyrule21 case c == 'r': -goto yystate32 +goto yystate110 case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'q' || c >= 's' && c <= 'z': goto yystate23 } @@ -1242,10 +1242,10 @@ yystate110: c = lexer.getChar() switch { default: -goto yyrule20 -case c == 'e': +goto yyrule21 +case c == 'i': goto yystate111 -case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'd' || c >= 'f' && c <= 'z': +case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'h' || c >= 'j' && c <= 'z': goto yystate23 } @@ -1253,10 +1253,10 @@ yystate111: c = lexer.getChar() switch { default: -goto yyrule20 -case c == 'r': +goto yyrule21 +case c == 'p': goto yystate112 -case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'q' || c >= 's' && c <= 'z': +case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'o' || c >= 'q' && c <= 'z': goto yystate23 } @@ -1264,10 +1264,10 @@ yystate112: c = lexer.getChar() switch { default: -goto yyrule20 -case c == 'm': +goto yyrule21 +case c == 't': goto yystate113 -case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'l' || c >= 'n' && c <= 'z': +case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 's' || c >= 'u' && c <= 'z': goto yystate23 } @@ -1275,10 +1275,10 @@ yystate113: c = lexer.getChar() switch { default: -goto yyrule20 -case c == 'a': +goto yyrule21 +case c == 'i': goto yystate114 -case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'b' && c <= 'z': +case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'h' || c >= 'j' && c <= 'z': goto yystate23 } @@ -1286,10 +1286,10 @@ yystate114: c = lexer.getChar() switch { default: -goto yyrule20 -case c == 'n': +goto yyrule21 +case c == 'o': goto yystate115 -case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'm' || c >= 'o' && c <= 'z': +case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'n' || c >= 'p' && c <= 'z': goto yystate23 } @@ -1297,10 +1297,10 @@ yystate115: c = lexer.getChar() switch { default: -goto yyrule20 -case c == 'e': -goto yystate116 -case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'd' || c >= 'f' && c <= 'z': +goto yyrule21 +case c == 'n': +goto yystate51 +case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'm' || c >= 'o' && c <= 'z': goto yystate23 } @@ -1308,10 +1308,10 @@ yystate116: c = lexer.getChar() switch { default: -goto yyrule20 -case c == 'n': +goto yyrule21 +case c == 'o': goto yystate117 -case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'm' || c >= 'o' && c <= 'z': +case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'n' || c >= 'p' && c <= 'z': goto yystate23 } @@ -1319,10 +1319,10 @@ yystate117: c = lexer.getChar() switch { default: -goto yyrule20 -case c == 't': -goto yystate69 -case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 's' || c >= 'u' && c <= 'z': +goto yyrule21 +case c == 'r': +goto yystate54 +case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'q' || c >= 's' && c <= 'z': goto yystate23 } @@ -1330,10 +1330,10 @@ yystate118: c = lexer.getChar() switch { default: -goto yyrule20 -case c == 'u': -goto yystate119 -case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 't' || c >= 'v' && c <= 'z': +goto yyrule21 +case c == 'f': +goto yystate56 +case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'e' || c >= 'g' && c <= 'z': goto yystate23 } @@ -1341,10 +1341,10 @@ yystate119: c = lexer.getChar() switch { default: -goto yyrule20 -case c == 'm': +goto yyrule21 +case c == 'e': goto yystate120 -case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'l' || c >= 'n' && c <= 'z': +case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'd' || c >= 'f' && c <= 'z': goto yystate23 } @@ -1352,10 +1352,10 @@ yystate120: c = lexer.getChar() switch { default: -goto yyrule14 -case c == 'm': +goto yyrule21 +case c == 'e': goto yystate121 -case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'l' || c >= 'n' && c <= 'z': +case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'd' || c >= 'f' && c <= 'z': goto yystate23 } @@ -1363,10 +1363,10 @@ yystate121: c = lexer.getChar() switch { default: -goto yyrule20 -case c == 'a': +goto yyrule21 +case c == 'p': goto yystate122 -case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'b' && c <= 'z': +case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'o' || c >= 'q' && c <= 'z': goto yystate23 } @@ -1374,10 +1374,10 @@ yystate122: c = lexer.getChar() switch { default: -goto yyrule20 -case c == 'r': +goto yyrule21 +case c == 'i': goto yystate123 -case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'q' || c >= 's' && c <= 'z': +case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'h' || c >= 'j' && c <= 'z': goto yystate23 } @@ -1385,10 +1385,10 @@ yystate123: c = lexer.getChar() switch { default: -goto yyrule20 -case c == 'y': -goto yystate76 -case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'x' || c == 'z': +goto yyrule21 +case c == 'n': +goto yystate124 +case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'm' || c >= 'o' && c <= 'z': goto yystate23 } @@ -1396,10 +1396,10 @@ yystate124: c = lexer.getChar() switch { default: -goto yyrule20 -case c == 'i': +goto yyrule21 +case c == 'g': goto yystate125 -case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'h' || c >= 'j' && c <= 'z': +case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'f' || c >= 'h' && c <= 'z': goto yystate23 } @@ -1407,10 +1407,10 @@ yystate125: c = lexer.getChar() switch { default: -goto yyrule20 -case c == 't': +goto yyrule21 +case c == '_': goto yystate126 -case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 's' || c >= 'u' && c <= 'z': +case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c >= 'a' && c <= 'z': goto yystate23 } @@ -1418,41 +1418,318 @@ yystate126: c = lexer.getChar() switch { default: -goto yyrule20 -case c == 'h': -goto yystate80 -case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'g' || c >= 'i' && c <= 'z': +goto yyrule21 +case c == 'e': +goto yystate127 +case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'd' || c >= 'f' && c <= 'z': goto yystate23 } -goto yystate127 // silence unused label error yystate127: c = lexer.getChar() -yystart127: switch { default: -goto yyabort -case c == '*': -goto yystate129 -case c >= '\x01' && c <= ')' || c >= '+' && c <= 'ÿ': +goto yyrule21 +case c == 'x': goto yystate128 +case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'w' || c == 'y' || c == 'z': +goto yystate23 } yystate128: c = lexer.getChar() -goto yyrule3 +switch { +default: +goto yyrule21 +case c == 't': +goto yystate129 +case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 's' || c >= 'u' && c <= 'z': +goto yystate23 +} yystate129: c = lexer.getChar() switch { default: -goto yyrule3 -case c == '/': +goto yyrule21 +case c == 'r': goto yystate130 +case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'q' || c >= 's' && c <= 'z': +goto yystate23 } yystate130: c = lexer.getChar() +switch { +default: +goto yyrule21 +case c == 'a': +goto yystate69 +case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'b' && c <= 'z': +goto yystate23 +} + +yystate131: +c = lexer.getChar() +switch { +default: +goto yyrule21 +case c == 'a': +goto yystate132 +case c == 'i': +goto yystate133 +case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'b' && c <= 'h' || c >= 'j' && c <= 'z': +goto yystate23 +} + +yystate132: +c = lexer.getChar() +switch { +default: +goto yyrule21 +case c == 'x': +goto yystate100 +case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'w' || c == 'y' || c == 'z': +goto yystate23 +} + +yystate133: +c = lexer.getChar() +switch { +default: +goto yyrule21 +case c == 'n': +goto yystate100 +case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'm' || c >= 'o' && c <= 'z': +goto yystate23 +} + +yystate134: +c = lexer.getChar() +switch { +default: +goto yyrule21 +case c == 'r': +goto yystate32 +case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'q' || c >= 's' && c <= 'z': +goto yystate23 +} + +yystate135: +c = lexer.getChar() +switch { +default: +goto yyrule21 +case c == 'e': +goto yystate136 +case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'd' || c >= 'f' && c <= 'z': +goto yystate23 +} + +yystate136: +c = lexer.getChar() +switch { +default: +goto yyrule21 +case c == 'r': +goto yystate137 +case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'q' || c >= 's' && c <= 'z': +goto yystate23 +} + +yystate137: +c = lexer.getChar() +switch { +default: +goto yyrule21 +case c == 'm': +goto yystate138 +case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'l' || c >= 'n' && c <= 'z': +goto yystate23 +} + +yystate138: +c = lexer.getChar() +switch { +default: +goto yyrule21 +case c == 'a': +goto yystate139 +case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'b' && c <= 'z': +goto yystate23 +} + +yystate139: +c = lexer.getChar() +switch { +default: +goto yyrule21 +case c == 'n': +goto yystate140 +case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'm' || c >= 'o' && c <= 'z': +goto yystate23 +} + +yystate140: +c = lexer.getChar() +switch { +default: +goto yyrule21 +case c == 'e': +goto yystate141 +case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'd' || c >= 'f' && c <= 'z': +goto yystate23 +} + +yystate141: +c = lexer.getChar() +switch { +default: +goto yyrule21 +case c == 'n': +goto yystate142 +case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'm' || c >= 'o' && c <= 'z': +goto yystate23 +} + +yystate142: +c = lexer.getChar() +switch { +default: +goto yyrule21 +case c == 't': +goto yystate82 +case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 's' || c >= 'u' && c <= 'z': +goto yystate23 +} + +yystate143: +c = lexer.getChar() +switch { +default: +goto yyrule21 +case c == 'u': +goto yystate144 +case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 't' || c >= 'v' && c <= 'z': +goto yystate23 +} + +yystate144: +c = lexer.getChar() +switch { +default: +goto yyrule21 +case c == 'm': +goto yystate145 +case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'l' || c >= 'n' && c <= 'z': +goto yystate23 +} + +yystate145: +c = lexer.getChar() +switch { +default: +goto yyrule15 +case c == 'm': +goto yystate146 +case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'l' || c >= 'n' && c <= 'z': +goto yystate23 +} + +yystate146: +c = lexer.getChar() +switch { +default: +goto yyrule21 +case c == 'a': +goto yystate147 +case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'b' && c <= 'z': +goto yystate23 +} + +yystate147: +c = lexer.getChar() +switch { +default: +goto yyrule21 +case c == 'r': +goto yystate148 +case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'q' || c >= 's' && c <= 'z': +goto yystate23 +} + +yystate148: +c = lexer.getChar() +switch { +default: +goto yyrule21 +case c == 'y': +goto yystate89 +case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'x' || c == 'z': +goto yystate23 +} + +yystate149: +c = lexer.getChar() +switch { +default: +goto yyrule21 +case c == 'i': +goto yystate150 +case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'h' || c >= 'j' && c <= 'z': +goto yystate23 +} + +yystate150: +c = lexer.getChar() +switch { +default: +goto yyrule21 +case c == 't': +goto yystate151 +case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 's' || c >= 'u' && c <= 'z': +goto yystate23 +} + +yystate151: +c = lexer.getChar() +switch { +default: +goto yyrule21 +case c == 'h': +goto yystate93 +case c >= '0' && c <= ':' || c >= 'A' && c <= 'Z' || c == '_' || c >= 'a' && c <= 'g' || c >= 'i' && c <= 'z': +goto yystate23 +} + +goto yystate152 // silence unused label error +yystate152: +c = lexer.getChar() +yystart152: +switch { +default: +goto yyabort +case c == '*': +goto yystate154 +case c >= '\x01' && c <= ')' || c >= '+' && c <= 'ÿ': +goto yystate153 +} + +yystate153: +c = lexer.getChar() +goto yyrule3 + +yystate154: +c = lexer.getChar() +switch { +default: +goto yyrule3 +case c == '/': +goto yystate155 +} + +yystate155: +c = lexer.getChar() goto yyrule2 yyrule1: // "/*" @@ -1507,47 +1784,51 @@ yyrule12: // BY|by { return GROUP_OP } -yyrule13: // AVG|SUM|MAX|MIN|COUNT +yyrule13: // KEEPING_EXTRA|keeping_extra +{ +return KEEPING_EXTRA +} +yyrule14: // AVG|SUM|MAX|MIN|COUNT { lval.str = lexer.token(); return AGGR_OP goto yystate0 } -yyrule14: // avg|sum|max|min|count +yyrule15: // avg|sum|max|min|count { lval.str = strings.ToUpper(lexer.token()); return AGGR_OP goto yystate0 } -yyrule15: // \<|>|AND|OR|and|or +yyrule16: // \<|>|AND|OR|and|or { lval.str = strings.ToUpper(lexer.token()); return CMP_OP goto yystate0 } -yyrule16: // ==|!=|>=|<= +yyrule17: // ==|!=|>=|<= { lval.str = lexer.token(); return CMP_OP goto yystate0 } -yyrule17: // [+\-] +yyrule18: // [+\-] { lval.str = lexer.token(); return ADDITIVE_OP goto yystate0 } -yyrule18: // [*/%] +yyrule19: // [*/%] { lval.str = lexer.token(); return MULT_OP goto yystate0 } -yyrule19: // {D}+{U} +yyrule20: // {D}+{U} { lval.str = lexer.token(); return DURATION goto yystate0 } -yyrule20: // {L}({L}|{D})* +yyrule21: // {L}({L}|{D})* { lval.str = lexer.token(); return IDENTIFIER goto yystate0 } -yyrule21: // \-?{D}+(\.{D}*)? +yyrule22: // \-?{D}+(\.{D}*)? { num, err := strconv.ParseFloat(lexer.token(), 64); if (err != nil && err.(*strconv.NumError).Err == strconv.ErrSyntax) { @@ -1556,21 +1837,21 @@ yyrule21: // \-?{D}+(\.{D}*)? lval.num = clientmodel.SampleValue(num) return NUMBER } -yyrule22: // \"(\\.|[^\\"])*\" +yyrule23: // \"(\\.|[^\\"])*\" { lval.str = lexer.token()[1:len(lexer.token()) - 1]; return STRING goto yystate0 } -yyrule23: // \'(\\.|[^\\'])*\' +yyrule24: // \'(\\.|[^\\'])*\' { lval.str = lexer.token()[1:len(lexer.token()) - 1]; return STRING goto yystate0 } -yyrule24: // [{}\[\]()=,] +yyrule25: // [{}\[\]()=,] { return int(lexer.buf[0]) } -yyrule25: // [\t\n\r ] +yyrule26: // [\t\n\r ] { /* gobble up any whitespace */ goto yystate0 diff --git a/rules/parser.y b/rules/parser.y index 2e265f706..0591ea589 100644 --- a/rules/parser.y +++ b/rules/parser.y @@ -39,7 +39,7 @@ %token IDENTIFIER STRING DURATION %token NUMBER -%token PERMANENT GROUP_OP +%token PERMANENT GROUP_OP KEEPING_EXTRA %token AGGR_OP CMP_OP ADDITIVE_OP MULT_OP %token ALERT IF FOR WITH SUMMARY DESCRIPTION @@ -47,7 +47,7 @@ %type label_list grouping_opts %type label_assign label_assign_list rule_labels %type rule_expr func_arg -%type qualifier +%type qualifier extra_labels_opts %type for_duration %right '=' @@ -135,10 +135,10 @@ rule_expr : '(' rule_expr ')' $$, err = NewMatrix($1, $3) if err != nil { yylex.Error(err.Error()); return 1 } } - | AGGR_OP '(' rule_expr ')' grouping_opts + | AGGR_OP '(' rule_expr ')' grouping_opts extra_labels_opts { var err error - $$, err = NewVectorAggregation($1, $3, $5) + $$, err = NewVectorAggregation($1, $3, $5, $6) if err != nil { yylex.Error(err.Error()); return 1 } } /* Yacc can only attach associativity to terminals, so we @@ -165,6 +165,12 @@ rule_expr : '(' rule_expr ')' { $$ = ast.NewScalarLiteral($1)} ; +extra_labels_opts : + { $$ = false } + | KEEPING_EXTRA + { $$ = true } + ; + grouping_opts : { $$ = clientmodel.LabelNames{} } | GROUP_OP '(' label_list ')' diff --git a/rules/parser.y.go b/rules/parser.y.go index d33cb7941..58cb028f3 100644 --- a/rules/parser.y.go +++ b/rules/parser.y.go @@ -30,16 +30,17 @@ const DURATION = 57350 const NUMBER = 57351 const PERMANENT = 57352 const GROUP_OP = 57353 -const AGGR_OP = 57354 -const CMP_OP = 57355 -const ADDITIVE_OP = 57356 -const MULT_OP = 57357 -const ALERT = 57358 -const IF = 57359 -const FOR = 57360 -const WITH = 57361 -const SUMMARY = 57362 -const DESCRIPTION = 57363 +const KEEPING_EXTRA = 57354 +const AGGR_OP = 57355 +const CMP_OP = 57356 +const ADDITIVE_OP = 57357 +const MULT_OP = 57358 +const ALERT = 57359 +const IF = 57360 +const FOR = 57361 +const WITH = 57362 +const SUMMARY = 57363 +const DESCRIPTION = 57364 var yyToknames = []string{ "START_RULES", @@ -50,6 +51,7 @@ var yyToknames = []string{ "NUMBER", "PERMANENT", "GROUP_OP", + "KEEPING_EXTRA", "AGGR_OP", "CMP_OP", "ADDITIVE_OP", @@ -68,7 +70,7 @@ const yyEofCode = 1 const yyErrCode = 2 const yyMaxDepth = 200 -//line parser.y:191 +//line parser.y:197 //line yacctab:1 @@ -81,79 +83,79 @@ var yyExca = []int{ -2, 1, } -const yyNprod = 36 +const yyNprod = 38 const yyPrivate = 57344 var yyTokenNames []string var yyStates []string -const yyLast = 101 +const yyLast = 103 var yyAct = []int{ - 20, 38, 34, 43, 33, 17, 6, 18, 16, 17, - 19, 15, 59, 18, 16, 17, 16, 17, 15, 27, - 28, 29, 15, 60, 23, 41, 40, 49, 15, 22, - 15, 8, 35, 67, 10, 66, 45, 9, 44, 50, - 18, 16, 17, 46, 47, 51, 18, 16, 17, 53, - 52, 7, 32, 57, 30, 15, 39, 8, 35, 48, - 10, 15, 65, 9, 8, 22, 71, 10, 21, 68, - 9, 61, 42, 14, 37, 56, 62, 7, 26, 13, - 72, 70, 54, 69, 7, 64, 39, 25, 24, 2, - 3, 11, 5, 4, 1, 58, 12, 36, 55, 63, - 31, + 20, 38, 34, 17, 33, 43, 6, 18, 16, 17, + 19, 15, 59, 18, 16, 17, 15, 62, 23, 27, + 28, 29, 15, 46, 47, 41, 40, 49, 15, 22, + 8, 35, 69, 10, 68, 50, 45, 9, 44, 39, + 18, 16, 17, 48, 73, 51, 18, 16, 17, 53, + 52, 7, 32, 57, 30, 15, 8, 35, 37, 10, + 70, 15, 8, 9, 67, 10, 16, 17, 22, 9, + 61, 21, 63, 42, 14, 64, 56, 7, 26, 74, + 15, 13, 72, 7, 54, 71, 66, 39, 25, 24, + 2, 3, 11, 5, 4, 1, 58, 60, 12, 36, + 55, 65, 31, } var yyPact = []int{ - 85, -1000, -1000, 58, 63, -1000, 33, 58, 42, -2, - -1000, -1000, 82, 81, -1000, 70, 58, 58, 58, 27, - -1000, 25, 50, 58, 6, 55, -26, -10, -17, 2, - -1000, 11, -1000, -1000, 33, -1000, 19, -1000, -1000, 37, - 0, 17, 58, -1000, -1000, 51, -1000, 80, 75, 64, - 58, -6, -1000, -1000, -1000, -1000, -3, 33, 52, 68, - 79, 6, -1000, 8, -1000, 49, -1000, 77, 74, -1000, - 45, 73, -1000, + 86, -1000, -1000, 56, 64, -1000, 32, 56, 44, -9, + -1000, -1000, 83, 82, -1000, 70, 56, 56, 56, 26, + -1000, 24, 33, 56, 5, 55, -25, -13, -18, 51, + -1000, 10, -1000, -1000, 32, -1000, -2, -1000, -1000, 20, + -1, 12, 56, -1000, -1000, 50, -1000, 81, 77, 65, + 56, -7, -1000, -1000, -1000, 58, -10, 32, 52, 67, + -1000, -1000, 80, 5, -1000, 6, -1000, 39, -1000, 79, + 75, -1000, 22, 72, -1000, } var yyPgo = []int{ - 0, 100, 99, 98, 1, 97, 0, 2, 4, 96, - 95, 94, 93, 92, 91, + 0, 102, 101, 100, 1, 99, 0, 2, 4, 98, + 97, 96, 95, 94, 93, 92, } var yyR1 = []int{ - 0, 11, 11, 12, 12, 13, 14, 14, 10, 10, + 0, 12, 12, 13, 13, 14, 15, 15, 11, 11, 9, 9, 6, 6, 6, 5, 5, 4, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 3, 3, - 2, 2, 1, 1, 8, 8, + 7, 7, 7, 7, 7, 7, 7, 7, 10, 10, + 3, 3, 2, 2, 1, 1, 8, 8, } var yyR2 = []int{ 0, 2, 2, 0, 2, 1, 5, 11, 0, 2, 0, 1, 0, 3, 2, 1, 3, 3, 3, 2, - 4, 3, 4, 5, 3, 3, 3, 1, 0, 4, - 1, 3, 1, 3, 1, 1, + 4, 3, 4, 6, 3, 3, 3, 1, 0, 1, + 0, 4, 1, 3, 1, 3, 1, 1, } var yyChk = []int{ - -1000, -11, 4, 5, -12, -13, -7, 26, 6, 12, - 9, -14, -9, 16, 10, 28, 14, 15, 13, -7, - -6, 26, 23, 26, 6, 6, 8, -7, -7, -7, - 27, -1, 27, -8, -7, 7, -5, 24, -4, 6, - -7, -6, 17, 29, 27, 25, 24, 25, 22, 27, - 22, -7, -8, -4, 7, -3, 11, -7, -10, 18, - 26, 19, 8, -2, 6, -6, 27, 25, 20, 6, - 7, 21, 7, + -1000, -12, 4, 5, -13, -14, -7, 27, 6, 13, + 9, -15, -9, 17, 10, 29, 15, 16, 14, -7, + -6, 27, 24, 27, 6, 6, 8, -7, -7, -7, + 28, -1, 28, -8, -7, 7, -5, 25, -4, 6, + -7, -6, 18, 30, 28, 26, 25, 26, 23, 28, + 23, -7, -8, -4, 7, -3, 11, -7, -11, 19, + -10, 12, 27, 20, 8, -2, 6, -6, 28, 26, + 21, 6, 7, 22, 7, } var yyDef = []int{ 0, -2, 3, 0, -2, 2, 5, 0, 12, 0, 27, 4, 0, 0, 11, 0, 0, 0, 0, 0, 19, 0, 0, 0, 12, 0, 0, 24, 25, 26, - 18, 0, 21, 32, 34, 35, 0, 14, 15, 0, - 0, 0, 0, 22, 20, 0, 13, 0, 0, 28, - 0, 8, 33, 16, 17, 23, 0, 6, 0, 0, - 0, 12, 9, 0, 30, 0, 29, 0, 0, 31, - 0, 0, 7, + 18, 0, 21, 34, 36, 37, 0, 14, 15, 0, + 0, 0, 0, 22, 20, 0, 13, 0, 0, 30, + 0, 8, 35, 16, 17, 28, 0, 6, 0, 0, + 23, 29, 0, 12, 9, 0, 32, 0, 31, 0, + 0, 33, 0, 0, 7, } var yyTok1 = []int{ @@ -161,20 +163,21 @@ var yyTok1 = []int{ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 26, 27, 3, 3, 25, 3, 3, 3, 3, 3, + 27, 28, 3, 3, 26, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 22, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 23, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 28, 3, 29, 3, 3, 3, 3, 3, 3, + 3, 29, 3, 30, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 23, 3, 24, + 3, 3, 3, 24, 3, 25, } var yyTok2 = []int{ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, + 22, } var yyTok3 = []int{ 0, @@ -483,7 +486,7 @@ yydefault: //line parser.y:139 { var err error - yyVAL.ruleNode, err = NewVectorAggregation(yyS[yypt-4].str, yyS[yypt-2].ruleNode, yyS[yypt-0].labelNameSlice) + yyVAL.ruleNode, err = NewVectorAggregation(yyS[yypt-5].str, yyS[yypt-3].ruleNode, yyS[yypt-1].labelNameSlice, yyS[yypt-0].boolean) if err != nil { yylex.Error(err.Error()); return 1 } } case 24: @@ -512,27 +515,33 @@ yydefault: { yyVAL.ruleNode = ast.NewScalarLiteral(yyS[yypt-0].num)} case 28: //line parser.y:169 - { yyVAL.labelNameSlice = clientmodel.LabelNames{} } + { yyVAL.boolean = false } case 29: //line parser.y:171 - { yyVAL.labelNameSlice = yyS[yypt-1].labelNameSlice } + { yyVAL.boolean = true } case 30: //line parser.y:175 - { yyVAL.labelNameSlice = clientmodel.LabelNames{clientmodel.LabelName(yyS[yypt-0].str)} } + { yyVAL.labelNameSlice = clientmodel.LabelNames{} } case 31: //line parser.y:177 - { yyVAL.labelNameSlice = append(yyVAL.labelNameSlice, clientmodel.LabelName(yyS[yypt-0].str)) } + { yyVAL.labelNameSlice = yyS[yypt-1].labelNameSlice } case 32: //line parser.y:181 - { yyVAL.ruleNodeSlice = []ast.Node{yyS[yypt-0].ruleNode} } + { yyVAL.labelNameSlice = clientmodel.LabelNames{clientmodel.LabelName(yyS[yypt-0].str)} } case 33: //line parser.y:183 - { yyVAL.ruleNodeSlice = append(yyVAL.ruleNodeSlice, yyS[yypt-0].ruleNode) } + { yyVAL.labelNameSlice = append(yyVAL.labelNameSlice, clientmodel.LabelName(yyS[yypt-0].str)) } case 34: //line parser.y:187 - { yyVAL.ruleNode = yyS[yypt-0].ruleNode } + { yyVAL.ruleNodeSlice = []ast.Node{yyS[yypt-0].ruleNode} } case 35: //line parser.y:189 + { yyVAL.ruleNodeSlice = append(yyVAL.ruleNodeSlice, yyS[yypt-0].ruleNode) } + case 36: + //line parser.y:193 + { yyVAL.ruleNode = yyS[yypt-0].ruleNode } + case 37: + //line parser.y:195 { yyVAL.ruleNode = ast.NewStringLiteral(yyS[yypt-0].str) } } goto yystack /* stack new state and value */ diff --git a/rules/rules_test.go b/rules/rules_test.go index dad7b8b7b..57ec793d3 100644 --- a/rules/rules_test.go +++ b/rules/rules_test.go @@ -115,6 +115,22 @@ func TestExpressions(t *testing.T) { output: []string{`http_requests => 3600 @[%v]`}, fullRanges: 0, intervalRanges: 8, + }, { + expr: `SUM(http_requests{instance="0"}) BY(job)`, + output: []string{ + `http_requests{job="api-server"} => 400 @[%v]`, + `http_requests{job="app-server"} => 1200 @[%v]`, + }, + fullRanges: 0, + intervalRanges: 4, + }, { + expr: `SUM(http_requests{instance="0"}) BY(job) KEEPING_EXTRA`, + output: []string{ + `http_requests{instance="0", job="api-server"} => 400 @[%v]`, + `http_requests{instance="0", job="app-server"} => 1200 @[%v]`, + }, + fullRanges: 0, + intervalRanges: 4, }, { expr: `SUM(http_requests) BY (job)`, output: []string{