0001 %define api.pure full
0002 %parse-param {void *_parse_state}
0003 %parse-param {void *scanner}
0004 %lex-param {void* scanner}
0005 %locations
0006
0007 %{
0008
0009 #define YYDEBUG 1
0010
0011 #include <fnmatch.h>
0012 #include <stdio.h>
0013 #include <linux/compiler.h>
0014 #include <linux/types.h>
0015 #include <linux/zalloc.h>
0016 #include "pmu.h"
0017 #include "evsel.h"
0018 #include "parse-events.h"
0019 #include "parse-events-bison.h"
0020
0021 void parse_events_error(YYLTYPE *loc, void *parse_state, void *scanner, char const *msg);
0022
0023 #define ABORT_ON(val) \
0024 do { \
0025 if (val) \
0026 YYABORT; \
0027 } while (0)
0028
0029 static struct list_head* alloc_list(void)
0030 {
0031 struct list_head *list;
0032
0033 list = malloc(sizeof(*list));
0034 if (!list)
0035 return NULL;
0036
0037 INIT_LIST_HEAD(list);
0038 return list;
0039 }
0040
0041 static void free_list_evsel(struct list_head* list_evsel)
0042 {
0043 struct evsel *evsel, *tmp;
0044
0045 list_for_each_entry_safe(evsel, tmp, list_evsel, core.node) {
0046 list_del_init(&evsel->core.node);
0047 evsel__delete(evsel);
0048 }
0049 free(list_evsel);
0050 }
0051
0052 static void inc_group_count(struct list_head *list,
0053 struct parse_events_state *parse_state)
0054 {
0055 /* Count groups only have more than 1 members */
0056 if (!list_is_last(list->next, list))
0057 parse_state->nr_groups++;
0058 }
0059
0060 %}
0061
0062 %token PE_START_EVENTS PE_START_TERMS
0063 %token PE_VALUE PE_VALUE_SYM_HW PE_VALUE_SYM_SW PE_RAW PE_TERM
0064 %token PE_VALUE_SYM_TOOL
0065 %token PE_EVENT_NAME
0066 %token PE_NAME
0067 %token PE_BPF_OBJECT PE_BPF_SOURCE
0068 %token PE_MODIFIER_EVENT PE_MODIFIER_BP
0069 %token PE_NAME_CACHE_TYPE PE_NAME_CACHE_OP_RESULT
0070 %token PE_PREFIX_MEM PE_PREFIX_RAW PE_PREFIX_GROUP
0071 %token PE_ERROR
0072 %token PE_PMU_EVENT_PRE PE_PMU_EVENT_SUF PE_PMU_EVENT_SUF2 PE_KERNEL_PMU_EVENT PE_PMU_EVENT_FAKE
0073 %token PE_ARRAY_ALL PE_ARRAY_RANGE
0074 %token PE_DRV_CFG_TERM
0075 %type <num> PE_VALUE
0076 %type <num> PE_VALUE_SYM_HW
0077 %type <num> PE_VALUE_SYM_SW
0078 %type <num> PE_VALUE_SYM_TOOL
0079 %type <num> PE_RAW
0080 %type <num> PE_TERM
0081 %type <num> value_sym
0082 %type <str> PE_NAME
0083 %type <str> PE_BPF_OBJECT
0084 %type <str> PE_BPF_SOURCE
0085 %type <str> PE_NAME_CACHE_TYPE
0086 %type <str> PE_NAME_CACHE_OP_RESULT
0087 %type <str> PE_MODIFIER_EVENT
0088 %type <str> PE_MODIFIER_BP
0089 %type <str> PE_EVENT_NAME
0090 %type <str> PE_PMU_EVENT_PRE PE_PMU_EVENT_SUF PE_PMU_EVENT_SUF2 PE_KERNEL_PMU_EVENT PE_PMU_EVENT_FAKE
0091 %type <str> PE_DRV_CFG_TERM
0092 %type <str> event_pmu_name
0093 %destructor { free ($$); } <str>
0094 %type <term> event_term
0095 %destructor { parse_events_term__delete ($$); } <term>
0096 %type <list_terms> event_config
0097 %type <list_terms> opt_event_config
0098 %type <list_terms> opt_pmu_config
0099 %destructor { parse_events_terms__delete ($$); } <list_terms>
0100 %type <list_evsel> event_pmu
0101 %type <list_evsel> event_legacy_symbol
0102 %type <list_evsel> event_legacy_cache
0103 %type <list_evsel> event_legacy_mem
0104 %type <list_evsel> event_legacy_tracepoint
0105 %type <list_evsel> event_legacy_numeric
0106 %type <list_evsel> event_legacy_raw
0107 %type <list_evsel> event_bpf_file
0108 %type <list_evsel> event_def
0109 %type <list_evsel> event_mod
0110 %type <list_evsel> event_name
0111 %type <list_evsel> event
0112 %type <list_evsel> events
0113 %type <list_evsel> group_def
0114 %type <list_evsel> group
0115 %type <list_evsel> groups
0116 %destructor { free_list_evsel ($$); } <list_evsel>
0117 %type <tracepoint_name> tracepoint_name
0118 %destructor { free ($$.sys); free ($$.event); } <tracepoint_name>
0119 %type <array> array
0120 %type <array> array_term
0121 %type <array> array_terms
0122 %destructor { free ($$.ranges); } <array>
0123
0124 %union
0125 {
0126 char *str;
0127 u64 num;
0128 struct list_head *list_evsel;
0129 struct list_head *list_terms;
0130 struct parse_events_term *term;
0131 struct tracepoint_name {
0132 char *sys;
0133 char *event;
0134 } tracepoint_name;
0135 struct parse_events_array array;
0136 }
0137 %%
0138
0139 start:
0140 PE_START_EVENTS start_events
0141 |
0142 PE_START_TERMS start_terms
0143
0144 start_events: groups
0145 {
0146 struct parse_events_state *parse_state = _parse_state;
0147
0148 /* frees $1 */
0149 parse_events_update_lists($1, &parse_state->list);
0150 }
0151
0152 groups:
0153 groups ',' group
0154 {
0155 struct list_head *list = $1;
0156 struct list_head *group = $3;
0157
0158 /* frees $3 */
0159 parse_events_update_lists(group, list);
0160 $$ = list;
0161 }
0162 |
0163 groups ',' event
0164 {
0165 struct list_head *list = $1;
0166 struct list_head *event = $3;
0167
0168 /* frees $3 */
0169 parse_events_update_lists(event, list);
0170 $$ = list;
0171 }
0172 |
0173 group
0174 |
0175 event
0176
0177 group:
0178 group_def ':' PE_MODIFIER_EVENT
0179 {
0180 struct list_head *list = $1;
0181 int err;
0182
0183 err = parse_events__modifier_group(list, $3);
0184 free($3);
0185 if (err) {
0186 struct parse_events_state *parse_state = _parse_state;
0187 struct parse_events_error *error = parse_state->error;
0188
0189 parse_events_error__handle(error, @3.first_column,
0190 strdup("Bad modifier"), NULL);
0191 free_list_evsel(list);
0192 YYABORT;
0193 }
0194 $$ = list;
0195 }
0196 |
0197 group_def
0198
0199 group_def:
0200 PE_NAME '{' events '}'
0201 {
0202 struct list_head *list = $3;
0203
0204 inc_group_count(list, _parse_state);
0205 parse_events__set_leader($1, list, _parse_state);
0206 free($1);
0207 $$ = list;
0208 }
0209 |
0210 '{' events '}'
0211 {
0212 struct list_head *list = $2;
0213
0214 inc_group_count(list, _parse_state);
0215 parse_events__set_leader(NULL, list, _parse_state);
0216 $$ = list;
0217 }
0218
0219 events:
0220 events ',' event
0221 {
0222 struct list_head *event = $3;
0223 struct list_head *list = $1;
0224
0225 /* frees $3 */
0226 parse_events_update_lists(event, list);
0227 $$ = list;
0228 }
0229 |
0230 event
0231
0232 event: event_mod
0233
0234 event_mod:
0235 event_name PE_MODIFIER_EVENT
0236 {
0237 struct list_head *list = $1;
0238 int err;
0239
0240 /*
0241 * Apply modifier on all events added by single event definition
0242 * (there could be more events added for multiple tracepoint
0243 * definitions via '*?'.
0244 */
0245 err = parse_events__modifier_event(list, $2, false);
0246 free($2);
0247 if (err) {
0248 struct parse_events_state *parse_state = _parse_state;
0249 struct parse_events_error *error = parse_state->error;
0250
0251 parse_events_error__handle(error, @2.first_column,
0252 strdup("Bad modifier"), NULL);
0253 free_list_evsel(list);
0254 YYABORT;
0255 }
0256 $$ = list;
0257 }
0258 |
0259 event_name
0260
0261 event_name:
0262 PE_EVENT_NAME event_def
0263 {
0264 int err;
0265
0266 err = parse_events_name($2, $1);
0267 free($1);
0268 if (err) {
0269 free_list_evsel($2);
0270 YYABORT;
0271 }
0272 $$ = $2;
0273 }
0274 |
0275 event_def
0276
0277 event_def: event_pmu |
0278 event_legacy_symbol |
0279 event_legacy_cache sep_dc |
0280 event_legacy_mem |
0281 event_legacy_tracepoint sep_dc |
0282 event_legacy_numeric sep_dc |
0283 event_legacy_raw sep_dc |
0284 event_bpf_file
0285
0286 event_pmu_name:
0287 PE_NAME | PE_PMU_EVENT_PRE
0288
0289 event_pmu:
0290 event_pmu_name opt_pmu_config
0291 {
0292 struct parse_events_state *parse_state = _parse_state;
0293 struct parse_events_error *error = parse_state->error;
0294 struct list_head *list = NULL, *orig_terms = NULL, *terms= NULL;
0295 char *pattern = NULL;
0296
0297 #define CLEANUP_YYABORT \
0298 do { \
0299 parse_events_terms__delete($2); \
0300 parse_events_terms__delete(orig_terms); \
0301 free(list); \
0302 free($1); \
0303 free(pattern); \
0304 YYABORT; \
0305 } while(0)
0306
0307 if (parse_events_copy_term_list($2, &orig_terms))
0308 CLEANUP_YYABORT;
0309
0310 if (error)
0311 error->idx = @1.first_column;
0312
0313 list = alloc_list();
0314 if (!list)
0315 CLEANUP_YYABORT;
0316 if (parse_events_add_pmu(_parse_state, list, $1, $2, false, false)) {
0317 struct perf_pmu *pmu = NULL;
0318 int ok = 0;
0319
0320 if (asprintf(&pattern, "%s*", $1) < 0)
0321 CLEANUP_YYABORT;
0322
0323 while ((pmu = perf_pmu__scan(pmu)) != NULL) {
0324 char *name = pmu->name;
0325
0326 if (!strncmp(name, "uncore_", 7) &&
0327 strncmp($1, "uncore_", 7))
0328 name += 7;
0329 if (!perf_pmu__match(pattern, name, $1) ||
0330 !perf_pmu__match(pattern, pmu->alias_name, $1)) {
0331 if (parse_events_copy_term_list(orig_terms, &terms))
0332 CLEANUP_YYABORT;
0333 if (!parse_events_add_pmu(_parse_state, list, pmu->name, terms, true, false))
0334 ok++;
0335 parse_events_terms__delete(terms);
0336 }
0337 }
0338
0339 if (!ok)
0340 CLEANUP_YYABORT;
0341 }
0342 parse_events_terms__delete($2);
0343 parse_events_terms__delete(orig_terms);
0344 free(pattern);
0345 free($1);
0346 $$ = list;
0347 #undef CLEANUP_YYABORT
0348 }
0349 |
0350 PE_KERNEL_PMU_EVENT sep_dc
0351 {
0352 struct list_head *list;
0353 int err;
0354
0355 err = parse_events_multi_pmu_add(_parse_state, $1, NULL, &list);
0356 free($1);
0357 if (err < 0)
0358 YYABORT;
0359 $$ = list;
0360 }
0361 |
0362 PE_KERNEL_PMU_EVENT opt_pmu_config
0363 {
0364 struct list_head *list;
0365 int err;
0366
0367 /* frees $2 */
0368 err = parse_events_multi_pmu_add(_parse_state, $1, $2, &list);
0369 free($1);
0370 if (err < 0)
0371 YYABORT;
0372 $$ = list;
0373 }
0374 |
0375 PE_PMU_EVENT_PRE '-' PE_PMU_EVENT_SUF '-' PE_PMU_EVENT_SUF2 sep_dc
0376 {
0377 struct list_head *list;
0378 char pmu_name[128];
0379 snprintf(pmu_name, sizeof(pmu_name), "%s-%s-%s", $1, $3, $5);
0380 free($1);
0381 free($3);
0382 free($5);
0383 if (parse_events_multi_pmu_add(_parse_state, pmu_name, NULL, &list) < 0)
0384 YYABORT;
0385 $$ = list;
0386 }
0387 |
0388 PE_PMU_EVENT_PRE '-' PE_PMU_EVENT_SUF sep_dc
0389 {
0390 struct list_head *list;
0391 char pmu_name[128];
0392
0393 snprintf(pmu_name, sizeof(pmu_name), "%s-%s", $1, $3);
0394 free($1);
0395 free($3);
0396 if (parse_events_multi_pmu_add(_parse_state, pmu_name, NULL, &list) < 0)
0397 YYABORT;
0398 $$ = list;
0399 }
0400 |
0401 PE_PMU_EVENT_FAKE sep_dc
0402 {
0403 struct list_head *list;
0404 int err;
0405
0406 list = alloc_list();
0407 if (!list)
0408 YYABORT;
0409
0410 err = parse_events_add_pmu(_parse_state, list, $1, NULL, false, false);
0411 free($1);
0412 if (err < 0) {
0413 free(list);
0414 YYABORT;
0415 }
0416 $$ = list;
0417 }
0418 |
0419 PE_PMU_EVENT_FAKE opt_pmu_config
0420 {
0421 struct list_head *list;
0422 int err;
0423
0424 list = alloc_list();
0425 if (!list)
0426 YYABORT;
0427
0428 err = parse_events_add_pmu(_parse_state, list, $1, $2, false, false);
0429 free($1);
0430 parse_events_terms__delete($2);
0431 if (err < 0) {
0432 free(list);
0433 YYABORT;
0434 }
0435 $$ = list;
0436 }
0437
0438 value_sym:
0439 PE_VALUE_SYM_HW
0440 |
0441 PE_VALUE_SYM_SW
0442
0443 event_legacy_symbol:
0444 value_sym '/' event_config '/'
0445 {
0446 struct list_head *list;
0447 int type = $1 >> 16;
0448 int config = $1 & 255;
0449 int err;
0450
0451 list = alloc_list();
0452 ABORT_ON(!list);
0453 err = parse_events_add_numeric(_parse_state, list, type, config, $3);
0454 parse_events_terms__delete($3);
0455 if (err) {
0456 free_list_evsel(list);
0457 YYABORT;
0458 }
0459 $$ = list;
0460 }
0461 |
0462 value_sym sep_slash_slash_dc
0463 {
0464 struct list_head *list;
0465 int type = $1 >> 16;
0466 int config = $1 & 255;
0467
0468 list = alloc_list();
0469 ABORT_ON(!list);
0470 ABORT_ON(parse_events_add_numeric(_parse_state, list, type, config, NULL));
0471 $$ = list;
0472 }
0473 |
0474 PE_VALUE_SYM_TOOL sep_slash_slash_dc
0475 {
0476 struct list_head *list;
0477
0478 list = alloc_list();
0479 ABORT_ON(!list);
0480 ABORT_ON(parse_events_add_tool(_parse_state, list, $1));
0481 $$ = list;
0482 }
0483
0484 event_legacy_cache:
0485 PE_NAME_CACHE_TYPE '-' PE_NAME_CACHE_OP_RESULT '-' PE_NAME_CACHE_OP_RESULT opt_event_config
0486 {
0487 struct parse_events_state *parse_state = _parse_state;
0488 struct parse_events_error *error = parse_state->error;
0489 struct list_head *list;
0490 int err;
0491
0492 list = alloc_list();
0493 ABORT_ON(!list);
0494 err = parse_events_add_cache(list, &parse_state->idx, $1, $3, $5, error, $6,
0495 parse_state);
0496 parse_events_terms__delete($6);
0497 free($1);
0498 free($3);
0499 free($5);
0500 if (err) {
0501 free_list_evsel(list);
0502 YYABORT;
0503 }
0504 $$ = list;
0505 }
0506 |
0507 PE_NAME_CACHE_TYPE '-' PE_NAME_CACHE_OP_RESULT opt_event_config
0508 {
0509 struct parse_events_state *parse_state = _parse_state;
0510 struct parse_events_error *error = parse_state->error;
0511 struct list_head *list;
0512 int err;
0513
0514 list = alloc_list();
0515 ABORT_ON(!list);
0516 err = parse_events_add_cache(list, &parse_state->idx, $1, $3, NULL, error, $4,
0517 parse_state);
0518 parse_events_terms__delete($4);
0519 free($1);
0520 free($3);
0521 if (err) {
0522 free_list_evsel(list);
0523 YYABORT;
0524 }
0525 $$ = list;
0526 }
0527 |
0528 PE_NAME_CACHE_TYPE opt_event_config
0529 {
0530 struct parse_events_state *parse_state = _parse_state;
0531 struct parse_events_error *error = parse_state->error;
0532 struct list_head *list;
0533 int err;
0534
0535 list = alloc_list();
0536 ABORT_ON(!list);
0537 err = parse_events_add_cache(list, &parse_state->idx, $1, NULL, NULL, error, $2,
0538 parse_state);
0539 parse_events_terms__delete($2);
0540 free($1);
0541 if (err) {
0542 free_list_evsel(list);
0543 YYABORT;
0544 }
0545 $$ = list;
0546 }
0547
0548 event_legacy_mem:
0549 PE_PREFIX_MEM PE_VALUE '/' PE_VALUE ':' PE_MODIFIER_BP sep_dc
0550 {
0551 struct parse_events_state *parse_state = _parse_state;
0552 struct list_head *list;
0553 int err;
0554
0555 list = alloc_list();
0556 ABORT_ON(!list);
0557 err = parse_events_add_breakpoint(list, &parse_state->idx,
0558 $2, $6, $4);
0559 free($6);
0560 if (err) {
0561 free(list);
0562 YYABORT;
0563 }
0564 $$ = list;
0565 }
0566 |
0567 PE_PREFIX_MEM PE_VALUE '/' PE_VALUE sep_dc
0568 {
0569 struct parse_events_state *parse_state = _parse_state;
0570 struct list_head *list;
0571
0572 list = alloc_list();
0573 ABORT_ON(!list);
0574 if (parse_events_add_breakpoint(list, &parse_state->idx,
0575 $2, NULL, $4)) {
0576 free(list);
0577 YYABORT;
0578 }
0579 $$ = list;
0580 }
0581 |
0582 PE_PREFIX_MEM PE_VALUE ':' PE_MODIFIER_BP sep_dc
0583 {
0584 struct parse_events_state *parse_state = _parse_state;
0585 struct list_head *list;
0586 int err;
0587
0588 list = alloc_list();
0589 ABORT_ON(!list);
0590 err = parse_events_add_breakpoint(list, &parse_state->idx,
0591 $2, $4, 0);
0592 free($4);
0593 if (err) {
0594 free(list);
0595 YYABORT;
0596 }
0597 $$ = list;
0598 }
0599 |
0600 PE_PREFIX_MEM PE_VALUE sep_dc
0601 {
0602 struct parse_events_state *parse_state = _parse_state;
0603 struct list_head *list;
0604
0605 list = alloc_list();
0606 ABORT_ON(!list);
0607 if (parse_events_add_breakpoint(list, &parse_state->idx,
0608 $2, NULL, 0)) {
0609 free(list);
0610 YYABORT;
0611 }
0612 $$ = list;
0613 }
0614
0615 event_legacy_tracepoint:
0616 tracepoint_name opt_event_config
0617 {
0618 struct parse_events_state *parse_state = _parse_state;
0619 struct parse_events_error *error = parse_state->error;
0620 struct list_head *list;
0621 int err;
0622
0623 list = alloc_list();
0624 ABORT_ON(!list);
0625 if (error)
0626 error->idx = @1.first_column;
0627
0628 err = parse_events_add_tracepoint(list, &parse_state->idx, $1.sys, $1.event,
0629 error, $2);
0630
0631 parse_events_terms__delete($2);
0632 free($1.sys);
0633 free($1.event);
0634 if (err) {
0635 free(list);
0636 YYABORT;
0637 }
0638 $$ = list;
0639 }
0640
0641 tracepoint_name:
0642 PE_NAME '-' PE_NAME ':' PE_NAME
0643 {
0644 struct tracepoint_name tracepoint;
0645
0646 ABORT_ON(asprintf(&tracepoint.sys, "%s-%s", $1, $3) < 0);
0647 tracepoint.event = $5;
0648 free($1);
0649 free($3);
0650 $$ = tracepoint;
0651 }
0652 |
0653 PE_NAME ':' PE_NAME
0654 {
0655 struct tracepoint_name tracepoint = {$1, $3};
0656
0657 $$ = tracepoint;
0658 }
0659
0660 event_legacy_numeric:
0661 PE_VALUE ':' PE_VALUE opt_event_config
0662 {
0663 struct list_head *list;
0664 int err;
0665
0666 list = alloc_list();
0667 ABORT_ON(!list);
0668 err = parse_events_add_numeric(_parse_state, list, (u32)$1, $3, $4);
0669 parse_events_terms__delete($4);
0670 if (err) {
0671 free(list);
0672 YYABORT;
0673 }
0674 $$ = list;
0675 }
0676
0677 event_legacy_raw:
0678 PE_RAW opt_event_config
0679 {
0680 struct list_head *list;
0681 int err;
0682
0683 list = alloc_list();
0684 ABORT_ON(!list);
0685 err = parse_events_add_numeric(_parse_state, list, PERF_TYPE_RAW, $1, $2);
0686 parse_events_terms__delete($2);
0687 if (err) {
0688 free(list);
0689 YYABORT;
0690 }
0691 $$ = list;
0692 }
0693
0694 event_bpf_file:
0695 PE_BPF_OBJECT opt_event_config
0696 {
0697 struct parse_events_state *parse_state = _parse_state;
0698 struct list_head *list;
0699 int err;
0700
0701 list = alloc_list();
0702 ABORT_ON(!list);
0703 err = parse_events_load_bpf(parse_state, list, $1, false, $2);
0704 parse_events_terms__delete($2);
0705 free($1);
0706 if (err) {
0707 free(list);
0708 YYABORT;
0709 }
0710 $$ = list;
0711 }
0712 |
0713 PE_BPF_SOURCE opt_event_config
0714 {
0715 struct list_head *list;
0716 int err;
0717
0718 list = alloc_list();
0719 ABORT_ON(!list);
0720 err = parse_events_load_bpf(_parse_state, list, $1, true, $2);
0721 parse_events_terms__delete($2);
0722 if (err) {
0723 free(list);
0724 YYABORT;
0725 }
0726 $$ = list;
0727 }
0728
0729 opt_event_config:
0730 '/' event_config '/'
0731 {
0732 $$ = $2;
0733 }
0734 |
0735 '/' '/'
0736 {
0737 $$ = NULL;
0738 }
0739 |
0740 {
0741 $$ = NULL;
0742 }
0743
0744 opt_pmu_config:
0745 '/' event_config '/'
0746 {
0747 $$ = $2;
0748 }
0749 |
0750 '/' '/'
0751 {
0752 $$ = NULL;
0753 }
0754
0755 start_terms: event_config
0756 {
0757 struct parse_events_state *parse_state = _parse_state;
0758 if (parse_state->terms) {
0759 parse_events_terms__delete ($1);
0760 YYABORT;
0761 }
0762 parse_state->terms = $1;
0763 }
0764
0765 event_config:
0766 event_config ',' event_term
0767 {
0768 struct list_head *head = $1;
0769 struct parse_events_term *term = $3;
0770
0771 if (!head) {
0772 parse_events_term__delete(term);
0773 YYABORT;
0774 }
0775 list_add_tail(&term->list, head);
0776 $$ = $1;
0777 }
0778 |
0779 event_term
0780 {
0781 struct list_head *head = malloc(sizeof(*head));
0782 struct parse_events_term *term = $1;
0783
0784 ABORT_ON(!head);
0785 INIT_LIST_HEAD(head);
0786 list_add_tail(&term->list, head);
0787 $$ = head;
0788 }
0789
0790 event_term:
0791 PE_RAW
0792 {
0793 struct parse_events_term *term;
0794
0795 ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_CONFIG,
0796 NULL, $1, false, &@1, NULL));
0797 $$ = term;
0798 }
0799 |
0800 PE_NAME '=' PE_NAME
0801 {
0802 struct parse_events_term *term;
0803
0804 if (parse_events_term__str(&term, PARSE_EVENTS__TERM_TYPE_USER,
0805 $1, $3, &@1, &@3)) {
0806 free($1);
0807 free($3);
0808 YYABORT;
0809 }
0810 $$ = term;
0811 }
0812 |
0813 PE_NAME '=' PE_VALUE
0814 {
0815 struct parse_events_term *term;
0816
0817 if (parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER,
0818 $1, $3, false, &@1, &@3)) {
0819 free($1);
0820 YYABORT;
0821 }
0822 $$ = term;
0823 }
0824 |
0825 PE_NAME '=' PE_VALUE_SYM_HW
0826 {
0827 struct parse_events_term *term;
0828 int config = $3 & 255;
0829
0830 if (parse_events_term__sym_hw(&term, $1, config)) {
0831 free($1);
0832 YYABORT;
0833 }
0834 $$ = term;
0835 }
0836 |
0837 PE_NAME
0838 {
0839 struct parse_events_term *term;
0840
0841 if (parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER,
0842 $1, 1, true, &@1, NULL)) {
0843 free($1);
0844 YYABORT;
0845 }
0846 $$ = term;
0847 }
0848 |
0849 PE_VALUE_SYM_HW
0850 {
0851 struct parse_events_term *term;
0852 int config = $1 & 255;
0853
0854 ABORT_ON(parse_events_term__sym_hw(&term, NULL, config));
0855 $$ = term;
0856 }
0857 |
0858 PE_TERM '=' PE_NAME
0859 {
0860 struct parse_events_term *term;
0861
0862 if (parse_events_term__str(&term, (int)$1, NULL, $3, &@1, &@3)) {
0863 free($3);
0864 YYABORT;
0865 }
0866 $$ = term;
0867 }
0868 |
0869 PE_TERM '=' PE_VALUE
0870 {
0871 struct parse_events_term *term;
0872
0873 ABORT_ON(parse_events_term__num(&term, (int)$1, NULL, $3, false, &@1, &@3));
0874 $$ = term;
0875 }
0876 |
0877 PE_TERM
0878 {
0879 struct parse_events_term *term;
0880
0881 ABORT_ON(parse_events_term__num(&term, (int)$1, NULL, 1, true, &@1, NULL));
0882 $$ = term;
0883 }
0884 |
0885 PE_NAME array '=' PE_NAME
0886 {
0887 struct parse_events_term *term;
0888
0889 if (parse_events_term__str(&term, PARSE_EVENTS__TERM_TYPE_USER,
0890 $1, $4, &@1, &@4)) {
0891 free($1);
0892 free($4);
0893 free($2.ranges);
0894 YYABORT;
0895 }
0896 term->array = $2;
0897 $$ = term;
0898 }
0899 |
0900 PE_NAME array '=' PE_VALUE
0901 {
0902 struct parse_events_term *term;
0903
0904 if (parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER,
0905 $1, $4, false, &@1, &@4)) {
0906 free($1);
0907 free($2.ranges);
0908 YYABORT;
0909 }
0910 term->array = $2;
0911 $$ = term;
0912 }
0913 |
0914 PE_DRV_CFG_TERM
0915 {
0916 struct parse_events_term *term;
0917 char *config = strdup($1);
0918
0919 ABORT_ON(!config);
0920 if (parse_events_term__str(&term, PARSE_EVENTS__TERM_TYPE_DRV_CFG,
0921 config, $1, &@1, NULL)) {
0922 free($1);
0923 free(config);
0924 YYABORT;
0925 }
0926 $$ = term;
0927 }
0928
0929 array:
0930 '[' array_terms ']'
0931 {
0932 $$ = $2;
0933 }
0934 |
0935 PE_ARRAY_ALL
0936 {
0937 $$.nr_ranges = 0;
0938 $$.ranges = NULL;
0939 }
0940
0941 array_terms:
0942 array_terms ',' array_term
0943 {
0944 struct parse_events_array new_array;
0945
0946 new_array.nr_ranges = $1.nr_ranges + $3.nr_ranges;
0947 new_array.ranges = realloc($1.ranges,
0948 sizeof(new_array.ranges[0]) *
0949 new_array.nr_ranges);
0950 ABORT_ON(!new_array.ranges);
0951 memcpy(&new_array.ranges[$1.nr_ranges], $3.ranges,
0952 $3.nr_ranges * sizeof(new_array.ranges[0]));
0953 free($3.ranges);
0954 $$ = new_array;
0955 }
0956 |
0957 array_term
0958
0959 array_term:
0960 PE_VALUE
0961 {
0962 struct parse_events_array array;
0963
0964 array.nr_ranges = 1;
0965 array.ranges = malloc(sizeof(array.ranges[0]));
0966 ABORT_ON(!array.ranges);
0967 array.ranges[0].start = $1;
0968 array.ranges[0].length = 1;
0969 $$ = array;
0970 }
0971 |
0972 PE_VALUE PE_ARRAY_RANGE PE_VALUE
0973 {
0974 struct parse_events_array array;
0975
0976 ABORT_ON($3 < $1);
0977 array.nr_ranges = 1;
0978 array.ranges = malloc(sizeof(array.ranges[0]));
0979 ABORT_ON(!array.ranges);
0980 array.ranges[0].start = $1;
0981 array.ranges[0].length = $3 - $1 + 1;
0982 $$ = array;
0983 }
0984
0985 sep_dc: ':' |
0986
0987 sep_slash_slash_dc: '/' '/' | ':' |
0988
0989 %%
0990
0991 void parse_events_error(YYLTYPE *loc, void *parse_state,
0992 void *scanner __maybe_unused,
0993 char const *msg __maybe_unused)
0994 {
0995 parse_events_evlist_error(parse_state, loc->last_column, "parser error");
0996 }