1 %parse-param {struct list_head *expr_head} 2 %define parse.error verbose 3 4 %{ 5 6 #ifndef NDEBUG 7 #define YYDEBUG 1 8 #endif 9 10 #include <stdio.h> 11 #include <string.h> 12 #include <linux/compiler.h> 13 #include <linux/list.h> 14 #include "bpf-filter.h" 15 #include "cgroup.h" 16 17 int perf_bpf_filter_lex(void); 18 19 /* To indicate if the current term needs a pathname or not */ 20 int perf_bpf_filter_needs_path; 21 22 static void perf_bpf_filter_error(struct list_head *expr __maybe_unused, 23 char const *msg) 24 { 25 printf("perf_bpf_filter: %s\n", msg); 26 } 27 28 %} 29 30 %union 31 { 32 unsigned long num; 33 char *path; 34 struct { 35 enum perf_bpf_filter_term term; 36 int part; 37 } sample; 38 enum perf_bpf_filter_op op; 39 struct perf_bpf_filter_expr *expr; 40 } 41 42 %token BFT_SAMPLE BFT_SAMPLE_PATH BFT_OP BFT_ERROR BFT_NUM BFT_LOGICAL_OR BFT_PATH 43 %type <expr> filter_term filter_expr 44 %destructor { free ($$); } <expr> 45 %type <sample> BFT_SAMPLE BFT_SAMPLE_PATH 46 %type <op> BFT_OP 47 %type <num> BFT_NUM 48 %type <path> BFT_PATH 49 50 %% 51 52 filter: 53 filter ',' filter_term 54 { 55 list_add_tail(&$3->list, expr_head); 56 } 57 | 58 filter_term 59 { 60 list_add_tail(&$1->list, expr_head); 61 } 62 63 filter_term: 64 filter_term BFT_LOGICAL_OR filter_expr 65 { 66 struct perf_bpf_filter_expr *expr; 67 68 if ($1->op == PBF_OP_GROUP_BEGIN) { 69 expr = $1; 70 } else { 71 expr = perf_bpf_filter_expr__new(PBF_TERM_NONE, /*part=*/0, 72 PBF_OP_GROUP_BEGIN, /*val=*/1); 73 list_add_tail(&$1->list, &expr->groups); 74 } 75 expr->val++; 76 list_add_tail(&$3->list, &expr->groups); 77 $$ = expr; 78 } 79 | 80 filter_expr 81 { 82 $$ = $1; 83 } 84 85 filter_expr: 86 BFT_SAMPLE BFT_OP BFT_NUM 87 { 88 $$ = perf_bpf_filter_expr__new($1.term, $1.part, $2, $3); 89 } 90 | 91 BFT_SAMPLE_PATH BFT_OP BFT_PATH 92 { 93 struct cgroup *cgrp; 94 unsigned long cgroup_id = 0; 95 96 if ($2 != PBF_OP_EQ && $2 != PBF_OP_NEQ) { 97 printf("perf_bpf_filter: cgroup accepts '==' or '!=' only\n"); 98 YYERROR; 99 } 100 101 cgrp = cgroup__new($3, /*do_open=*/false); 102 if (cgrp && read_cgroup_id(cgrp) == 0) 103 cgroup_id = cgrp->id; 104 105 $$ = perf_bpf_filter_expr__new($1.term, $1.part, $2, cgroup_id); 106 cgroup__put(cgrp); 107 } 108 109 %% 110