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