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