%parse-param {struct list_head *format} %parse-param {char *name} %{ #include <linux/compiler.h> #include <linux/list.h> #include <linux/bitmap.h> #include <string.h> #include "pmu.h" extern int perf_pmu_lex (void); #define ABORT_ON(val) \ do { \ if (val) \ YYABORT; \ } while (0) %} %token PP_CONFIG PP_CONFIG1 PP_CONFIG2 %token PP_VALUE PP_ERROR %type <num> PP_VALUE %type <bits> bit_term %type <bits> bits %union { unsigned long num; DECLARE_BITMAP(bits, PERF_PMU_FORMAT_BITS); } %% format: format format_term | format_term format_term: PP_CONFIG ':' bits { ABORT_ON(perf_pmu__new_format(format, name, PERF_PMU_FORMAT_VALUE_CONFIG, $3)); } | PP_CONFIG1 ':' bits { ABORT_ON(perf_pmu__new_format(format, name, PERF_PMU_FORMAT_VALUE_CONFIG1, $3)); } | PP_CONFIG2 ':' bits { ABORT_ON(perf_pmu__new_format(format, name, PERF_PMU_FORMAT_VALUE_CONFIG2, $3)); } bits: bits ',' bit_term { bitmap_or($$, $1, $3, 64); } | bit_term { memcpy($$, $1, sizeof($1)); } bit_term: PP_VALUE '-' PP_VALUE { perf_pmu__set_format($$, $1, $3); } | PP_VALUE { perf_pmu__set_format($$, $1, 0); } %% void perf_pmu_error(struct list_head *list __used, char *name __used, char const *msg __used) { }