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