github.com/yankunsam/loki/v2@v2.6.3-0.20220817130409-389df5235c27/pkg/logql/syntax/expr.y (about)

     1  %{
     2  package syntax
     3  
     4  import (
     5    "time"
     6    "github.com/prometheus/prometheus/model/labels"
     7    "github.com/grafana/loki/pkg/logql/log"
     8  
     9  )
    10  %}
    11  
    12  %union{
    13    Expr                    Expr
    14    Filter                  labels.MatchType
    15    Grouping                *Grouping
    16    Labels                  []string
    17    LogExpr                 LogSelectorExpr
    18    LogRangeExpr            *LogRange
    19    Matcher                 *labels.Matcher
    20    Matchers                []*labels.Matcher
    21    RangeAggregationExpr    SampleExpr
    22    RangeOp                 string
    23    ConvOp                  string
    24    Selector                []*labels.Matcher
    25    VectorAggregationExpr   SampleExpr
    26    MetricExpr              SampleExpr
    27    VectorOp                string
    28    FilterOp                string
    29    BinOpExpr               SampleExpr
    30    LabelReplaceExpr        SampleExpr
    31    binOp                   string
    32    bytes                   uint64
    33    str                     string
    34    duration                time.Duration
    35    LiteralExpr             *LiteralExpr
    36    BinOpModifier           *BinOpOptions
    37    BoolModifier            *BinOpOptions
    38    OnOrIgnoringModifier    *BinOpOptions
    39    LabelParser             *LabelParserExpr
    40    LineFilters             *LineFilterExpr
    41    LineFilter              *LineFilterExpr
    42    PipelineExpr            MultiStageExpr
    43    PipelineStage           StageExpr
    44    BytesFilter             log.LabelFilterer
    45    NumberFilter            log.LabelFilterer
    46    DurationFilter          log.LabelFilterer
    47    LabelFilter             log.LabelFilterer
    48    UnitFilter              log.LabelFilterer
    49    IPLabelFilter           log.LabelFilterer
    50    LineFormatExpr          *LineFmtExpr
    51    LabelFormatExpr         *LabelFmtExpr
    52    LabelFormat             log.LabelFmt
    53    LabelsFormat            []log.LabelFmt
    54    JSONExpressionParser    *JSONExpressionParser
    55    JSONExpression          log.JSONExpression
    56    JSONExpressionList      []log.JSONExpression
    57    UnwrapExpr              *UnwrapExpr
    58    OffsetExpr              *OffsetExpr
    59  }
    60  
    61  %start root
    62  
    63  %type <Expr>                  expr
    64  %type <Filter>                filter
    65  %type <Grouping>              grouping
    66  %type <Labels>                labels
    67  %type <LogExpr>               logExpr
    68  %type <MetricExpr>            metricExpr
    69  %type <LogRangeExpr>          logRangeExpr
    70  %type <Matcher>               matcher
    71  %type <Matchers>              matchers
    72  %type <RangeAggregationExpr>  rangeAggregationExpr
    73  %type <RangeOp>               rangeOp
    74  %type <ConvOp>                convOp
    75  %type <Selector>              selector
    76  %type <VectorAggregationExpr> vectorAggregationExpr
    77  %type <VectorOp>              vectorOp
    78  %type <FilterOp>              filterOp
    79  %type <BinOpExpr>             binOpExpr
    80  %type <LiteralExpr>           literalExpr
    81  %type <LabelReplaceExpr>      labelReplaceExpr
    82  %type <BinOpModifier>         binOpModifier
    83  %type <BoolModifier>          boolModifier
    84  %type <OnOrIgnoringModifier>  onOrIgnoringModifier
    85  %type <LabelParser>           labelParser
    86  %type <PipelineExpr>          pipelineExpr
    87  %type <PipelineStage>         pipelineStage
    88  %type <BytesFilter>           bytesFilter
    89  %type <NumberFilter>          numberFilter
    90  %type <DurationFilter>        durationFilter
    91  %type <LabelFilter>           labelFilter
    92  %type <LineFilters>           lineFilters
    93  %type <LineFilter>            lineFilter
    94  %type <LineFormatExpr>        lineFormatExpr
    95  %type <LabelFormatExpr>       labelFormatExpr
    96  %type <LabelFormat>           labelFormat
    97  %type <LabelsFormat>          labelsFormat
    98  %type <JSONExpressionParser>  jsonExpressionParser
    99  %type <JSONExpression>        jsonExpression
   100  %type <JSONExpressionList>    jsonExpressionList
   101  %type <UnwrapExpr>            unwrapExpr
   102  %type <UnitFilter>            unitFilter
   103  %type <IPLabelFilter>         ipLabelFilter
   104  %type <OffsetExpr>            offsetExpr
   105  
   106  %token <bytes> BYTES
   107  %token <str>      IDENTIFIER STRING NUMBER
   108  %token <duration> DURATION RANGE
   109  %token <val>      MATCHERS LABELS EQ RE NRE OPEN_BRACE CLOSE_BRACE OPEN_BRACKET CLOSE_BRACKET COMMA DOT PIPE_MATCH PIPE_EXACT
   110                    OPEN_PARENTHESIS CLOSE_PARENTHESIS BY WITHOUT COUNT_OVER_TIME RATE RATE_COUNTER SUM AVG MAX MIN COUNT STDDEV STDVAR BOTTOMK TOPK
   111                    BYTES_OVER_TIME BYTES_RATE BOOL JSON REGEXP LOGFMT PIPE LINE_FMT LABEL_FMT UNWRAP AVG_OVER_TIME SUM_OVER_TIME MIN_OVER_TIME
   112                    MAX_OVER_TIME STDVAR_OVER_TIME STDDEV_OVER_TIME QUANTILE_OVER_TIME BYTES_CONV DURATION_CONV DURATION_SECONDS_CONV
   113                    FIRST_OVER_TIME LAST_OVER_TIME ABSENT_OVER_TIME LABEL_REPLACE UNPACK OFFSET PATTERN IP ON IGNORING GROUP_LEFT GROUP_RIGHT
   114  
   115  // Operators are listed with increasing precedence.
   116  %left <binOp> OR
   117  %left <binOp> AND UNLESS
   118  %left <binOp> CMP_EQ NEQ LT LTE GT GTE
   119  %left <binOp> ADD SUB
   120  %left <binOp> MUL DIV MOD
   121  %right <binOp> POW
   122  
   123  %%
   124  
   125  root: expr { exprlex.(*parser).expr = $1 };
   126  
   127  expr:
   128        logExpr                                      { $$ = $1 }
   129      | metricExpr                                   { $$ = $1 }
   130      ;
   131  
   132  metricExpr:
   133        rangeAggregationExpr                          { $$ = $1 }
   134      | vectorAggregationExpr                         { $$ = $1 }
   135      | binOpExpr                                     { $$ = $1 }
   136      | literalExpr                                   { $$ = $1 }
   137      | labelReplaceExpr                              { $$ = $1 }
   138      | OPEN_PARENTHESIS metricExpr CLOSE_PARENTHESIS { $$ = $2 }
   139      ;
   140  
   141  logExpr:
   142        selector                                    { $$ = newMatcherExpr($1)}
   143      | selector pipelineExpr                       { $$ = newPipelineExpr(newMatcherExpr($1), $2)}
   144      | OPEN_PARENTHESIS logExpr CLOSE_PARENTHESIS  { $$ = $2 }
   145      ;
   146  
   147  logRangeExpr:
   148        selector RANGE                                                                        { $$ = newLogRange(newMatcherExpr($1), $2, nil, nil ) }
   149      | selector RANGE offsetExpr                                                             { $$ = newLogRange(newMatcherExpr($1), $2, nil, $3 ) }
   150      | OPEN_PARENTHESIS selector CLOSE_PARENTHESIS RANGE                                     { $$ = newLogRange(newMatcherExpr($2), $4, nil, nil ) }
   151      | OPEN_PARENTHESIS selector CLOSE_PARENTHESIS RANGE offsetExpr                          { $$ = newLogRange(newMatcherExpr($2), $4, nil, $5 ) }
   152      | selector RANGE unwrapExpr                                                             { $$ = newLogRange(newMatcherExpr($1), $2, $3, nil ) }
   153      | selector RANGE offsetExpr unwrapExpr                                                  { $$ = newLogRange(newMatcherExpr($1), $2, $4, $3 ) }
   154      | OPEN_PARENTHESIS selector CLOSE_PARENTHESIS RANGE unwrapExpr                          { $$ = newLogRange(newMatcherExpr($2), $4, $5, nil ) }
   155      | OPEN_PARENTHESIS selector CLOSE_PARENTHESIS RANGE offsetExpr unwrapExpr               { $$ = newLogRange(newMatcherExpr($2), $4, $6, $5 ) }
   156      | selector unwrapExpr RANGE                                                             { $$ = newLogRange(newMatcherExpr($1), $3, $2, nil ) }
   157      | selector unwrapExpr RANGE offsetExpr                                                  { $$ = newLogRange(newMatcherExpr($1), $3, $2, $4 ) }
   158      | OPEN_PARENTHESIS selector unwrapExpr CLOSE_PARENTHESIS RANGE                          { $$ = newLogRange(newMatcherExpr($2), $5, $3, nil ) }
   159      | OPEN_PARENTHESIS selector unwrapExpr CLOSE_PARENTHESIS RANGE offsetExpr               { $$ = newLogRange(newMatcherExpr($2), $5, $3, $6 ) }
   160      | selector pipelineExpr RANGE                                                           { $$ = newLogRange(newPipelineExpr(newMatcherExpr($1), $2), $3, nil, nil ) }
   161      | selector pipelineExpr RANGE offsetExpr                                                { $$ = newLogRange(newPipelineExpr(newMatcherExpr($1), $2), $3, nil, $4 ) }
   162      | OPEN_PARENTHESIS selector pipelineExpr CLOSE_PARENTHESIS RANGE                        { $$ = newLogRange(newPipelineExpr(newMatcherExpr($2), $3), $5, nil, nil ) }
   163      | OPEN_PARENTHESIS selector pipelineExpr CLOSE_PARENTHESIS RANGE offsetExpr             { $$ = newLogRange(newPipelineExpr(newMatcherExpr($2), $3), $5, nil, $6 ) }
   164      | selector pipelineExpr unwrapExpr RANGE                                                { $$ = newLogRange(newPipelineExpr(newMatcherExpr($1), $2), $4, $3, nil ) }
   165      | selector pipelineExpr unwrapExpr RANGE offsetExpr                                     { $$ = newLogRange(newPipelineExpr(newMatcherExpr($1), $2), $4, $3, $5 ) }
   166      | OPEN_PARENTHESIS selector pipelineExpr unwrapExpr CLOSE_PARENTHESIS RANGE             { $$ = newLogRange(newPipelineExpr(newMatcherExpr($2), $3), $6, $4, nil ) }
   167      | OPEN_PARENTHESIS selector pipelineExpr unwrapExpr CLOSE_PARENTHESIS RANGE offsetExpr  { $$ = newLogRange(newPipelineExpr(newMatcherExpr($2), $3), $6, $4, $7 ) }
   168      | selector RANGE pipelineExpr                                                           { $$ = newLogRange(newPipelineExpr(newMatcherExpr($1), $3), $2, nil, nil) }
   169      | selector RANGE offsetExpr pipelineExpr                                                { $$ = newLogRange(newPipelineExpr(newMatcherExpr($1), $4), $2, nil, $3 ) }
   170      | selector RANGE pipelineExpr unwrapExpr                                                { $$ = newLogRange(newPipelineExpr(newMatcherExpr($1), $3), $2, $4, nil ) }
   171      | selector RANGE offsetExpr pipelineExpr unwrapExpr                                     { $$ = newLogRange(newPipelineExpr(newMatcherExpr($1), $4), $2, $5, $3 ) }
   172      | OPEN_PARENTHESIS logRangeExpr CLOSE_PARENTHESIS                                       { $$ = $2 }
   173      | logRangeExpr error
   174      ;
   175  
   176  unwrapExpr:
   177      PIPE UNWRAP IDENTIFIER                                                   { $$ = newUnwrapExpr($3, "")}
   178    | PIPE UNWRAP convOp OPEN_PARENTHESIS IDENTIFIER CLOSE_PARENTHESIS         { $$ = newUnwrapExpr($5, $3)}
   179    | unwrapExpr PIPE labelFilter                                              { $$ = $1.addPostFilter($3) }
   180    ;
   181  
   182  convOp:
   183      BYTES_CONV              { $$ = OpConvBytes }
   184    | DURATION_CONV           { $$ = OpConvDuration }
   185    | DURATION_SECONDS_CONV   { $$ = OpConvDurationSeconds }
   186    ;
   187  
   188  rangeAggregationExpr:
   189        rangeOp OPEN_PARENTHESIS logRangeExpr CLOSE_PARENTHESIS                        { $$ = newRangeAggregationExpr($3, $1, nil, nil) }
   190      | rangeOp OPEN_PARENTHESIS NUMBER COMMA logRangeExpr CLOSE_PARENTHESIS           { $$ = newRangeAggregationExpr($5, $1, nil, &$3) }
   191      | rangeOp OPEN_PARENTHESIS logRangeExpr CLOSE_PARENTHESIS grouping               { $$ = newRangeAggregationExpr($3, $1, $5, nil) }
   192      | rangeOp OPEN_PARENTHESIS NUMBER COMMA logRangeExpr CLOSE_PARENTHESIS grouping  { $$ = newRangeAggregationExpr($5, $1, $7, &$3) }
   193      ;
   194  
   195  vectorAggregationExpr:
   196      // Aggregations with 1 argument.
   197        vectorOp OPEN_PARENTHESIS metricExpr CLOSE_PARENTHESIS                               { $$ = mustNewVectorAggregationExpr($3, $1, nil, nil) }
   198      | vectorOp grouping OPEN_PARENTHESIS metricExpr CLOSE_PARENTHESIS                      { $$ = mustNewVectorAggregationExpr($4, $1, $2, nil,) }
   199      | vectorOp OPEN_PARENTHESIS metricExpr CLOSE_PARENTHESIS grouping                      { $$ = mustNewVectorAggregationExpr($3, $1, $5, nil) }
   200      // Aggregations with 2 arguments.
   201      | vectorOp OPEN_PARENTHESIS NUMBER COMMA metricExpr CLOSE_PARENTHESIS                 { $$ = mustNewVectorAggregationExpr($5, $1, nil, &$3) }
   202      | vectorOp OPEN_PARENTHESIS NUMBER COMMA metricExpr CLOSE_PARENTHESIS grouping        { $$ = mustNewVectorAggregationExpr($5, $1, $7, &$3) }
   203      | vectorOp grouping OPEN_PARENTHESIS NUMBER COMMA metricExpr CLOSE_PARENTHESIS        { $$ = mustNewVectorAggregationExpr($6, $1, $2, &$4) }
   204      ;
   205  
   206  labelReplaceExpr:
   207      LABEL_REPLACE OPEN_PARENTHESIS metricExpr COMMA STRING COMMA STRING COMMA STRING COMMA STRING CLOSE_PARENTHESIS
   208        { $$ = mustNewLabelReplaceExpr($3, $5, $7, $9, $11)}
   209      ;
   210  
   211  filter:
   212        PIPE_MATCH                       { $$ = labels.MatchRegexp }
   213      | PIPE_EXACT                       { $$ = labels.MatchEqual }
   214      | NRE                              { $$ = labels.MatchNotRegexp }
   215      | NEQ                              { $$ = labels.MatchNotEqual }
   216      ;
   217  
   218  selector:
   219        OPEN_BRACE matchers CLOSE_BRACE  { $$ = $2 }
   220      | OPEN_BRACE matchers error        { $$ = $2 }
   221      | OPEN_BRACE error CLOSE_BRACE     { }
   222      ;
   223  
   224  matchers:
   225        matcher                          { $$ = []*labels.Matcher{ $1 } }
   226      | matchers COMMA matcher           { $$ = append($1, $3) }
   227      ;
   228  
   229  matcher:
   230        IDENTIFIER EQ STRING             { $$ = mustNewMatcher(labels.MatchEqual, $1, $3) }
   231      | IDENTIFIER NEQ STRING            { $$ = mustNewMatcher(labels.MatchNotEqual, $1, $3) }
   232      | IDENTIFIER RE STRING             { $$ = mustNewMatcher(labels.MatchRegexp, $1, $3) }
   233      | IDENTIFIER NRE STRING            { $$ = mustNewMatcher(labels.MatchNotRegexp, $1, $3) }
   234      ;
   235  
   236  pipelineExpr:
   237        pipelineStage                  { $$ = MultiStageExpr{ $1 } }
   238      | pipelineExpr pipelineStage     { $$ = append($1, $2)}
   239      ;
   240  
   241  pipelineStage:
   242     lineFilters                   { $$ = $1 }
   243    | PIPE labelParser             { $$ = $2 }
   244    | PIPE jsonExpressionParser    { $$ = $2 }
   245    | PIPE labelFilter             { $$ = &LabelFilterExpr{LabelFilterer: $2 }}
   246    | PIPE lineFormatExpr          { $$ = $2 }
   247    | PIPE labelFormatExpr         { $$ = $2 }
   248    ;
   249  
   250  filterOp:
   251    IP { $$ = OpFilterIP }
   252    ;
   253  
   254  lineFilter:
   255      filter STRING                                                   { $$ = newLineFilterExpr($1, "", $2) }
   256    | filter filterOp OPEN_PARENTHESIS STRING CLOSE_PARENTHESIS       { $$ = newLineFilterExpr($1, $2, $4) }
   257    ;
   258  
   259  lineFilters:
   260      lineFilter                { $$ = $1 }
   261    | lineFilters lineFilter    { $$ = newNestedLineFilterExpr($1, $2) }
   262    ;
   263  
   264  labelParser:
   265      JSON           { $$ = newLabelParserExpr(OpParserTypeJSON, "") }
   266    | LOGFMT         { $$ = newLabelParserExpr(OpParserTypeLogfmt, "") }
   267    | REGEXP STRING  { $$ = newLabelParserExpr(OpParserTypeRegexp, $2) }
   268    | UNPACK         { $$ = newLabelParserExpr(OpParserTypeUnpack, "") }
   269    | PATTERN STRING { $$ = newLabelParserExpr(OpParserTypePattern, $2) }
   270    ;
   271  
   272  jsonExpressionParser:
   273      JSON jsonExpressionList { $$ = newJSONExpressionParser($2) }
   274  
   275  lineFormatExpr: LINE_FMT STRING { $$ = newLineFmtExpr($2) };
   276  
   277  labelFormat:
   278       IDENTIFIER EQ IDENTIFIER { $$ = log.NewRenameLabelFmt($1, $3)}
   279    |  IDENTIFIER EQ STRING     { $$ = log.NewTemplateLabelFmt($1, $3)}
   280    ;
   281  
   282  labelsFormat:
   283      labelFormat                    { $$ = []log.LabelFmt{ $1 } }
   284    | labelsFormat COMMA labelFormat { $$ = append($1, $3) }
   285    | labelsFormat COMMA error
   286    ;
   287  
   288  labelFormatExpr: LABEL_FMT labelsFormat { $$ = newLabelFmtExpr($2) };
   289  
   290  labelFilter:
   291        matcher                                        { $$ = log.NewStringLabelFilter($1) }
   292      | ipLabelFilter                                       { $$ = $1 }
   293      | unitFilter                                     { $$ = $1 }
   294      | numberFilter                                   { $$ = $1 }
   295      | OPEN_PARENTHESIS labelFilter CLOSE_PARENTHESIS { $$ = $2 }
   296      | labelFilter labelFilter                        { $$ = log.NewAndLabelFilter($1, $2 ) }
   297      | labelFilter AND labelFilter                    { $$ = log.NewAndLabelFilter($1, $3 ) }
   298      | labelFilter COMMA labelFilter                  { $$ = log.NewAndLabelFilter($1, $3 ) }
   299      | labelFilter OR labelFilter                     { $$ = log.NewOrLabelFilter($1, $3 ) }
   300      ;
   301  
   302  jsonExpression:
   303      IDENTIFIER EQ STRING { $$ = log.NewJSONExpr($1, $3) }
   304    | IDENTIFIER { $$ = log.NewJSONExpr($1, $1) }
   305  
   306  jsonExpressionList:
   307      jsonExpression                          { $$ = []log.JSONExpression{$1} }
   308    | jsonExpressionList COMMA jsonExpression { $$ = append($1, $3) }
   309    ;
   310  
   311  ipLabelFilter:
   312      IDENTIFIER EQ IP OPEN_PARENTHESIS STRING CLOSE_PARENTHESIS { $$ = log.NewIPLabelFilter($5, $1,log.LabelFilterEqual) }
   313    | IDENTIFIER NEQ IP OPEN_PARENTHESIS STRING CLOSE_PARENTHESIS { $$ = log.NewIPLabelFilter($5, $1, log.LabelFilterNotEqual) }
   314    ;
   315  
   316  unitFilter:
   317        durationFilter { $$ = $1 }
   318      | bytesFilter    { $$ = $1 }
   319  
   320  durationFilter:
   321        IDENTIFIER GT DURATION      { $$ = log.NewDurationLabelFilter(log.LabelFilterGreaterThan, $1, $3) }
   322      | IDENTIFIER GTE DURATION     { $$ = log.NewDurationLabelFilter(log.LabelFilterGreaterThanOrEqual, $1, $3) }
   323      | IDENTIFIER LT DURATION      { $$ = log.NewDurationLabelFilter(log.LabelFilterLesserThan, $1, $3) }
   324      | IDENTIFIER LTE DURATION     { $$ = log.NewDurationLabelFilter(log.LabelFilterLesserThanOrEqual, $1, $3) }
   325      | IDENTIFIER NEQ DURATION     { $$ = log.NewDurationLabelFilter(log.LabelFilterNotEqual, $1, $3) }
   326      | IDENTIFIER EQ DURATION      { $$ = log.NewDurationLabelFilter(log.LabelFilterEqual, $1, $3) }
   327      | IDENTIFIER CMP_EQ DURATION  { $$ = log.NewDurationLabelFilter(log.LabelFilterEqual, $1, $3) }
   328      ;
   329  
   330  bytesFilter:
   331        IDENTIFIER GT BYTES     { $$ = log.NewBytesLabelFilter(log.LabelFilterGreaterThan, $1, $3) }
   332      | IDENTIFIER GTE BYTES    { $$ = log.NewBytesLabelFilter(log.LabelFilterGreaterThanOrEqual, $1, $3) }
   333      | IDENTIFIER LT BYTES     { $$ = log.NewBytesLabelFilter(log.LabelFilterLesserThan, $1, $3) }
   334      | IDENTIFIER LTE BYTES    { $$ = log.NewBytesLabelFilter(log.LabelFilterLesserThanOrEqual, $1, $3) }
   335      | IDENTIFIER NEQ BYTES    { $$ = log.NewBytesLabelFilter(log.LabelFilterNotEqual, $1, $3) }
   336      | IDENTIFIER EQ BYTES     { $$ = log.NewBytesLabelFilter(log.LabelFilterEqual, $1, $3) }
   337      | IDENTIFIER CMP_EQ BYTES { $$ = log.NewBytesLabelFilter(log.LabelFilterEqual, $1, $3) }
   338      ;
   339  
   340  numberFilter:
   341        IDENTIFIER GT NUMBER      { $$ = log.NewNumericLabelFilter(log.LabelFilterGreaterThan, $1, mustNewFloat($3))}
   342      | IDENTIFIER GTE NUMBER     { $$ = log.NewNumericLabelFilter(log.LabelFilterGreaterThanOrEqual, $1, mustNewFloat($3))}
   343      | IDENTIFIER LT NUMBER      { $$ = log.NewNumericLabelFilter(log.LabelFilterLesserThan, $1, mustNewFloat($3))}
   344      | IDENTIFIER LTE NUMBER     { $$ = log.NewNumericLabelFilter(log.LabelFilterLesserThanOrEqual, $1, mustNewFloat($3))}
   345      | IDENTIFIER NEQ NUMBER     { $$ = log.NewNumericLabelFilter(log.LabelFilterNotEqual, $1, mustNewFloat($3))}
   346      | IDENTIFIER EQ NUMBER      { $$ = log.NewNumericLabelFilter(log.LabelFilterEqual, $1, mustNewFloat($3))}
   347      | IDENTIFIER CMP_EQ NUMBER  { $$ = log.NewNumericLabelFilter(log.LabelFilterEqual, $1, mustNewFloat($3))}
   348      ;
   349  
   350  // Operator precedence only works if each of these is listed separately.
   351  binOpExpr:
   352           expr OR binOpModifier expr          { $$ = mustNewBinOpExpr("or", $3, $1, $4) }
   353           | expr AND binOpModifier expr       { $$ = mustNewBinOpExpr("and", $3, $1, $4) }
   354           | expr UNLESS binOpModifier expr    { $$ = mustNewBinOpExpr("unless", $3, $1, $4) }
   355           | expr ADD binOpModifier expr       { $$ = mustNewBinOpExpr("+", $3, $1, $4) }
   356           | expr SUB binOpModifier expr       { $$ = mustNewBinOpExpr("-", $3, $1, $4) }
   357           | expr MUL binOpModifier expr       { $$ = mustNewBinOpExpr("*", $3, $1, $4) }
   358           | expr DIV binOpModifier expr       { $$ = mustNewBinOpExpr("/", $3, $1, $4) }
   359           | expr MOD binOpModifier expr       { $$ = mustNewBinOpExpr("%", $3, $1, $4) }
   360           | expr POW binOpModifier expr       { $$ = mustNewBinOpExpr("^", $3, $1, $4) }
   361           | expr CMP_EQ binOpModifier expr    { $$ = mustNewBinOpExpr("==", $3, $1, $4) }
   362           | expr NEQ binOpModifier expr       { $$ = mustNewBinOpExpr("!=", $3, $1, $4) }
   363           | expr GT binOpModifier expr        { $$ = mustNewBinOpExpr(">", $3, $1, $4) }
   364           | expr GTE binOpModifier expr       { $$ = mustNewBinOpExpr(">=", $3, $1, $4) }
   365           | expr LT binOpModifier expr        { $$ = mustNewBinOpExpr("<", $3, $1, $4) }
   366           | expr LTE binOpModifier expr       { $$ = mustNewBinOpExpr("<=", $3, $1, $4) }
   367           ;
   368  
   369  boolModifier:
   370  		{
   371  		 $$ = &BinOpOptions{VectorMatching: &VectorMatching{Card: CardOneToOne}}
   372          	}
   373          | BOOL
   374          	{
   375          	 $$ = &BinOpOptions{VectorMatching: &VectorMatching{Card: CardOneToOne}, ReturnBool:true}
   376          	}
   377          ;
   378  
   379  onOrIgnoringModifier:
   380      	boolModifier ON OPEN_PARENTHESIS labels CLOSE_PARENTHESIS
   381  		{
   382  		$$ = $1
   383      		$$.VectorMatching.On=true
   384      		$$.VectorMatching.MatchingLabels=$4
   385  		}
   386  	| boolModifier ON OPEN_PARENTHESIS CLOSE_PARENTHESIS
   387  		{
   388  		$$ = $1
   389  		$$.VectorMatching.On=true
   390  		}
   391  	| boolModifier IGNORING OPEN_PARENTHESIS labels CLOSE_PARENTHESIS
   392  		{
   393  		$$ = $1
   394      		$$.VectorMatching.MatchingLabels=$4
   395  		}
   396  	| boolModifier IGNORING OPEN_PARENTHESIS CLOSE_PARENTHESIS
   397  		{
   398  		$$ = $1
   399  		}
   400  	;
   401  
   402  binOpModifier:
   403  	boolModifier {$$ = $1 }
   404   	| onOrIgnoringModifier {$$ = $1 }
   405   	| onOrIgnoringModifier GROUP_LEFT
   406                  	{
   407                          $$ = $1
   408                          $$.VectorMatching.Card = CardManyToOne
   409                          }
   410   	| onOrIgnoringModifier GROUP_LEFT OPEN_PARENTHESIS CLOSE_PARENTHESIS
   411          	{
   412                  $$ = $1
   413                  $$.VectorMatching.Card = CardManyToOne
   414                  }
   415   	| onOrIgnoringModifier GROUP_LEFT OPEN_PARENTHESIS labels CLOSE_PARENTHESIS
   416                  {
   417                  $$ = $1
   418                  $$.VectorMatching.Card = CardManyToOne
   419                  $$.VectorMatching.Include = $4
   420                  }
   421          | onOrIgnoringModifier GROUP_RIGHT
   422          	{
   423                  $$ = $1
   424                  $$.VectorMatching.Card = CardOneToMany
   425                  }
   426   	| onOrIgnoringModifier GROUP_RIGHT OPEN_PARENTHESIS CLOSE_PARENTHESIS
   427                  {
   428                  $$ = $1
   429                  $$.VectorMatching.Card = CardOneToMany
   430                  }
   431   	| onOrIgnoringModifier GROUP_RIGHT OPEN_PARENTHESIS labels CLOSE_PARENTHESIS
   432                  {
   433                  $$ = $1
   434                  $$.VectorMatching.Card = CardOneToMany
   435                  $$.VectorMatching.Include = $4
   436                  }
   437          ;
   438  
   439  literalExpr:
   440             NUMBER         { $$ = mustNewLiteralExpr( $1, false ) }
   441             | ADD NUMBER   { $$ = mustNewLiteralExpr( $2, false ) }
   442             | SUB NUMBER   { $$ = mustNewLiteralExpr( $2, true ) }
   443             ;
   444  
   445  vectorOp:
   446          SUM     { $$ = OpTypeSum }
   447        | AVG     { $$ = OpTypeAvg }
   448        | COUNT   { $$ = OpTypeCount }
   449        | MAX     { $$ = OpTypeMax }
   450        | MIN     { $$ = OpTypeMin }
   451        | STDDEV  { $$ = OpTypeStddev }
   452        | STDVAR  { $$ = OpTypeStdvar }
   453        | BOTTOMK { $$ = OpTypeBottomK }
   454        | TOPK    { $$ = OpTypeTopK }
   455        ;
   456  
   457  rangeOp:
   458        COUNT_OVER_TIME    { $$ = OpRangeTypeCount }
   459      | RATE               { $$ = OpRangeTypeRate }
   460      | RATE_COUNTER       { $$ = OpRangeTypeRateCounter }
   461      | BYTES_OVER_TIME    { $$ = OpRangeTypeBytes }
   462      | BYTES_RATE         { $$ = OpRangeTypeBytesRate }
   463      | AVG_OVER_TIME      { $$ = OpRangeTypeAvg }
   464      | SUM_OVER_TIME      { $$ = OpRangeTypeSum }
   465      | MIN_OVER_TIME      { $$ = OpRangeTypeMin }
   466      | MAX_OVER_TIME      { $$ = OpRangeTypeMax }
   467      | STDVAR_OVER_TIME   { $$ = OpRangeTypeStdvar }
   468      | STDDEV_OVER_TIME   { $$ = OpRangeTypeStddev }
   469      | QUANTILE_OVER_TIME { $$ = OpRangeTypeQuantile }
   470      | FIRST_OVER_TIME    { $$ = OpRangeTypeFirst }
   471      | LAST_OVER_TIME     { $$ = OpRangeTypeLast }
   472      | ABSENT_OVER_TIME   { $$ = OpRangeTypeAbsent }
   473      ;
   474  
   475  offsetExpr:
   476      OFFSET DURATION { $$ = newOffsetExpr( $2 ) }
   477  
   478  labels:
   479        IDENTIFIER                 { $$ = []string{ $1 } }
   480      | labels COMMA IDENTIFIER    { $$ = append($1, $3) }
   481      ;
   482  
   483  grouping:
   484        BY OPEN_PARENTHESIS labels CLOSE_PARENTHESIS        { $$ = &Grouping{ Without: false , Groups: $3 } }
   485      | WITHOUT OPEN_PARENTHESIS labels CLOSE_PARENTHESIS   { $$ = &Grouping{ Without: true , Groups: $3 } }
   486      | BY OPEN_PARENTHESIS CLOSE_PARENTHESIS               { $$ = &Grouping{ Without: false , Groups: nil } }
   487      | WITHOUT OPEN_PARENTHESIS CLOSE_PARENTHESIS          { $$ = &Grouping{ Without: true , Groups: nil } }
   488      ;
   489  %%