Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
at v5.8 915 lines 17 kB view raw
1%define api.pure full 2%parse-param {void *_parse_state} 3%parse-param {void *scanner} 4%lex-param {void* scanner} 5%locations 6 7%{ 8 9#define YYDEBUG 1 10 11#include <fnmatch.h> 12#include <stdio.h> 13#include <linux/compiler.h> 14#include <linux/types.h> 15#include <linux/zalloc.h> 16#include "pmu.h" 17#include "evsel.h" 18#include "parse-events.h" 19#include "parse-events-bison.h" 20 21void parse_events_error(YYLTYPE *loc, void *parse_state, void *scanner, char const *msg); 22 23#define ABORT_ON(val) \ 24do { \ 25 if (val) \ 26 YYABORT; \ 27} while (0) 28 29static struct list_head* alloc_list(void) 30{ 31 struct list_head *list; 32 33 list = malloc(sizeof(*list)); 34 if (!list) 35 return NULL; 36 37 INIT_LIST_HEAD(list); 38 return list; 39} 40 41static void free_list_evsel(struct list_head* list_evsel) 42{ 43 struct evsel *evsel, *tmp; 44 45 list_for_each_entry_safe(evsel, tmp, list_evsel, core.node) { 46 list_del_init(&evsel->core.node); 47 evsel__delete(evsel); 48 } 49 free(list_evsel); 50} 51 52static void inc_group_count(struct list_head *list, 53 struct parse_events_state *parse_state) 54{ 55 /* Count groups only have more than 1 members */ 56 if (!list_is_last(list->next, list)) 57 parse_state->nr_groups++; 58} 59 60%} 61 62%token PE_START_EVENTS PE_START_TERMS 63%token PE_VALUE PE_VALUE_SYM_HW PE_VALUE_SYM_SW PE_RAW PE_TERM 64%token PE_VALUE_SYM_TOOL 65%token PE_EVENT_NAME 66%token PE_NAME 67%token PE_BPF_OBJECT PE_BPF_SOURCE 68%token PE_MODIFIER_EVENT PE_MODIFIER_BP 69%token PE_NAME_CACHE_TYPE PE_NAME_CACHE_OP_RESULT 70%token PE_PREFIX_MEM PE_PREFIX_RAW PE_PREFIX_GROUP 71%token PE_ERROR 72%token PE_PMU_EVENT_PRE PE_PMU_EVENT_SUF PE_KERNEL_PMU_EVENT 73%token PE_ARRAY_ALL PE_ARRAY_RANGE 74%token PE_DRV_CFG_TERM 75%type <num> PE_VALUE 76%type <num> PE_VALUE_SYM_HW 77%type <num> PE_VALUE_SYM_SW 78%type <num> PE_VALUE_SYM_TOOL 79%type <num> PE_RAW 80%type <num> PE_TERM 81%type <num> value_sym 82%type <str> PE_NAME 83%type <str> PE_BPF_OBJECT 84%type <str> PE_BPF_SOURCE 85%type <str> PE_NAME_CACHE_TYPE 86%type <str> PE_NAME_CACHE_OP_RESULT 87%type <str> PE_MODIFIER_EVENT 88%type <str> PE_MODIFIER_BP 89%type <str> PE_EVENT_NAME 90%type <str> PE_PMU_EVENT_PRE PE_PMU_EVENT_SUF PE_KERNEL_PMU_EVENT 91%type <str> PE_DRV_CFG_TERM 92%destructor { free ($$); } <str> 93%type <term> event_term 94%destructor { parse_events_term__delete ($$); } <term> 95%type <list_terms> event_config 96%type <list_terms> opt_event_config 97%type <list_terms> opt_pmu_config 98%destructor { parse_events_terms__delete ($$); } <list_terms> 99%type <list_evsel> event_pmu 100%type <list_evsel> event_legacy_symbol 101%type <list_evsel> event_legacy_cache 102%type <list_evsel> event_legacy_mem 103%type <list_evsel> event_legacy_tracepoint 104%type <list_evsel> event_legacy_numeric 105%type <list_evsel> event_legacy_raw 106%type <list_evsel> event_bpf_file 107%type <list_evsel> event_def 108%type <list_evsel> event_mod 109%type <list_evsel> event_name 110%type <list_evsel> event 111%type <list_evsel> events 112%type <list_evsel> group_def 113%type <list_evsel> group 114%type <list_evsel> groups 115%destructor { free_list_evsel ($$); } <list_evsel> 116%type <tracepoint_name> tracepoint_name 117%destructor { free ($$.sys); free ($$.event); } <tracepoint_name> 118%type <array> array 119%type <array> array_term 120%type <array> array_terms 121%destructor { free ($$.ranges); } <array> 122 123%union 124{ 125 char *str; 126 u64 num; 127 struct list_head *list_evsel; 128 struct list_head *list_terms; 129 struct parse_events_term *term; 130 struct tracepoint_name { 131 char *sys; 132 char *event; 133 } tracepoint_name; 134 struct parse_events_array array; 135} 136%% 137 138start: 139PE_START_EVENTS start_events 140| 141PE_START_TERMS start_terms 142 143start_events: groups 144{ 145 struct parse_events_state *parse_state = _parse_state; 146 147 /* frees $1 */ 148 parse_events_update_lists($1, &parse_state->list); 149} 150 151groups: 152groups ',' group 153{ 154 struct list_head *list = $1; 155 struct list_head *group = $3; 156 157 /* frees $3 */ 158 parse_events_update_lists(group, list); 159 $$ = list; 160} 161| 162groups ',' event 163{ 164 struct list_head *list = $1; 165 struct list_head *event = $3; 166 167 /* frees $3 */ 168 parse_events_update_lists(event, list); 169 $$ = list; 170} 171| 172group 173| 174event 175 176group: 177group_def ':' PE_MODIFIER_EVENT 178{ 179 struct list_head *list = $1; 180 int err; 181 182 err = parse_events__modifier_group(list, $3); 183 free($3); 184 if (err) { 185 free_list_evsel(list); 186 YYABORT; 187 } 188 $$ = list; 189} 190| 191group_def 192 193group_def: 194PE_NAME '{' events '}' 195{ 196 struct list_head *list = $3; 197 198 inc_group_count(list, _parse_state); 199 parse_events__set_leader($1, list, _parse_state); 200 free($1); 201 $$ = list; 202} 203| 204'{' events '}' 205{ 206 struct list_head *list = $2; 207 208 inc_group_count(list, _parse_state); 209 parse_events__set_leader(NULL, list, _parse_state); 210 $$ = list; 211} 212 213events: 214events ',' event 215{ 216 struct list_head *event = $3; 217 struct list_head *list = $1; 218 219 /* frees $3 */ 220 parse_events_update_lists(event, list); 221 $$ = list; 222} 223| 224event 225 226event: event_mod 227 228event_mod: 229event_name PE_MODIFIER_EVENT 230{ 231 struct list_head *list = $1; 232 int err; 233 234 /* 235 * Apply modifier on all events added by single event definition 236 * (there could be more events added for multiple tracepoint 237 * definitions via '*?'. 238 */ 239 err = parse_events__modifier_event(list, $2, false); 240 free($2); 241 if (err) { 242 free_list_evsel(list); 243 YYABORT; 244 } 245 $$ = list; 246} 247| 248event_name 249 250event_name: 251PE_EVENT_NAME event_def 252{ 253 int err; 254 255 err = parse_events_name($2, $1); 256 free($1); 257 if (err) { 258 free_list_evsel($2); 259 YYABORT; 260 } 261 $$ = $2; 262} 263| 264event_def 265 266event_def: event_pmu | 267 event_legacy_symbol | 268 event_legacy_cache sep_dc | 269 event_legacy_mem | 270 event_legacy_tracepoint sep_dc | 271 event_legacy_numeric sep_dc | 272 event_legacy_raw sep_dc | 273 event_bpf_file 274 275event_pmu: 276PE_NAME opt_pmu_config 277{ 278 struct parse_events_state *parse_state = _parse_state; 279 struct parse_events_error *error = parse_state->error; 280 struct list_head *list = NULL, *orig_terms = NULL, *terms= NULL; 281 char *pattern = NULL; 282 283#define CLEANUP_YYABORT \ 284 do { \ 285 parse_events_terms__delete($2); \ 286 parse_events_terms__delete(orig_terms); \ 287 free(list); \ 288 free($1); \ 289 free(pattern); \ 290 YYABORT; \ 291 } while(0) 292 293 if (parse_events_copy_term_list($2, &orig_terms)) 294 CLEANUP_YYABORT; 295 296 if (error) 297 error->idx = @1.first_column; 298 299 list = alloc_list(); 300 if (!list) 301 CLEANUP_YYABORT; 302 if (parse_events_add_pmu(_parse_state, list, $1, $2, false, false)) { 303 struct perf_pmu *pmu = NULL; 304 int ok = 0; 305 306 if (asprintf(&pattern, "%s*", $1) < 0) 307 CLEANUP_YYABORT; 308 309 while ((pmu = perf_pmu__scan(pmu)) != NULL) { 310 char *name = pmu->name; 311 312 if (!strncmp(name, "uncore_", 7) && 313 strncmp($1, "uncore_", 7)) 314 name += 7; 315 if (!fnmatch(pattern, name, 0)) { 316 if (parse_events_copy_term_list(orig_terms, &terms)) 317 CLEANUP_YYABORT; 318 if (!parse_events_add_pmu(_parse_state, list, pmu->name, terms, true, false)) 319 ok++; 320 parse_events_terms__delete(terms); 321 } 322 } 323 324 if (!ok) 325 CLEANUP_YYABORT; 326 } 327 parse_events_terms__delete($2); 328 parse_events_terms__delete(orig_terms); 329 free(pattern); 330 free($1); 331 $$ = list; 332#undef CLEANUP_YYABORT 333} 334| 335PE_KERNEL_PMU_EVENT sep_dc 336{ 337 struct list_head *list; 338 int err; 339 340 err = parse_events_multi_pmu_add(_parse_state, $1, &list); 341 free($1); 342 if (err < 0) 343 YYABORT; 344 $$ = list; 345} 346| 347PE_PMU_EVENT_PRE '-' PE_PMU_EVENT_SUF sep_dc 348{ 349 struct list_head *list; 350 char pmu_name[128]; 351 352 snprintf(pmu_name, sizeof(pmu_name), "%s-%s", $1, $3); 353 free($1); 354 free($3); 355 if (parse_events_multi_pmu_add(_parse_state, pmu_name, &list) < 0) 356 YYABORT; 357 $$ = list; 358} 359 360value_sym: 361PE_VALUE_SYM_HW 362| 363PE_VALUE_SYM_SW 364 365event_legacy_symbol: 366value_sym '/' event_config '/' 367{ 368 struct list_head *list; 369 int type = $1 >> 16; 370 int config = $1 & 255; 371 int err; 372 373 list = alloc_list(); 374 ABORT_ON(!list); 375 err = parse_events_add_numeric(_parse_state, list, type, config, $3); 376 parse_events_terms__delete($3); 377 if (err) { 378 free_list_evsel(list); 379 YYABORT; 380 } 381 $$ = list; 382} 383| 384value_sym sep_slash_slash_dc 385{ 386 struct list_head *list; 387 int type = $1 >> 16; 388 int config = $1 & 255; 389 390 list = alloc_list(); 391 ABORT_ON(!list); 392 ABORT_ON(parse_events_add_numeric(_parse_state, list, type, config, NULL)); 393 $$ = list; 394} 395| 396PE_VALUE_SYM_TOOL sep_slash_slash_dc 397{ 398 struct list_head *list; 399 400 list = alloc_list(); 401 ABORT_ON(!list); 402 ABORT_ON(parse_events_add_tool(_parse_state, list, $1)); 403 $$ = list; 404} 405 406event_legacy_cache: 407PE_NAME_CACHE_TYPE '-' PE_NAME_CACHE_OP_RESULT '-' PE_NAME_CACHE_OP_RESULT opt_event_config 408{ 409 struct parse_events_state *parse_state = _parse_state; 410 struct parse_events_error *error = parse_state->error; 411 struct list_head *list; 412 int err; 413 414 list = alloc_list(); 415 ABORT_ON(!list); 416 err = parse_events_add_cache(list, &parse_state->idx, $1, $3, $5, error, $6); 417 parse_events_terms__delete($6); 418 free($1); 419 free($3); 420 free($5); 421 if (err) { 422 free_list_evsel(list); 423 YYABORT; 424 } 425 $$ = list; 426} 427| 428PE_NAME_CACHE_TYPE '-' PE_NAME_CACHE_OP_RESULT opt_event_config 429{ 430 struct parse_events_state *parse_state = _parse_state; 431 struct parse_events_error *error = parse_state->error; 432 struct list_head *list; 433 int err; 434 435 list = alloc_list(); 436 ABORT_ON(!list); 437 err = parse_events_add_cache(list, &parse_state->idx, $1, $3, NULL, error, $4); 438 parse_events_terms__delete($4); 439 free($1); 440 free($3); 441 if (err) { 442 free_list_evsel(list); 443 YYABORT; 444 } 445 $$ = list; 446} 447| 448PE_NAME_CACHE_TYPE opt_event_config 449{ 450 struct parse_events_state *parse_state = _parse_state; 451 struct parse_events_error *error = parse_state->error; 452 struct list_head *list; 453 int err; 454 455 list = alloc_list(); 456 ABORT_ON(!list); 457 err = parse_events_add_cache(list, &parse_state->idx, $1, NULL, NULL, error, $2); 458 parse_events_terms__delete($2); 459 free($1); 460 if (err) { 461 free_list_evsel(list); 462 YYABORT; 463 } 464 $$ = list; 465} 466 467event_legacy_mem: 468PE_PREFIX_MEM PE_VALUE '/' PE_VALUE ':' PE_MODIFIER_BP sep_dc 469{ 470 struct parse_events_state *parse_state = _parse_state; 471 struct list_head *list; 472 int err; 473 474 list = alloc_list(); 475 ABORT_ON(!list); 476 err = parse_events_add_breakpoint(list, &parse_state->idx, 477 (void *) $2, $6, $4); 478 free($6); 479 if (err) { 480 free(list); 481 YYABORT; 482 } 483 $$ = list; 484} 485| 486PE_PREFIX_MEM PE_VALUE '/' PE_VALUE sep_dc 487{ 488 struct parse_events_state *parse_state = _parse_state; 489 struct list_head *list; 490 491 list = alloc_list(); 492 ABORT_ON(!list); 493 if (parse_events_add_breakpoint(list, &parse_state->idx, 494 (void *) $2, NULL, $4)) { 495 free(list); 496 YYABORT; 497 } 498 $$ = list; 499} 500| 501PE_PREFIX_MEM PE_VALUE ':' PE_MODIFIER_BP sep_dc 502{ 503 struct parse_events_state *parse_state = _parse_state; 504 struct list_head *list; 505 int err; 506 507 list = alloc_list(); 508 ABORT_ON(!list); 509 err = parse_events_add_breakpoint(list, &parse_state->idx, 510 (void *) $2, $4, 0); 511 free($4); 512 if (err) { 513 free(list); 514 YYABORT; 515 } 516 $$ = list; 517} 518| 519PE_PREFIX_MEM PE_VALUE sep_dc 520{ 521 struct parse_events_state *parse_state = _parse_state; 522 struct list_head *list; 523 524 list = alloc_list(); 525 ABORT_ON(!list); 526 if (parse_events_add_breakpoint(list, &parse_state->idx, 527 (void *) $2, NULL, 0)) { 528 free(list); 529 YYABORT; 530 } 531 $$ = list; 532} 533 534event_legacy_tracepoint: 535tracepoint_name opt_event_config 536{ 537 struct parse_events_state *parse_state = _parse_state; 538 struct parse_events_error *error = parse_state->error; 539 struct list_head *list; 540 int err; 541 542 list = alloc_list(); 543 ABORT_ON(!list); 544 if (error) 545 error->idx = @1.first_column; 546 547 err = parse_events_add_tracepoint(list, &parse_state->idx, $1.sys, $1.event, 548 error, $2); 549 550 parse_events_terms__delete($2); 551 free($1.sys); 552 free($1.event); 553 if (err) { 554 free(list); 555 YYABORT; 556 } 557 $$ = list; 558} 559 560tracepoint_name: 561PE_NAME '-' PE_NAME ':' PE_NAME 562{ 563 struct tracepoint_name tracepoint; 564 565 ABORT_ON(asprintf(&tracepoint.sys, "%s-%s", $1, $3) < 0); 566 tracepoint.event = $5; 567 free($1); 568 free($3); 569 $$ = tracepoint; 570} 571| 572PE_NAME ':' PE_NAME 573{ 574 struct tracepoint_name tracepoint = {$1, $3}; 575 576 $$ = tracepoint; 577} 578 579event_legacy_numeric: 580PE_VALUE ':' PE_VALUE opt_event_config 581{ 582 struct list_head *list; 583 int err; 584 585 list = alloc_list(); 586 ABORT_ON(!list); 587 err = parse_events_add_numeric(_parse_state, list, (u32)$1, $3, $4); 588 parse_events_terms__delete($4); 589 if (err) { 590 free(list); 591 YYABORT; 592 } 593 $$ = list; 594} 595 596event_legacy_raw: 597PE_RAW opt_event_config 598{ 599 struct list_head *list; 600 int err; 601 602 list = alloc_list(); 603 ABORT_ON(!list); 604 err = parse_events_add_numeric(_parse_state, list, PERF_TYPE_RAW, $1, $2); 605 parse_events_terms__delete($2); 606 if (err) { 607 free(list); 608 YYABORT; 609 } 610 $$ = list; 611} 612 613event_bpf_file: 614PE_BPF_OBJECT opt_event_config 615{ 616 struct parse_events_state *parse_state = _parse_state; 617 struct list_head *list; 618 int err; 619 620 list = alloc_list(); 621 ABORT_ON(!list); 622 err = parse_events_load_bpf(parse_state, list, $1, false, $2); 623 parse_events_terms__delete($2); 624 free($1); 625 if (err) { 626 free(list); 627 YYABORT; 628 } 629 $$ = list; 630} 631| 632PE_BPF_SOURCE opt_event_config 633{ 634 struct list_head *list; 635 int err; 636 637 list = alloc_list(); 638 ABORT_ON(!list); 639 err = parse_events_load_bpf(_parse_state, list, $1, true, $2); 640 parse_events_terms__delete($2); 641 if (err) { 642 free(list); 643 YYABORT; 644 } 645 $$ = list; 646} 647 648opt_event_config: 649'/' event_config '/' 650{ 651 $$ = $2; 652} 653| 654'/' '/' 655{ 656 $$ = NULL; 657} 658| 659{ 660 $$ = NULL; 661} 662 663opt_pmu_config: 664'/' event_config '/' 665{ 666 $$ = $2; 667} 668| 669'/' '/' 670{ 671 $$ = NULL; 672} 673 674start_terms: event_config 675{ 676 struct parse_events_state *parse_state = _parse_state; 677 if (parse_state->terms) { 678 parse_events_terms__delete ($1); 679 YYABORT; 680 } 681 parse_state->terms = $1; 682} 683 684event_config: 685event_config ',' event_term 686{ 687 struct list_head *head = $1; 688 struct parse_events_term *term = $3; 689 690 if (!head) { 691 parse_events_term__delete(term); 692 YYABORT; 693 } 694 list_add_tail(&term->list, head); 695 $$ = $1; 696} 697| 698event_term 699{ 700 struct list_head *head = malloc(sizeof(*head)); 701 struct parse_events_term *term = $1; 702 703 ABORT_ON(!head); 704 INIT_LIST_HEAD(head); 705 list_add_tail(&term->list, head); 706 $$ = head; 707} 708 709event_term: 710PE_RAW 711{ 712 struct parse_events_term *term; 713 714 ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_CONFIG, 715 NULL, $1, false, &@1, NULL)); 716 $$ = term; 717} 718| 719PE_NAME '=' PE_NAME 720{ 721 struct parse_events_term *term; 722 723 if (parse_events_term__str(&term, PARSE_EVENTS__TERM_TYPE_USER, 724 $1, $3, &@1, &@3)) { 725 free($1); 726 free($3); 727 YYABORT; 728 } 729 $$ = term; 730} 731| 732PE_NAME '=' PE_VALUE 733{ 734 struct parse_events_term *term; 735 736 if (parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER, 737 $1, $3, false, &@1, &@3)) { 738 free($1); 739 YYABORT; 740 } 741 $$ = term; 742} 743| 744PE_NAME '=' PE_VALUE_SYM_HW 745{ 746 struct parse_events_term *term; 747 int config = $3 & 255; 748 749 if (parse_events_term__sym_hw(&term, $1, config)) { 750 free($1); 751 YYABORT; 752 } 753 $$ = term; 754} 755| 756PE_NAME 757{ 758 struct parse_events_term *term; 759 760 if (parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER, 761 $1, 1, true, &@1, NULL)) { 762 free($1); 763 YYABORT; 764 } 765 $$ = term; 766} 767| 768PE_VALUE_SYM_HW 769{ 770 struct parse_events_term *term; 771 int config = $1 & 255; 772 773 ABORT_ON(parse_events_term__sym_hw(&term, NULL, config)); 774 $$ = term; 775} 776| 777PE_TERM '=' PE_NAME 778{ 779 struct parse_events_term *term; 780 781 if (parse_events_term__str(&term, (int)$1, NULL, $3, &@1, &@3)) { 782 free($3); 783 YYABORT; 784 } 785 $$ = term; 786} 787| 788PE_TERM '=' PE_VALUE 789{ 790 struct parse_events_term *term; 791 792 ABORT_ON(parse_events_term__num(&term, (int)$1, NULL, $3, false, &@1, &@3)); 793 $$ = term; 794} 795| 796PE_TERM 797{ 798 struct parse_events_term *term; 799 800 ABORT_ON(parse_events_term__num(&term, (int)$1, NULL, 1, true, &@1, NULL)); 801 $$ = term; 802} 803| 804PE_NAME array '=' PE_NAME 805{ 806 struct parse_events_term *term; 807 808 if (parse_events_term__str(&term, PARSE_EVENTS__TERM_TYPE_USER, 809 $1, $4, &@1, &@4)) { 810 free($1); 811 free($4); 812 free($2.ranges); 813 YYABORT; 814 } 815 term->array = $2; 816 $$ = term; 817} 818| 819PE_NAME array '=' PE_VALUE 820{ 821 struct parse_events_term *term; 822 823 if (parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER, 824 $1, $4, false, &@1, &@4)) { 825 free($1); 826 free($2.ranges); 827 YYABORT; 828 } 829 term->array = $2; 830 $$ = term; 831} 832| 833PE_DRV_CFG_TERM 834{ 835 struct parse_events_term *term; 836 char *config = strdup($1); 837 838 ABORT_ON(!config); 839 if (parse_events_term__str(&term, PARSE_EVENTS__TERM_TYPE_DRV_CFG, 840 config, $1, &@1, NULL)) { 841 free($1); 842 free(config); 843 YYABORT; 844 } 845 $$ = term; 846} 847 848array: 849'[' array_terms ']' 850{ 851 $$ = $2; 852} 853| 854PE_ARRAY_ALL 855{ 856 $$.nr_ranges = 0; 857 $$.ranges = NULL; 858} 859 860array_terms: 861array_terms ',' array_term 862{ 863 struct parse_events_array new_array; 864 865 new_array.nr_ranges = $1.nr_ranges + $3.nr_ranges; 866 new_array.ranges = realloc($1.ranges, 867 sizeof(new_array.ranges[0]) * 868 new_array.nr_ranges); 869 ABORT_ON(!new_array.ranges); 870 memcpy(&new_array.ranges[$1.nr_ranges], $3.ranges, 871 $3.nr_ranges * sizeof(new_array.ranges[0])); 872 free($3.ranges); 873 $$ = new_array; 874} 875| 876array_term 877 878array_term: 879PE_VALUE 880{ 881 struct parse_events_array array; 882 883 array.nr_ranges = 1; 884 array.ranges = malloc(sizeof(array.ranges[0])); 885 ABORT_ON(!array.ranges); 886 array.ranges[0].start = $1; 887 array.ranges[0].length = 1; 888 $$ = array; 889} 890| 891PE_VALUE PE_ARRAY_RANGE PE_VALUE 892{ 893 struct parse_events_array array; 894 895 ABORT_ON($3 < $1); 896 array.nr_ranges = 1; 897 array.ranges = malloc(sizeof(array.ranges[0])); 898 ABORT_ON(!array.ranges); 899 array.ranges[0].start = $1; 900 array.ranges[0].length = $3 - $1 + 1; 901 $$ = array; 902} 903 904sep_dc: ':' | 905 906sep_slash_slash_dc: '/' '/' | ':' | 907 908%% 909 910void parse_events_error(YYLTYPE *loc, void *parse_state, 911 void *scanner __maybe_unused, 912 char const *msg __maybe_unused) 913{ 914 parse_events_evlist_error(parse_state, loc->last_column, "parser error"); 915}