linux/tools/perf/util/parse-events.y
<<
>>
Prefs
   1%pure-parser
   2%parse-param {void *_data}
   3%parse-param {void *scanner}
   4%lex-param {void* scanner}
   5
   6%{
   7
   8#define YYDEBUG 1
   9
  10#include <linux/compiler.h>
  11#include <linux/list.h>
  12#include "types.h"
  13#include "util.h"
  14#include "parse-events.h"
  15#include "parse-events-bison.h"
  16
  17extern int parse_events_lex (YYSTYPE* lvalp, void* scanner);
  18
  19#define ABORT_ON(val) \
  20do { \
  21        if (val) \
  22                YYABORT; \
  23} while (0)
  24
  25static inc_group_count(struct list_head *list,
  26                       struct parse_events_evlist *data)
  27{
  28        /* Count groups only have more than 1 members */
  29        if (!list_is_last(list->next, list))
  30                data->nr_groups++;
  31}
  32
  33%}
  34
  35%token PE_START_EVENTS PE_START_TERMS
  36%token PE_VALUE PE_VALUE_SYM_HW PE_VALUE_SYM_SW PE_RAW PE_TERM
  37%token PE_EVENT_NAME
  38%token PE_NAME
  39%token PE_MODIFIER_EVENT PE_MODIFIER_BP
  40%token PE_NAME_CACHE_TYPE PE_NAME_CACHE_OP_RESULT
  41%token PE_PREFIX_MEM PE_PREFIX_RAW PE_PREFIX_GROUP
  42%token PE_ERROR
  43%type <num> PE_VALUE
  44%type <num> PE_VALUE_SYM_HW
  45%type <num> PE_VALUE_SYM_SW
  46%type <num> PE_RAW
  47%type <num> PE_TERM
  48%type <str> PE_NAME
  49%type <str> PE_NAME_CACHE_TYPE
  50%type <str> PE_NAME_CACHE_OP_RESULT
  51%type <str> PE_MODIFIER_EVENT
  52%type <str> PE_MODIFIER_BP
  53%type <str> PE_EVENT_NAME
  54%type <num> value_sym
  55%type <head> event_config
  56%type <term> event_term
  57%type <head> event_pmu
  58%type <head> event_legacy_symbol
  59%type <head> event_legacy_cache
  60%type <head> event_legacy_mem
  61%type <head> event_legacy_tracepoint
  62%type <head> event_legacy_numeric
  63%type <head> event_legacy_raw
  64%type <head> event_def
  65%type <head> event_mod
  66%type <head> event_name
  67%type <head> event
  68%type <head> events
  69%type <head> group_def
  70%type <head> group
  71%type <head> groups
  72
  73%union
  74{
  75        char *str;
  76        u64 num;
  77        struct list_head *head;
  78        struct parse_events_term *term;
  79}
  80%%
  81
  82start:
  83PE_START_EVENTS start_events
  84|
  85PE_START_TERMS  start_terms
  86
  87start_events: groups
  88{
  89        struct parse_events_evlist *data = _data;
  90
  91        parse_events_update_lists($1, &data->list);
  92}
  93
  94groups:
  95groups ',' group
  96{
  97        struct list_head *list  = $1;
  98        struct list_head *group = $3;
  99
 100        parse_events_update_lists(group, list);
 101        $$ = list;
 102}
 103|
 104groups ',' event
 105{
 106        struct list_head *list  = $1;
 107        struct list_head *event = $3;
 108
 109        parse_events_update_lists(event, list);
 110        $$ = list;
 111}
 112|
 113group
 114|
 115event
 116
 117group:
 118group_def ':' PE_MODIFIER_EVENT
 119{
 120        struct list_head *list = $1;
 121
 122        ABORT_ON(parse_events__modifier_group(list, $3));
 123        $$ = list;
 124}
 125|
 126group_def
 127
 128group_def:
 129PE_NAME '{' events '}'
 130{
 131        struct list_head *list = $3;
 132
 133        inc_group_count(list, _data);
 134        parse_events__set_leader($1, list);
 135        $$ = list;
 136}
 137|
 138'{' events '}'
 139{
 140        struct list_head *list = $2;
 141
 142        inc_group_count(list, _data);
 143        parse_events__set_leader(NULL, list);
 144        $$ = list;
 145}
 146
 147events:
 148events ',' event
 149{
 150        struct list_head *event = $3;
 151        struct list_head *list  = $1;
 152
 153        parse_events_update_lists(event, list);
 154        $$ = list;
 155}
 156|
 157event
 158
 159event: event_mod
 160
 161event_mod:
 162event_name PE_MODIFIER_EVENT
 163{
 164        struct list_head *list = $1;
 165
 166        /*
 167         * Apply modifier on all events added by single event definition
 168         * (there could be more events added for multiple tracepoint
 169         * definitions via '*?'.
 170         */
 171        ABORT_ON(parse_events__modifier_event(list, $2, false));
 172        $$ = list;
 173}
 174|
 175event_name
 176
 177event_name:
 178PE_EVENT_NAME event_def
 179{
 180        ABORT_ON(parse_events_name($2, $1));
 181        free($1);
 182        $$ = $2;
 183}
 184|
 185event_def
 186
 187event_def: event_pmu |
 188           event_legacy_symbol |
 189           event_legacy_cache sep_dc |
 190           event_legacy_mem |
 191           event_legacy_tracepoint sep_dc |
 192           event_legacy_numeric sep_dc |
 193           event_legacy_raw sep_dc
 194
 195event_pmu:
 196PE_NAME '/' event_config '/'
 197{
 198        struct parse_events_evlist *data = _data;
 199        struct list_head *list = NULL;
 200
 201        ABORT_ON(parse_events_add_pmu(&list, &data->idx, $1, $3));
 202        parse_events__free_terms($3);
 203        $$ = list;
 204}
 205
 206value_sym:
 207PE_VALUE_SYM_HW
 208|
 209PE_VALUE_SYM_SW
 210
 211event_legacy_symbol:
 212value_sym '/' event_config '/'
 213{
 214        struct parse_events_evlist *data = _data;
 215        struct list_head *list = NULL;
 216        int type = $1 >> 16;
 217        int config = $1 & 255;
 218
 219        ABORT_ON(parse_events_add_numeric(&list, &data->idx,
 220                                          type, config, $3));
 221        parse_events__free_terms($3);
 222        $$ = list;
 223}
 224|
 225value_sym sep_slash_dc
 226{
 227        struct parse_events_evlist *data = _data;
 228        struct list_head *list = NULL;
 229        int type = $1 >> 16;
 230        int config = $1 & 255;
 231
 232        ABORT_ON(parse_events_add_numeric(&list, &data->idx,
 233                                          type, config, NULL));
 234        $$ = list;
 235}
 236
 237event_legacy_cache:
 238PE_NAME_CACHE_TYPE '-' PE_NAME_CACHE_OP_RESULT '-' PE_NAME_CACHE_OP_RESULT
 239{
 240        struct parse_events_evlist *data = _data;
 241        struct list_head *list = NULL;
 242
 243        ABORT_ON(parse_events_add_cache(&list, &data->idx, $1, $3, $5));
 244        $$ = list;
 245}
 246|
 247PE_NAME_CACHE_TYPE '-' PE_NAME_CACHE_OP_RESULT
 248{
 249        struct parse_events_evlist *data = _data;
 250        struct list_head *list = NULL;
 251
 252        ABORT_ON(parse_events_add_cache(&list, &data->idx, $1, $3, NULL));
 253        $$ = list;
 254}
 255|
 256PE_NAME_CACHE_TYPE
 257{
 258        struct parse_events_evlist *data = _data;
 259        struct list_head *list = NULL;
 260
 261        ABORT_ON(parse_events_add_cache(&list, &data->idx, $1, NULL, NULL));
 262        $$ = list;
 263}
 264
 265event_legacy_mem:
 266PE_PREFIX_MEM PE_VALUE ':' PE_MODIFIER_BP sep_dc
 267{
 268        struct parse_events_evlist *data = _data;
 269        struct list_head *list = NULL;
 270
 271        ABORT_ON(parse_events_add_breakpoint(&list, &data->idx,
 272                                             (void *) $2, $4));
 273        $$ = list;
 274}
 275|
 276PE_PREFIX_MEM PE_VALUE sep_dc
 277{
 278        struct parse_events_evlist *data = _data;
 279        struct list_head *list = NULL;
 280
 281        ABORT_ON(parse_events_add_breakpoint(&list, &data->idx,
 282                                             (void *) $2, NULL));
 283        $$ = list;
 284}
 285
 286event_legacy_tracepoint:
 287PE_NAME ':' PE_NAME
 288{
 289        struct parse_events_evlist *data = _data;
 290        struct list_head *list = NULL;
 291
 292        ABORT_ON(parse_events_add_tracepoint(&list, &data->idx, $1, $3));
 293        $$ = list;
 294}
 295
 296event_legacy_numeric:
 297PE_VALUE ':' PE_VALUE
 298{
 299        struct parse_events_evlist *data = _data;
 300        struct list_head *list = NULL;
 301
 302        ABORT_ON(parse_events_add_numeric(&list, &data->idx, (u32)$1, $3, NULL));
 303        $$ = list;
 304}
 305
 306event_legacy_raw:
 307PE_RAW
 308{
 309        struct parse_events_evlist *data = _data;
 310        struct list_head *list = NULL;
 311
 312        ABORT_ON(parse_events_add_numeric(&list, &data->idx,
 313                                          PERF_TYPE_RAW, $1, NULL));
 314        $$ = list;
 315}
 316
 317start_terms: event_config
 318{
 319        struct parse_events_terms *data = _data;
 320        data->terms = $1;
 321}
 322
 323event_config:
 324event_config ',' event_term
 325{
 326        struct list_head *head = $1;
 327        struct parse_events_term *term = $3;
 328
 329        ABORT_ON(!head);
 330        list_add_tail(&term->list, head);
 331        $$ = $1;
 332}
 333|
 334event_term
 335{
 336        struct list_head *head = malloc(sizeof(*head));
 337        struct parse_events_term *term = $1;
 338
 339        ABORT_ON(!head);
 340        INIT_LIST_HEAD(head);
 341        list_add_tail(&term->list, head);
 342        $$ = head;
 343}
 344
 345event_term:
 346PE_NAME '=' PE_NAME
 347{
 348        struct parse_events_term *term;
 349
 350        ABORT_ON(parse_events_term__str(&term, PARSE_EVENTS__TERM_TYPE_USER,
 351                                        $1, $3));
 352        $$ = term;
 353}
 354|
 355PE_NAME '=' PE_VALUE
 356{
 357        struct parse_events_term *term;
 358
 359        ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER,
 360                                        $1, $3));
 361        $$ = term;
 362}
 363|
 364PE_NAME '=' PE_VALUE_SYM_HW
 365{
 366        struct parse_events_term *term;
 367        int config = $3 & 255;
 368
 369        ABORT_ON(parse_events_term__sym_hw(&term, $1, config));
 370        $$ = term;
 371}
 372|
 373PE_NAME
 374{
 375        struct parse_events_term *term;
 376
 377        ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER,
 378                                        $1, 1));
 379        $$ = term;
 380}
 381|
 382PE_VALUE_SYM_HW
 383{
 384        struct parse_events_term *term;
 385        int config = $1 & 255;
 386
 387        ABORT_ON(parse_events_term__sym_hw(&term, NULL, config));
 388        $$ = term;
 389}
 390|
 391PE_TERM '=' PE_NAME
 392{
 393        struct parse_events_term *term;
 394
 395        ABORT_ON(parse_events_term__str(&term, (int)$1, NULL, $3));
 396        $$ = term;
 397}
 398|
 399PE_TERM '=' PE_VALUE
 400{
 401        struct parse_events_term *term;
 402
 403        ABORT_ON(parse_events_term__num(&term, (int)$1, NULL, $3));
 404        $$ = term;
 405}
 406|
 407PE_TERM
 408{
 409        struct parse_events_term *term;
 410
 411        ABORT_ON(parse_events_term__num(&term, (int)$1, NULL, 1));
 412        $$ = term;
 413}
 414
 415sep_dc: ':' |
 416
 417sep_slash_dc: '/' | ':' |
 418
 419%%
 420
 421void parse_events_error(void *data __maybe_unused, void *scanner __maybe_unused,
 422                        char const *msg __maybe_unused)
 423{
 424}
 425