1%{ 2 #include <iostream> 3 #include <vector> 4 #include <list> 5 #include <map> 6 7 #include "declarations.h" 8 #include "logging.h" 9 #include "language_y.h" 10 #include "field_list.h" 11 #include "fields/all_fields.h" 12 13 extern int yylex(yy::parser::semantic_type*, yy::parser::location_type*, void *); 14 15 ParseLocation toParseLocation(yy::parser::location_type loc) { 16 return ParseLocation(loc.begin.line); 17 } 18 #define LOC toParseLocation(yylloc) 19%} 20 21%parse-param { void* scanner } 22%parse-param { Declarations* decls } 23%lex-param { void* scanner } 24 25%glr-parser 26%skeleton "glr.cc" 27 28%expect-rr 0 29 30%debug 31%define parse.error verbose 32%locations 33%verbose 34 35%union { 36 int integer; 37 std::string* string; 38 39 EnumDef* enum_definition; 40 std::map<int, std::string>* enumeration_values; 41 std::pair<int, std::string>* enumeration_value; 42 43 PacketDef* packet_definition_value; 44 FieldList* packet_field_definitions; 45 PacketField* packet_field_type; 46 47 StructDef* struct_definition_value; 48 49 std::set<std::string*>* test_cases_t; 50 std::string* test_case_t; 51 52 std::map<std::string, std::variant<int64_t, std::string>>* constraint_list_t; 53 std::pair<std::string, std::variant<int64_t, std::string>>* constraint_t; 54} 55 56%token <integer> INTEGER 57%token <integer> IS_LITTLE_ENDIAN 58%token <string> IDENTIFIER 59%token <string> SIZE_MODIFIER 60%token <string> STRING 61 62%token ENUM "enum" 63%token PACKET "packet" 64%token PAYLOAD "payload" 65%token BODY "body" 66%token STRUCT "struct" 67%token SIZE "size" 68%token COUNT "count" 69%token FIXED "fixed" 70%token RESERVED "reserved" 71%token GROUP "group" 72%token CUSTOM_FIELD "custom_field" 73%token CHECKSUM "checksum" 74%token CHECKSUM_START "checksum_start" 75%token PADDING "padding" 76%token TEST "test" 77 78%type<enum_definition> enum_definition 79%type<enumeration_values> enumeration_list 80%type<enumeration_value> enumeration 81 82%type<packet_definition_value> packet_definition; 83%type<packet_field_definitions> field_definition_list; 84%type<packet_field_type> field_definition; 85%type<packet_field_type> group_field_definition; 86%type<packet_field_type> type_def_field_definition; 87%type<packet_field_type> scalar_field_definition; 88%type<packet_field_type> checksum_start_field_definition; 89%type<packet_field_type> padding_field_definition; 90%type<packet_field_type> size_field_definition; 91%type<packet_field_type> payload_field_definition; 92%type<packet_field_type> body_field_definition; 93%type<packet_field_type> fixed_field_definition; 94%type<packet_field_type> reserved_field_definition; 95%type<packet_field_type> array_field_definition; 96 97%type<struct_definition_value> struct_definition; 98 99%type<test_cases_t> test_definition; 100%type<test_cases_t> test_case_list; 101%type<test_case_t> test_case; 102 103%type<constraint_list_t> constraint_list; 104%type<constraint_t> constraint; 105%destructor { std::cout << "DESTROYING STRING " << *$$ << "\n"; delete $$; } IDENTIFIER STRING SIZE_MODIFIER 106 107%% 108 109file 110 : IS_LITTLE_ENDIAN declarations 111 { 112 decls->is_little_endian = ($1 == 1); 113 if (decls->is_little_endian) { 114 DEBUG() << "LITTLE ENDIAN "; 115 } else { 116 DEBUG() << "BIG ENDIAN "; 117 } 118 } 119 120declarations 121 : /* empty */ 122 | declarations declaration 123 124declaration 125 : enum_definition 126 { 127 DEBUG() << "FOUND ENUM\n\n"; 128 decls->AddTypeDef($1->name_, $1); 129 } 130 | packet_definition 131 { 132 DEBUG() << "FOUND PACKET\n\n"; 133 decls->AddPacketDef($1->name_, $1); 134 } 135 | struct_definition 136 { 137 DEBUG() << "FOUND STRUCT\n\n"; 138 decls->AddTypeDef($1->name_, $1); 139 } 140 | group_definition 141 { 142 // All actions are handled in group_definition 143 } 144 | checksum_definition 145 { 146 // All actions are handled in checksum_definition 147 } 148 | custom_field_definition 149 { 150 // All actions are handled in custom_field_definition 151 } 152 | test_definition 153 { 154 // All actions are handled in test_definition 155 } 156 157enum_definition 158 : ENUM IDENTIFIER ':' INTEGER '{' enumeration_list ',' '}' 159 { 160 DEBUG() << "Enum Declared: name=" << *$2 161 << " size=" << $4 << "\n"; 162 163 $$ = new EnumDef(std::move(*$2), $4); 164 for (const auto& e : *$6) { 165 $$->AddEntry(e.second, e.first); 166 } 167 delete $2; 168 delete $6; 169 } 170 171enumeration_list 172 : enumeration 173 { 174 DEBUG() << "Enumerator with comma\n"; 175 $$ = new std::map<int, std::string>(); 176 $$->insert(std::move(*$1)); 177 delete $1; 178 } 179 | enumeration_list ',' enumeration 180 { 181 DEBUG() << "Enumerator with list\n"; 182 $$ = $1; 183 $$->insert(std::move(*$3)); 184 delete $3; 185 } 186 187enumeration 188 : IDENTIFIER '=' INTEGER 189 { 190 DEBUG() << "Enumerator: name=" << *$1 191 << " value=" << $3 << "\n"; 192 $$ = new std::pair($3, std::move(*$1)); 193 delete $1; 194 } 195 196group_definition 197 : GROUP IDENTIFIER '{' field_definition_list '}' 198 { 199 decls->AddGroupDef(*$2, $4); 200 delete $2; 201 } 202 203checksum_definition 204 : CHECKSUM IDENTIFIER ':' INTEGER STRING 205 { 206 DEBUG() << "Checksum field defined\n"; 207 decls->AddTypeDef(*$2, new ChecksumDef(*$2, *$5, $4)); 208 delete $2; 209 delete $5; 210 } 211 212custom_field_definition 213 : CUSTOM_FIELD IDENTIFIER ':' INTEGER STRING 214 { 215 decls->AddTypeDef(*$2, new CustomFieldDef(*$2, *$5, $4)); 216 delete $2; 217 delete $5; 218 } 219 | CUSTOM_FIELD IDENTIFIER STRING 220 { 221 decls->AddTypeDef(*$2, new CustomFieldDef(*$2, *$3)); 222 delete $2; 223 delete $3; 224 } 225 226test_definition 227 : TEST IDENTIFIER '{' test_case_list ',' '}' 228 { 229 auto&& packet_name = *$2; 230 DEBUG() << "Test Declared: name=" << *$2 << "\n"; 231 auto packet = decls->GetPacketDef(packet_name); 232 if (packet == nullptr) { 233 ERRORLOC(LOC) << "Could not find packet " << packet_name << "\n"; 234 } 235 236 for (const auto& t : *$4) { 237 packet->AddTestCase(*t); 238 } 239 delete $2; 240 delete $4; 241 } 242 243test_case_list 244 : test_case 245 { 246 DEBUG() << "Test case with comma\n"; 247 $$ = new std::set<std::string*>(); 248 $$->insert($1); 249 } 250 | test_case_list ',' test_case 251 { 252 DEBUG() << "Test case with list\n"; 253 $$ = $1; 254 $$->insert($3); 255 } 256 257test_case 258 : STRING 259 { 260 DEBUG() << "Test Case: name=" << *$1 << "\n"; 261 $$ = $1; 262 } 263 264struct_definition 265 : STRUCT IDENTIFIER '{' field_definition_list '}' 266 { 267 auto&& struct_name = *$2; 268 auto&& field_definition_list = *$4; 269 270 DEBUG() << "Struct " << struct_name << " with no parent"; 271 DEBUG() << "STRUCT FIELD LIST SIZE: " << field_definition_list.size(); 272 auto struct_definition = new StructDef(std::move(struct_name), std::move(field_definition_list)); 273 struct_definition->AssignSizeFields(); 274 275 $$ = struct_definition; 276 delete $2; 277 delete $4; 278 } 279 | STRUCT IDENTIFIER ':' IDENTIFIER '{' field_definition_list '}' 280 { 281 auto&& struct_name = *$2; 282 auto&& parent_struct_name = *$4; 283 auto&& field_definition_list = *$6; 284 285 DEBUG() << "Struct " << struct_name << " with parent " << parent_struct_name << "\n"; 286 DEBUG() << "STRUCT FIELD LIST SIZE: " << field_definition_list.size() << "\n"; 287 288 auto parent_struct = decls->GetTypeDef(parent_struct_name); 289 if (parent_struct == nullptr) { 290 ERRORLOC(LOC) << "Could not find struct " << parent_struct_name 291 << " used as parent for " << struct_name; 292 } 293 294 if (parent_struct->GetDefinitionType() != TypeDef::Type::STRUCT) { 295 ERRORLOC(LOC) << parent_struct_name << " is not a struct"; 296 } 297 auto struct_definition = new StructDef(std::move(struct_name), std::move(field_definition_list), (StructDef*)parent_struct); 298 struct_definition->AssignSizeFields(); 299 300 $$ = struct_definition; 301 delete $2; 302 delete $4; 303 delete $6; 304 } 305 | STRUCT IDENTIFIER ':' IDENTIFIER '(' constraint_list ')' '{' field_definition_list '}' 306 { 307 auto&& struct_name = *$2; 308 auto&& parent_struct_name = *$4; 309 auto&& constraints = *$6; 310 auto&& field_definition_list = *$9; 311 312 auto parent_struct = decls->GetTypeDef(parent_struct_name); 313 if (parent_struct == nullptr) { 314 ERRORLOC(LOC) << "Could not find struct " << parent_struct_name 315 << " used as parent for " << struct_name; 316 } 317 318 if (parent_struct->GetDefinitionType() != TypeDef::Type::STRUCT) { 319 ERRORLOC(LOC) << parent_struct_name << " is not a struct"; 320 } 321 322 auto struct_definition = new StructDef(std::move(struct_name), std::move(field_definition_list), (StructDef*)parent_struct); 323 struct_definition->AssignSizeFields(); 324 325 for (const auto& constraint : constraints) { 326 const auto& constraint_name = constraint.first; 327 const auto& constraint_value = constraint.second; 328 DEBUG() << "Parent constraint on " << constraint_name; 329 struct_definition->AddParentConstraint(constraint_name, constraint_value); 330 } 331 332 $$ = struct_definition; 333 334 delete $2; 335 delete $4; 336 delete $6; 337 delete $9; 338 } 339 340packet_definition 341 : PACKET IDENTIFIER '{' field_definition_list '}' /* Packet with no parent */ 342 { 343 auto&& packet_name = *$2; 344 auto&& field_definition_list = *$4; 345 346 DEBUG() << "Packet " << packet_name << " with no parent"; 347 DEBUG() << "PACKET FIELD LIST SIZE: " << field_definition_list.size(); 348 auto packet_definition = new PacketDef(std::move(packet_name), std::move(field_definition_list)); 349 packet_definition->AssignSizeFields(); 350 351 $$ = packet_definition; 352 delete $2; 353 delete $4; 354 } 355 | PACKET IDENTIFIER ':' IDENTIFIER '{' field_definition_list '}' 356 { 357 auto&& packet_name = *$2; 358 auto&& parent_packet_name = *$4; 359 auto&& field_definition_list = *$6; 360 361 DEBUG() << "Packet " << packet_name << " with parent " << parent_packet_name << "\n"; 362 DEBUG() << "PACKET FIELD LIST SIZE: " << field_definition_list.size() << "\n"; 363 364 auto parent_packet = decls->GetPacketDef(parent_packet_name); 365 if (parent_packet == nullptr) { 366 ERRORLOC(LOC) << "Could not find packet " << parent_packet_name 367 << " used as parent for " << packet_name; 368 } 369 370 371 auto packet_definition = new PacketDef(std::move(packet_name), std::move(field_definition_list), parent_packet); 372 packet_definition->AssignSizeFields(); 373 374 $$ = packet_definition; 375 delete $2; 376 delete $4; 377 delete $6; 378 } 379 | PACKET IDENTIFIER ':' IDENTIFIER '(' constraint_list ')' '{' field_definition_list '}' 380 { 381 auto&& packet_name = *$2; 382 auto&& parent_packet_name = *$4; 383 auto&& constraints = *$6; 384 auto&& field_definition_list = *$9; 385 386 DEBUG() << "Packet " << packet_name << " with parent " << parent_packet_name << "\n"; 387 DEBUG() << "PACKET FIELD LIST SIZE: " << field_definition_list.size() << "\n"; 388 DEBUG() << "CONSTRAINT LIST SIZE: " << constraints.size() << "\n"; 389 390 auto parent_packet = decls->GetPacketDef(parent_packet_name); 391 if (parent_packet == nullptr) { 392 ERRORLOC(LOC) << "Could not find packet " << parent_packet_name 393 << " used as parent for " << packet_name << "\n"; 394 } 395 396 auto packet_definition = new PacketDef(std::move(packet_name), std::move(field_definition_list), parent_packet); 397 packet_definition->AssignSizeFields(); 398 399 for (const auto& constraint : constraints) { 400 const auto& constraint_name = constraint.first; 401 const auto& constraint_value = constraint.second; 402 DEBUG() << "Parent constraint on " << constraint_name; 403 packet_definition->AddParentConstraint(constraint_name, constraint_value); 404 } 405 406 $$ = packet_definition; 407 408 delete $2; 409 delete $4; 410 delete $6; 411 delete $9; 412 } 413 414field_definition_list 415 : /* empty */ 416 { 417 DEBUG() << "Empty Field definition\n"; 418 $$ = new FieldList(); 419 } 420 | field_definition 421 { 422 DEBUG() << "Field definition\n"; 423 $$ = new FieldList(); 424 425 if ($1->GetFieldType() == GroupField::kFieldType) { 426 auto group_fields = static_cast<GroupField*>($1)->GetFields(); 427 FieldList reversed_fields(group_fields->rbegin(), group_fields->rend()); 428 for (auto& field : reversed_fields) { 429 $$->PrependField(field); 430 } 431 delete $1; 432 break; 433 } 434 435 $$->PrependField($1); 436 } 437 | field_definition ',' field_definition_list 438 { 439 DEBUG() << "Field definition with list\n"; 440 $$ = $3; 441 442 if ($1->GetFieldType() == GroupField::kFieldType) { 443 auto group_fields = static_cast<GroupField*>($1)->GetFields(); 444 FieldList reversed_fields(group_fields->rbegin(), group_fields->rend()); 445 for (auto& field : reversed_fields) { 446 $$->PrependField(field); 447 } 448 delete $1; 449 break; 450 } 451 452 $$->PrependField($1); 453 } 454 455field_definition 456 : group_field_definition 457 { 458 DEBUG() << "Group Field"; 459 $$ = $1; 460 } 461 | type_def_field_definition 462 { 463 DEBUG() << "Field with a pre-defined type\n"; 464 $$ = $1; 465 } 466 | scalar_field_definition 467 { 468 DEBUG() << "Scalar field\n"; 469 $$ = $1; 470 } 471 | checksum_start_field_definition 472 { 473 DEBUG() << "Checksum start field\n"; 474 $$ = $1; 475 } 476 | padding_field_definition 477 { 478 DEBUG() << "Padding field\n"; 479 $$ = $1; 480 } 481 | size_field_definition 482 { 483 DEBUG() << "Size field\n"; 484 $$ = $1; 485 } 486 | body_field_definition 487 { 488 DEBUG() << "Body field\n"; 489 $$ = $1; 490 } 491 | payload_field_definition 492 { 493 DEBUG() << "Payload field\n"; 494 $$ = $1; 495 } 496 | fixed_field_definition 497 { 498 DEBUG() << "Fixed field\n"; 499 $$ = $1; 500 } 501 | reserved_field_definition 502 { 503 DEBUG() << "Reserved field\n"; 504 $$ = $1; 505 } 506 | array_field_definition 507 { 508 DEBUG() << "ARRAY field\n"; 509 $$ = $1; 510 } 511 512group_field_definition 513 : IDENTIFIER 514 { 515 auto group = decls->GetGroupDef(*$1); 516 if (group == nullptr) { 517 ERRORLOC(LOC) << "Could not find group with name " << *$1; 518 } 519 520 std::list<PacketField*>* expanded_fields; 521 expanded_fields = new std::list<PacketField*>(group->begin(), group->end()); 522 $$ = new GroupField(LOC, expanded_fields); 523 delete $1; 524 } 525 | IDENTIFIER '{' constraint_list '}' 526 { 527 DEBUG() << "Group with fixed field(s) " << *$1 << "\n"; 528 auto group = decls->GetGroupDef(*$1); 529 if (group == nullptr) { 530 ERRORLOC(LOC) << "Could not find group with name " << *$1; 531 } 532 533 std::list<PacketField*>* expanded_fields = new std::list<PacketField*>(); 534 for (const auto field : *group) { 535 const auto constraint = $3->find(field->GetName()); 536 if (constraint != $3->end()) { 537 if (field->GetFieldType() == ScalarField::kFieldType) { 538 DEBUG() << "Fixing group scalar value\n"; 539 expanded_fields->push_back(new FixedScalarField(field->GetSize().bits(), std::get<int64_t>(constraint->second), LOC)); 540 } else if (field->GetFieldType() == EnumField::kFieldType) { 541 DEBUG() << "Fixing group enum value\n"; 542 543 auto type_def = decls->GetTypeDef(field->GetDataType()); 544 EnumDef* enum_def = (type_def->GetDefinitionType() == TypeDef::Type::ENUM ? (EnumDef*)type_def : nullptr); 545 if (enum_def == nullptr) { 546 ERRORLOC(LOC) << "No enum found of type " << field->GetDataType(); 547 } 548 if (!enum_def->HasEntry(std::get<std::string>(constraint->second))) { 549 ERRORLOC(LOC) << "Enum " << field->GetDataType() << " has no enumeration " << std::get<std::string>(constraint->second); 550 } 551 552 expanded_fields->push_back(new FixedEnumField(enum_def, std::get<std::string>(constraint->second), LOC)); 553 } else { 554 ERRORLOC(LOC) << "Unimplemented constraint of type " << field->GetFieldType(); 555 } 556 $3->erase(constraint); 557 } else { 558 expanded_fields->push_back(field); 559 } 560 } 561 if ($3->size() > 0) { 562 ERRORLOC(LOC) << "Could not find member " << $3->begin()->first << " in group " << *$1; 563 } 564 565 $$ = new GroupField(LOC, expanded_fields); 566 delete $1; 567 delete $3; 568 } 569 570constraint_list 571 : constraint ',' constraint_list 572 { 573 DEBUG() << "Group field value list\n"; 574 $3->insert(*$1); 575 $$ = $3; 576 delete($1); 577 } 578 | constraint 579 { 580 DEBUG() << "Group field value\n"; 581 $$ = new std::map<std::string, std::variant<int64_t, std::string>>(); 582 $$->insert(*$1); 583 delete($1); 584 } 585 586constraint 587 : IDENTIFIER '=' INTEGER 588 { 589 DEBUG() << "Group with a fixed integer value=" << $1 << " value=" << $3 << "\n"; 590 591 $$ = new std::pair(*$1, std::variant<int64_t,std::string>($3)); 592 delete $1; 593 } 594 | IDENTIFIER '=' IDENTIFIER 595 { 596 DEBUG() << "Group with a fixed enum field value=" << *$3 << " enum=" << *$1; 597 598 $$ = new std::pair(*$1, std::variant<int64_t,std::string>(*$3)); 599 delete $1; 600 delete $3; 601 } 602 603type_def_field_definition 604 : IDENTIFIER ':' IDENTIFIER 605 { 606 DEBUG() << "Predefined type field " << *$1 << " : " << *$3 << "\n"; 607 if (auto type_def = decls->GetTypeDef(*$3)) { 608 $$ = type_def->GetNewField(*$1, LOC); 609 } else { 610 ERRORLOC(LOC) << "No type with this name\n"; 611 } 612 delete $1; 613 delete $3; 614 } 615 616scalar_field_definition 617 : IDENTIFIER ':' INTEGER 618 { 619 DEBUG() << "Scalar field " << *$1 << " : " << $3 << "\n"; 620 $$ = new ScalarField(*$1, $3, LOC); 621 delete $1; 622 } 623 624body_field_definition 625 : BODY 626 { 627 DEBUG() << "Body field\n"; 628 $$ = new BodyField(LOC); 629 } 630 631payload_field_definition 632 : PAYLOAD ':' '[' SIZE_MODIFIER ']' 633 { 634 DEBUG() << "Payload field with modifier " << *$4 << "\n"; 635 $$ = new PayloadField(*$4, LOC); 636 delete $4; 637 } 638 | PAYLOAD 639 { 640 DEBUG() << "Payload field\n"; 641 $$ = new PayloadField("", LOC); 642 } 643 644checksum_start_field_definition 645 : CHECKSUM_START '(' IDENTIFIER ')' 646 { 647 DEBUG() << "ChecksumStart field defined\n"; 648 $$ = new ChecksumStartField(*$3, LOC); 649 delete $3; 650 } 651 652padding_field_definition 653 : PADDING '[' INTEGER ']' 654 { 655 DEBUG() << "Padding field defined\n"; 656 $$ = new PaddingField($3, LOC); 657 } 658 659size_field_definition 660 : SIZE '(' IDENTIFIER ')' ':' INTEGER 661 { 662 DEBUG() << "Size field defined\n"; 663 $$ = new SizeField(*$3, $6, LOC); 664 delete $3; 665 } 666 | SIZE '(' PAYLOAD ')' ':' INTEGER 667 { 668 DEBUG() << "Size for payload defined\n"; 669 $$ = new SizeField("payload", $6, LOC); 670 } 671 | SIZE '(' BODY ')' ':' INTEGER 672 { 673 DEBUG() << "Size for body defined\n"; 674 $$ = new SizeField("body", $6, LOC); 675 } 676 | COUNT '(' IDENTIFIER ')' ':' INTEGER 677 { 678 DEBUG() << "Count field defined\n"; 679 $$ = new CountField(*$3, $6, LOC); 680 delete $3; 681 } 682 683fixed_field_definition 684 : FIXED '=' INTEGER ':' INTEGER 685 { 686 DEBUG() << "Fixed field defined value=" << $3 << " size=" << $5 << "\n"; 687 $$ = new FixedScalarField($5, $3, LOC); 688 } 689 | FIXED '=' IDENTIFIER ':' IDENTIFIER 690 { 691 DEBUG() << "Fixed enum field defined value=" << *$3 << " enum=" << *$5; 692 auto type_def = decls->GetTypeDef(*$5); 693 if (type_def != nullptr) { 694 EnumDef* enum_def = (type_def->GetDefinitionType() == TypeDef::Type::ENUM ? (EnumDef*)type_def : nullptr); 695 if (!enum_def->HasEntry(*$3)) { 696 ERRORLOC(LOC) << "Previously defined enum " << enum_def->GetTypeName() << " has no entry for " << *$3; 697 } 698 699 $$ = new FixedEnumField(enum_def, *$3, LOC); 700 } else { 701 ERRORLOC(LOC) << "No enum found with name " << *$5; 702 } 703 704 delete $3; 705 delete $5; 706 } 707 708reserved_field_definition 709 : RESERVED ':' INTEGER 710 { 711 DEBUG() << "Reserved field of size=" << $3 << "\n"; 712 $$ = new ReservedField($3, LOC); 713 } 714 715array_field_definition 716 : IDENTIFIER ':' INTEGER '[' ']' 717 { 718 DEBUG() << "Vector field defined name=" << *$1 << " element_size=" << $3; 719 $$ = new VectorField(*$1, $3, "", LOC); 720 delete $1; 721 } 722 | IDENTIFIER ':' INTEGER '[' SIZE_MODIFIER ']' 723 { 724 DEBUG() << "Vector field defined name=" << *$1 << " element_size=" << $3 725 << " size_modifier=" << *$5; 726 $$ = new VectorField(*$1, $3, *$5, LOC); 727 delete $1; 728 delete $5; 729 } 730 | IDENTIFIER ':' INTEGER '[' INTEGER ']' 731 { 732 DEBUG() << "Array field defined name=" << *$1 << " element_size=" << $3 733 << " fixed_size=" << $5; 734 $$ = new ArrayField(*$1, $3, $5, LOC); 735 delete $1; 736 } 737 | IDENTIFIER ':' IDENTIFIER '[' ']' 738 { 739 DEBUG() << "Vector field defined name=" << *$1 << " type=" << *$3; 740 if (auto type_def = decls->GetTypeDef(*$3)) { 741 $$ = new VectorField(*$1, type_def, "", LOC); 742 } else { 743 ERRORLOC(LOC) << "Can't find type used in array field."; 744 } 745 delete $1; 746 delete $3; 747 } 748 | IDENTIFIER ':' IDENTIFIER '[' SIZE_MODIFIER ']' 749 { 750 DEBUG() << "Vector field defined name=" << *$1 << " type=" << *$3 751 << " size_modifier=" << *$5; 752 if (auto type_def = decls->GetTypeDef(*$3)) { 753 $$ = new VectorField(*$1, type_def, *$5, LOC); 754 } else { 755 ERRORLOC(LOC) << "Can't find type used in array field."; 756 } 757 delete $1; 758 delete $3; 759 delete $5; 760 } 761 | IDENTIFIER ':' IDENTIFIER '[' INTEGER ']' 762 { 763 DEBUG() << "Array field defined name=" << *$1 << " type=" << *$3 764 << " fixed_size=" << $5; 765 if (auto type_def = decls->GetTypeDef(*$3)) { 766 $$ = new ArrayField(*$1, type_def, $5, LOC); 767 } else { 768 ERRORLOC(LOC) << "Can't find type used in array field."; 769 } 770 delete $1; 771 delete $3; 772 } 773 774%% 775 776 777void yy::parser::error(const yy::parser::location_type& loc, const std::string& error) { 778 ERROR() << error << " at location " << loc << "\n"; 779 abort(); 780} 781