1/* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17%{ 18 19#include "Annotation.h" 20#include "AST.h" 21#include "ArrayType.h" 22#include "CompoundType.h" 23#include "ConstantExpression.h" 24#include "EnumType.h" 25#include "Interface.h" 26#include "Location.h" 27#include "Method.h" 28#include "VectorType.h" 29#include "RefType.h" 30 31#include "hidl-gen_y.h" 32 33#include <android-base/logging.h> 34#include <hidl-util/FQName.h> 35#include <hidl-util/StringHelper.h> 36#include <stdio.h> 37 38using namespace android; 39 40extern int yylex(yy::parser::semantic_type *, yy::parser::location_type *, void *); 41 42#define scanner ast->scanner() 43 44::android::Location convertYYLoc(const yy::parser::location_type &loc) { 45 return ::android::Location( 46 ::android::Position(*(loc.begin.filename), loc.begin.line, loc.begin.column), 47 ::android::Position(*(loc.end.filename), loc.end.line, loc.end.column) 48 ); 49} 50 51bool isValidInterfaceField(const char *identifier, std::string *errorMsg) { 52 static const std::vector<std::string> reserved({ 53 // Injected names to interfaces by auto-generated code 54 "isRemote", "descriptor", "hidlStaticBlock", "onTransact", 55 "castFrom", "Proxy", "Stub", 56 57 // Inherited methods from IBase is detected in addMethod. Not added here 58 // because we need hidl-gen to compile IBase. 59 60 // Inherited names by interfaces from IInterface / IBinder 61 "onAsBinder", "asBinder", "queryLocalInterface", "getInterfaceDescriptor", "isBinderAlive", 62 "pingBinder", "dump", "transact", "checkSubclass", "attachObject", "findObject", 63 "detachObject", "localBinder", "remoteBinder", "mImpl", 64 }); 65 std::string idstr(identifier); 66 if (std::find(reserved.begin(), reserved.end(), idstr) != reserved.end()) { 67 *errorMsg = idstr + " cannot be a name inside an interface"; 68 return false; 69 } 70 return true; 71} 72 73bool isValidStructField(const char *identifier, std::string *errorMsg) { 74 static const std::vector<std::string> reserved({ 75 // Injected names to structs and unions by auto-generated code 76 "readEmbeddedFromParcel", "writeEmbeddedToParcel", "readVectorFromParcel", 77 "writeVectorToParcel", "writeEmbeddedToBlob", 78 }); 79 std::string idstr(identifier); 80 if (std::find(reserved.begin(), reserved.end(), idstr) != reserved.end()) { 81 *errorMsg = idstr + " cannot be a name inside an struct or union"; 82 return false; 83 } 84 return true; 85} 86 87bool isValidIdentifier(const char *identifier, std::string *errorMsg) { 88 static const std::vector<std::string> keywords({ 89 "uint8_t", "uint16_t", "uint32_t", "uint64_t", 90 "int8_t", "int16_t", "int32_t", "int64_t", "bool", "float", "double", 91 "interface", "struct", "union", "string", "vec", "enum", "ref", "handle", 92 "package", "import", "typedef", "generates", "oneway", "extends", 93 "fmq_sync", "fmq_unsync", 94 }); 95 static const std::vector<std::string> cppKeywords({ 96 "alignas", "alignof", "and", "and_eq", "asm", "atomic_cancel", "atomic_commit", 97 "atomic_noexcept", "auto", "bitand", "bitor", "bool", "break", "case", "catch", 98 "char", "char16_t", "char32_t", "class", "compl", "concept", "const", "constexpr", 99 "const_cast", "continue", "decltype", "default", "delete", "do", "double", 100 "dynamic_cast", "else", "enum", "explicit", "export", "extern", "false", "float", 101 "for", "friend", "goto", "if", "inline", "int", "import", "long", "module", "mutable", 102 "namespace", "new", "noexcept", "not", "not_eq", "nullptr", "operator", "or", "or_eq", 103 "private", "protected", "public", "register", "reinterpret_cast", "requires", "return", 104 "short", "signed", "sizeof", "static", "static_assert", "static_cast", "struct", 105 "switch", "synchronized", "template", "this", "thread_local", "throw", "true", "try", 106 "typedef", "typeid", "typename", "union", "unsigned", "using", "virtual", "void", 107 "volatile", "wchar_t", "while", "xor", "xor_eq", 108 }); 109 static const std::vector<std::string> javaKeywords({ 110 "abstract", "continue", "for", "new", "switch", "assert", "default", "goto", "package", 111 "synchronized", "boolean", "do", "if", "private", "this", "break", "double", 112 "implements", "protected", "throw", "byte", "else", "import", "public", "throws", 113 "case", "enum", "instanceof", "return", "transient", "catch", "extends", "int", 114 "short", "try", "char", "final", "interface", "static", "void", "class", "finally", 115 "long", "strictfp", "volatile", "const", "float", "native", "super", "while", 116 }); 117 static const std::vector<std::string> cppCollide({ 118 "size_t", "offsetof", 119 "DECLARE_SERVICE_MANAGER_INTERACTIONS", "IMPLEMENT_HWBINDER_META_INTERFACE", 120 "IMPLEMENT_SERVICE_MANAGER_INTERACTIONS" 121 }); 122 static const std::vector<std::string> hidlReserved({ 123 // Part of HidlSupport 124 "hidl_string", "hidl_vec", "hidl_array", "hidl_version", "toBinder", "castInterface", 125 "make_hidl_version" 126 }); 127 128 // errors 129 std::string idstr(identifier); 130 if (std::find(keywords.begin(), keywords.end(), idstr) != keywords.end()) { 131 *errorMsg = idstr + " is a HIDL keyword " 132 "and is therefore not a valid identifier"; 133 return false; 134 } 135 if (std::find(cppKeywords.begin(), cppKeywords.end(), idstr) != cppKeywords.end()) { 136 *errorMsg = idstr + " is a C++ keyword " 137 "and is therefore not a valid identifier"; 138 return false; 139 } 140 if (std::find(javaKeywords.begin(), javaKeywords.end(), idstr) != javaKeywords.end()) { 141 *errorMsg = idstr + " is a Java keyword " 142 "and is therefore not a valid identifier"; 143 return false; 144 } 145 if (std::find(cppCollide.begin(), cppCollide.end(), idstr) != cppCollide.end()) { 146 *errorMsg = idstr + " collides with reserved names in C++ code " 147 "and is therefore not a valid identifier"; 148 return false; 149 } 150 if (StringHelper::StartsWith(idstr, "_hidl_")) { 151 *errorMsg = idstr + " starts with _hidl_ " 152 "and is therefore not a valid identifier"; 153 return false; 154 } 155 if (StringHelper::EndsWith(idstr, "_cb")) { 156 *errorMsg = idstr + " ends with _cb " 157 "and is therefore not a valid identifier"; 158 return false; 159 } 160 161 // warnings 162 if (std::find(hidlReserved.begin(), hidlReserved.end(), idstr) != hidlReserved.end()) { 163 *errorMsg = idstr + " is a name reserved by HIDL and should be avoided"; 164 } 165 return true; 166} 167 168%} 169 170%initial-action { 171 // Initialize the initial location. 172 @$.begin.filename = @$.end.filename = 173 const_cast<std::string *>(&ast->getFilename()); 174} 175 176%parse-param { android::AST *ast } 177%lex-param { void *scanner } 178%pure-parser 179%glr-parser 180%skeleton "glr.cc" 181 182%expect-rr 0 183 184%token<str> ENUM 185%token<str> EXTENDS 186%token<str> FQNAME 187%token<str> GENERATES 188%token<str> IDENTIFIER 189%token<str> IMPORT 190%token<str> INTEGER 191%token<str> FLOAT 192%token<str> INTERFACE 193%token<str> PACKAGE 194%token<type> TYPE 195%token<str> STRUCT 196%token<str> STRING_LITERAL 197%token<str> TYPEDEF 198%token<str> UNION 199%token<templatedType> TEMPLATED 200%token<void> ONEWAY 201 202/* Operator precedence and associativity, as per 203 * http://en.cppreference.com/w/cpp/language/operator_precedence */ 204/* Precedence level 15 ternary operator */ 205%right '?' ':' 206/* Precedence level 13 - 14, LTR, logical operators*/ 207%left LOGICAL_OR 208%left LOGICAL_AND 209/* Precedence level 10 - 12, LTR, bitwise operators*/ 210%left '|' 211%left '^' 212%left '&' 213/* Precedence level 9, LTR */ 214%left EQUALITY NEQ 215/* Precedence level 8, LTR */ 216%left '<' '>' LEQ GEQ 217/* Precedence level 7, LTR */ 218%left LSHIFT RSHIFT 219/* Precedence level 6, LTR */ 220%left '+' '-' 221/* Precedence level 5, LTR */ 222%left '*' '/' '%' 223/* Precedence level 3, RTL; but we have to use %left here */ 224%left UNARY_MINUS UNARY_PLUS '!' '~' 225 226%type<str> error_stmt opt_error_stmt error 227%type<str> package 228%type<fqName> fqname 229%type<type> fqtype 230%type<str> valid_identifier 231 232%type<type> type enum_storage_type 233%type<type> array_type_base 234%type<arrayType> array_type 235%type<type> opt_extends 236%type<type> type_declaration type_declaration_body interface_declaration typedef_declaration 237%type<type> named_struct_or_union_declaration named_enum_declaration 238%type<type> compound_declaration annotated_compound_declaration 239 240%type<field> field_declaration 241%type<fields> field_declarations struct_or_union_body 242%type<constantExpression> const_expr 243%type<enumValue> enum_value 244%type<enumValues> enum_values enum_declaration_body 245%type<typedVars> typed_vars 246%type<typedVar> typed_var 247%type<method> method_declaration 248%type<compoundStyle> struct_or_union_keyword 249%type<stringVec> annotation_string_values annotation_string_value 250%type<constExprVec> annotation_const_expr_values annotation_const_expr_value 251%type<annotationParam> annotation_param 252%type<annotationParams> opt_annotation_params annotation_params 253%type<annotation> annotation 254%type<annotations> opt_annotations 255 256%start program 257 258%union { 259 const char *str; 260 android::Type *type; 261 android::ArrayType *arrayType; 262 android::TemplatedType *templatedType; 263 android::FQName *fqName; 264 android::CompoundType *compoundType; 265 android::CompoundField *field; 266 std::vector<android::CompoundField *> *fields; 267 android::EnumValue *enumValue; 268 android::ConstantExpression *constantExpression; 269 std::vector<android::EnumValue *> *enumValues; 270 android::TypedVar *typedVar; 271 android::TypedVarVector *typedVars; 272 android::Method *method; 273 android::CompoundType::Style compoundStyle; 274 std::vector<std::string> *stringVec; 275 std::vector<android::ConstantExpression *> *constExprVec; 276 android::AnnotationParam *annotationParam; 277 android::AnnotationParamVector *annotationParams; 278 android::Annotation *annotation; 279 std::vector<android::Annotation *> *annotations; 280} 281 282%% 283 284valid_identifier 285 : IDENTIFIER 286 { 287 std::string errorMsg; 288 if (!isValidIdentifier($1, &errorMsg)) { 289 std::cerr << "ERROR: " << errorMsg << " at " << @1 << "\n"; 290 YYERROR; 291 } 292 if (!errorMsg.empty()) { 293 std::cerr << "WARNING: " << errorMsg << " at " << @1 << "\n"; 294 } 295 $$ = $1; 296 } 297 ; 298 299opt_annotations 300 : /* empty */ 301 { 302 $$ = new std::vector<Annotation *>; 303 } 304 | opt_annotations annotation 305 { 306 $$ = $1; 307 $$->push_back($2); 308 } 309 ; 310 311annotation 312 : '@' IDENTIFIER opt_annotation_params 313 { 314 $$ = new Annotation($2, $3); 315 } 316 ; 317 318opt_annotation_params 319 : /* empty */ 320 { 321 $$ = new AnnotationParamVector; 322 } 323 | '(' annotation_params ')' 324 { 325 $$ = $2; 326 } 327 ; 328 329annotation_params 330 : annotation_param 331 { 332 $$ = new AnnotationParamVector; 333 $$->push_back($1); 334 } 335 | annotation_params ',' annotation_param 336 { 337 $$ = $1; 338 $$->push_back($3); 339 } 340 ; 341 342annotation_param 343 : IDENTIFIER '=' annotation_string_value 344 { 345 $$ = new AnnotationParam($1, $3); 346 } 347 | IDENTIFIER '=' annotation_const_expr_value 348 { 349 $$ = new AnnotationParam($1, $3); 350 } 351 ; 352 353annotation_string_value 354 : STRING_LITERAL 355 { 356 $$ = new std::vector<std::string>; 357 $$->push_back($1); 358 } 359 | '{' annotation_string_values '}' { $$ = $2; } 360 ; 361 362annotation_string_values 363 : STRING_LITERAL 364 { 365 $$ = new std::vector<std::string>; 366 $$->push_back($1); 367 } 368 | annotation_string_values ',' STRING_LITERAL 369 { 370 $$ = $1; 371 $$->push_back($3); 372 } 373 ; 374 375annotation_const_expr_value 376 : const_expr 377 { 378 $$ = new std::vector<ConstantExpression *>; 379 $$->push_back($1); 380 } 381 | '{' annotation_const_expr_values '}' { $$ = $2; } 382 ; 383 384annotation_const_expr_values 385 : const_expr 386 { 387 $$ = new std::vector<ConstantExpression *>; 388 $$->push_back($1); 389 } 390 | annotation_const_expr_values ',' const_expr 391 { 392 $$ = $1; 393 $$->push_back($3); 394 } 395 ; 396 397error_stmt 398 : error ';' 399 { 400 $$ = $1; 401 ast->addSyntaxError(); 402 // std::cerr << "WARNING: skipping errors until " << @2 << ".\n"; 403 } 404 ; 405 406opt_error_stmt 407 : /* empty */ { $$ = NULL; } 408 | error_stmt { $$ = $1; } 409 ; 410 411require_semicolon 412 : ';' 413 | /* empty */ 414 { 415 std::cerr << "ERROR: missing ; at " << @$ << "\n"; 416 ast->addSyntaxError(); 417 } 418 ; 419 420program 421 : opt_error_stmt 422 package 423 imports 424 body 425 ; 426 427fqname 428 : FQNAME 429 { 430 $$ = new FQName($1); 431 if(!$$->isValid()) { 432 std::cerr << "ERROR: FQName '" << $1 << "' is not valid at " 433 << @1 434 << ".\n"; 435 YYERROR; 436 } 437 } 438 | valid_identifier 439 { 440 $$ = new FQName($1); 441 if(!$$->isValid()) { 442 std::cerr << "ERROR: FQName '" << $1 << "' is not valid at " 443 << @1 444 << ".\n"; 445 YYERROR; 446 } 447 } 448 ; 449 450fqtype 451 : fqname 452 { 453 $$ = ast->lookupType(*($1)); 454 if ($$ == NULL) { 455 std::cerr << "ERROR: Failed to lookup type '" << $1->string() << "' at " 456 << @1 457 << "\n"; 458 459 YYERROR; 460 } 461 } 462 | TYPE 463 ; 464 465package 466 : PACKAGE FQNAME require_semicolon 467 { 468 if (!ast->setPackage($2)) { 469 std::cerr << "ERROR: Malformed package identifier '" 470 << $2 471 << "' at " 472 << @2 473 << "\n"; 474 475 YYERROR; 476 } 477 } 478 479import_stmt 480 : IMPORT FQNAME require_semicolon 481 { 482 if (!ast->addImport($2)) { 483 std::cerr << "ERROR: Unable to import '" << $2 << "' at " << @2 484 << "\n"; 485 ast->addSyntaxError(); 486 } 487 } 488 | IMPORT valid_identifier require_semicolon 489 { 490 if (!ast->addImport($2)) { 491 std::cerr << "ERROR: Unable to import '" << $2 << "' at " << @2 492 << "\n"; 493 ast->addSyntaxError(); 494 } 495 } 496 | IMPORT error_stmt 497 ; 498 499 500imports 501 : /* empty */ 502 | imports import_stmt 503 ; 504 505opt_extends 506 : /* empty */ { $$ = NULL; } 507 | EXTENDS fqtype { $$ = $2; } 508 509body 510 : type_declarations 511 ; 512 513interface_declarations 514 : /* empty */ 515 | interface_declarations type_declaration 516 { 517 std::string errorMsg; 518 if ($2 != nullptr && 519 $2->isNamedType() && 520 !isValidInterfaceField(static_cast<NamedType *>($2)->localName().c_str(), 521 &errorMsg)) { 522 std::cerr << "ERROR: " << errorMsg << " at " 523 << @2 << "\n"; 524 YYERROR; 525 } 526 } 527 | interface_declarations method_declaration 528 { 529 std::string errorMsg; 530 if ($2 != nullptr && 531 !isValidInterfaceField($2->name().c_str(), &errorMsg)) { 532 std::cerr << "ERROR: " << errorMsg << " at " 533 << @2 << "\n"; 534 YYERROR; 535 } 536 537 if ($2 != nullptr) { 538 if (!ast->scope()->isInterface()) { 539 std::cerr << "ERROR: unknown error in interface declaration at " 540 << @2 << "\n"; 541 YYERROR; 542 } 543 544 Interface *iface = static_cast<Interface *>(ast->scope()); 545 if (!iface->addMethod($2)) { 546 std::cerr << "ERROR: Unable to add method '" << $2->name() 547 << "' at " << @2 << "\n"; 548 549 YYERROR; 550 } 551 } 552 // ignore if $2 is nullptr (from error recovery) 553 } 554 ; 555 556type_declarations 557 : /* empty */ 558 | error_stmt 559 | type_declarations type_declaration 560 ; 561 562type_declaration 563 : opt_annotations type_declaration_body 564 { 565 if ($2 != nullptr) { 566 $2->setAnnotations($1); 567 } else if (!$1->empty()) { 568 // Since typedefs are always resolved to their target it makes 569 // little sense to annotate them and have their annotations 570 // impose semantics other than their target type. 571 std::cerr << "ERROR: typedefs cannot be annotated. at " << @2 572 << "\n"; 573 574 YYERROR; 575 } 576 $$ = $2; 577 } 578 ; 579 580type_declaration_body 581 : named_struct_or_union_declaration require_semicolon 582 | named_enum_declaration require_semicolon 583 | typedef_declaration require_semicolon 584 | interface_declaration require_semicolon 585 ; 586 587interface_declaration 588 : INTERFACE valid_identifier opt_extends 589 { 590 Type *parent = $3; 591 592 if (ast->package() != gIBasePackageFqName) { 593 if (!ast->addImport(gIBaseFqName.string().c_str())) { 594 std::cerr << "ERROR: Unable to automatically import '" 595 << gIBaseFqName.string() 596 << "' at " << @$ 597 << "\n"; 598 YYERROR; 599 } 600 if (parent == nullptr) { 601 parent = ast->lookupType(gIBaseFqName); 602 } 603 } 604 605 if (parent != NULL && !parent->isInterface()) { 606 std::cerr << "ERROR: You can only extend interfaces. at " << @3 607 << "\n"; 608 609 YYERROR; 610 } 611 612 if ($2[0] != 'I') { 613 std::cerr << "ERROR: All interface names must start with an 'I' " 614 << "prefix. at " << @2 << "\n"; 615 616 YYERROR; 617 } 618 619 Interface *iface = new Interface($2, convertYYLoc(@2), static_cast<Interface *>(parent)); 620 621 // Register interface immediately so it can be referenced inside 622 // definition. 623 std::string errorMsg; 624 if (!ast->addScopedType(iface, &errorMsg)) { 625 std::cerr << "ERROR: " << errorMsg << " at " << @2 << "\n"; 626 YYERROR; 627 } 628 629 ast->enterScope(iface); 630 } 631 '{' interface_declarations '}' 632 { 633 if (!ast->scope()->isInterface()) { 634 std::cerr << "ERROR: unknown error in interface declaration at " 635 << @5 << "\n"; 636 YYERROR; 637 } 638 639 Interface *iface = static_cast<Interface *>(ast->scope()); 640 if (!iface->addAllReservedMethods()) { 641 std::cerr << "ERROR: unknown error in adding reserved methods at " 642 << @5 << "\n"; 643 YYERROR; 644 } 645 646 ast->leaveScope(); 647 648 $$ = iface; 649 } 650 ; 651 652typedef_declaration 653 : TYPEDEF type valid_identifier 654 { 655 std::string errorMsg; 656 if (!ast->addTypeDef($3, $2, convertYYLoc(@3), &errorMsg)) { 657 std::cerr << "ERROR: " << errorMsg << " at " << @3 << "\n"; 658 YYERROR; 659 } 660 661 $$ = nullptr; 662 } 663 ; 664 665const_expr 666 : INTEGER { $$ = new ConstantExpression($1); } 667 | fqname 668 { 669 if(!$1->isValidValueName()) { 670 std::cerr << "ERROR: '" << $1->string() 671 << "' does not refer to an enum value at " 672 << @1 << ".\n"; 673 YYERROR; 674 } 675 if($1->isIdentifier()) { 676 std::string identifier = $1->name(); 677 LocalIdentifier *iden = ast->scope()->lookupIdentifier(identifier); 678 if(!iden) { 679 std::cerr << "ERROR: identifier " << $1->string() 680 << " could not be found at " << @1 << ".\n"; 681 YYERROR; 682 } 683 if(!iden->isEnumValue()) { 684 std::cerr << "ERROR: identifier " << $1->string() 685 << " is not an enum value at " << @1 << ".\n"; 686 YYERROR; 687 } 688 $$ = new ConstantExpression( 689 *(static_cast<EnumValue *>(iden)->constExpr()), $1->string()); 690 } else { 691 std::string errorMsg; 692 EnumValue *v = ast->lookupEnumValue(*($1), &errorMsg); 693 if(v == nullptr) { 694 std::cerr << "ERROR: " << errorMsg << " at " << @1 << ".\n"; 695 YYERROR; 696 } 697 $$ = new ConstantExpression(*(v->constExpr()), $1->string()); 698 } 699 } 700 | const_expr '?' const_expr ':' const_expr 701 { 702 $$ = new ConstantExpression($1, $3, $5); 703 } 704 | const_expr LOGICAL_OR const_expr { $$ = new ConstantExpression($1, "||", $3); } 705 | const_expr LOGICAL_AND const_expr { $$ = new ConstantExpression($1, "&&", $3); } 706 | const_expr '|' const_expr { $$ = new ConstantExpression($1, "|" , $3); } 707 | const_expr '^' const_expr { $$ = new ConstantExpression($1, "^" , $3); } 708 | const_expr '&' const_expr { $$ = new ConstantExpression($1, "&" , $3); } 709 | const_expr EQUALITY const_expr { $$ = new ConstantExpression($1, "==", $3); } 710 | const_expr NEQ const_expr { $$ = new ConstantExpression($1, "!=", $3); } 711 | const_expr '<' const_expr { $$ = new ConstantExpression($1, "<" , $3); } 712 | const_expr '>' const_expr { $$ = new ConstantExpression($1, ">" , $3); } 713 | const_expr LEQ const_expr { $$ = new ConstantExpression($1, "<=", $3); } 714 | const_expr GEQ const_expr { $$ = new ConstantExpression($1, ">=", $3); } 715 | const_expr LSHIFT const_expr { $$ = new ConstantExpression($1, "<<", $3); } 716 | const_expr RSHIFT const_expr { $$ = new ConstantExpression($1, ">>", $3); } 717 | const_expr '+' const_expr { $$ = new ConstantExpression($1, "+" , $3); } 718 | const_expr '-' const_expr { $$ = new ConstantExpression($1, "-" , $3); } 719 | const_expr '*' const_expr { $$ = new ConstantExpression($1, "*" , $3); } 720 | const_expr '/' const_expr { $$ = new ConstantExpression($1, "/" , $3); } 721 | const_expr '%' const_expr { $$ = new ConstantExpression($1, "%" , $3); } 722 | '+' const_expr %prec UNARY_PLUS { $$ = new ConstantExpression("+", $2); } 723 | '-' const_expr %prec UNARY_MINUS { $$ = new ConstantExpression("-", $2); } 724 | '!' const_expr { $$ = new ConstantExpression("!", $2); } 725 | '~' const_expr { $$ = new ConstantExpression("~", $2); } 726 | '(' const_expr ')' { $$ = $2; } 727 | '(' error ')' 728 { 729 ast->addSyntaxError(); 730 // to avoid segfaults 731 $$ = new ConstantExpression(ConstantExpression::Zero(ScalarType::KIND_INT32)); 732 } 733 ; 734 735method_declaration 736 : error_stmt { $$ = nullptr; } 737 | opt_annotations valid_identifier '(' typed_vars ')' require_semicolon 738 { 739 $$ = new Method($2, $4, new std::vector<TypedVar *>, false, $1); 740 } 741 | opt_annotations ONEWAY valid_identifier '(' typed_vars ')' require_semicolon 742 { 743 $$ = new Method($3, $5, new std::vector<TypedVar *>, true, $1); 744 } 745 | opt_annotations valid_identifier '(' typed_vars ')' GENERATES '(' typed_vars ')' require_semicolon 746 { 747 $$ = new Method($2, $4, $8, false, $1); 748 } 749 ; 750 751typed_vars 752 : /* empty */ 753 { 754 $$ = new TypedVarVector(); 755 } 756 | typed_var 757 { 758 $$ = new TypedVarVector(); 759 if (!$$->add($1)) { 760 std::cerr << "ERROR: duplicated argument or result name " 761 << $1->name() << " at " << @1 << "\n"; 762 ast->addSyntaxError(); 763 } 764 } 765 | typed_vars ',' typed_var 766 { 767 $$ = $1; 768 if (!$$->add($3)) { 769 std::cerr << "ERROR: duplicated argument or result name " 770 << $3->name() << " at " << @3 << "\n"; 771 ast->addSyntaxError(); 772 } 773 } 774 ; 775 776typed_var : type valid_identifier { $$ = new TypedVar($2, $1); } 777 ; 778 779 780struct_or_union_keyword 781 : STRUCT { $$ = CompoundType::STYLE_STRUCT; } 782 | UNION { $$ = CompoundType::STYLE_UNION; } 783 ; 784 785named_struct_or_union_declaration 786 : struct_or_union_keyword valid_identifier 787 { 788 CompoundType *container = new CompoundType($1, $2, convertYYLoc(@2)); 789 ast->enterScope(container); 790 } 791 struct_or_union_body 792 { 793 if (!ast->scope()->isCompoundType()) { 794 std::cerr << "ERROR: unknown error in struct or union declaration at " 795 << @4 << "\n"; 796 YYERROR; 797 } 798 CompoundType *container = static_cast<CompoundType *>(ast->scope()); 799 800 std::string errorMsg; 801 if (!container->setFields($4, &errorMsg)) { 802 std::cerr << "ERROR: " << errorMsg << " at " << @4 << "\n"; 803 YYERROR; 804 } 805 806 ast->leaveScope(); 807 808 if (!ast->addScopedType(container, &errorMsg)) { 809 std::cerr << "ERROR: " << errorMsg << " at " << @2 << "\n"; 810 YYERROR; 811 } 812 813 $$ = container; 814 } 815 ; 816 817struct_or_union_body 818 : '{' field_declarations '}' { $$ = $2; } 819 ; 820 821field_declarations 822 : /* empty */ { $$ = new std::vector<CompoundField *>; } 823 | field_declarations field_declaration 824 { 825 $$ = $1; 826 827 if ($2 != NULL) { 828 $$->push_back($2); 829 } 830 } 831 ; 832 833field_declaration 834 : error_stmt { $$ = nullptr; } 835 | type valid_identifier require_semicolon 836 { 837 std::string errorMsg; 838 if (ast->scope()->isCompoundType() && 839 static_cast<CompoundType *>(ast->scope())->style() == CompoundType::STYLE_STRUCT && 840 !isValidStructField($2, &errorMsg)) { 841 std::cerr << "ERROR: " << errorMsg << " at " 842 << @2 << "\n"; 843 YYERROR; 844 } 845 $$ = new CompoundField($2, $1); 846 } 847 | annotated_compound_declaration ';' 848 { 849 std::string errorMsg; 850 if (ast->scope()->isCompoundType() && 851 static_cast<CompoundType *>(ast->scope())->style() == CompoundType::STYLE_STRUCT && 852 $1 != nullptr && 853 $1->isNamedType() && 854 !isValidStructField(static_cast<NamedType *>($1)->localName().c_str(), &errorMsg)) { 855 std::cerr << "ERROR: " << errorMsg << " at " 856 << @2 << "\n"; 857 YYERROR; 858 } 859 $$ = NULL; 860 } 861 ; 862 863annotated_compound_declaration 864 : opt_annotations compound_declaration 865 { 866 $2->setAnnotations($1); 867 $$ = $2; 868 } 869 ; 870 871compound_declaration 872 : named_struct_or_union_declaration { $$ = $1; } 873 | named_enum_declaration { $$ = $1; } 874 ; 875 876enum_storage_type 877 : ':' fqtype 878 { 879 $$ = $2; 880 881 if ($$ != NULL && !$$->isValidEnumStorageType()) { 882 std::cerr << "ERROR: Invalid enum storage type specified. at " 883 << @2 << "\n"; 884 885 YYERROR; 886 } 887 } 888 ; 889 890opt_comma 891 : /* empty */ 892 | ',' 893 ; 894 895named_enum_declaration 896 : ENUM valid_identifier enum_storage_type 897 { 898 ast->enterScope(new EnumType($2, convertYYLoc(@2), $3)); 899 } 900 enum_declaration_body 901 { 902 if (!ast->scope()->isEnum()) { 903 std::cerr << "ERROR: unknown error in enum declaration at " 904 << @5 << "\n"; 905 YYERROR; 906 } 907 908 EnumType *enumType = static_cast<EnumType *>(ast->scope()); 909 ast->leaveScope(); 910 911 std::string errorMsg; 912 if (!ast->addScopedType(enumType, &errorMsg)) { 913 std::cerr << "ERROR: " << errorMsg << " at " << @2 << "\n"; 914 YYERROR; 915 } 916 917 $$ = enumType; 918 } 919 ; 920 921enum_declaration_body 922 : '{' enum_values opt_comma '}' { $$ = $2; } 923 ; 924 925enum_value 926 : valid_identifier { $$ = new EnumValue($1); } 927 | valid_identifier '=' const_expr { $$ = new EnumValue($1, $3); } 928 ; 929 930enum_values 931 : /* empty */ 932 { /* do nothing */ } 933 | enum_value 934 { 935 if (!ast->scope()->isEnum()) { 936 std::cerr << "ERROR: unknown error in enum declaration at " 937 << @1 << "\n"; 938 YYERROR; 939 } 940 941 static_cast<EnumType *>(ast->scope())->addValue($1); 942 } 943 | enum_values ',' enum_value 944 { 945 if (!ast->scope()->isEnum()) { 946 std::cerr << "ERROR: unknown error in enum declaration at " 947 << @3 << "\n"; 948 YYERROR; 949 } 950 951 static_cast<EnumType *>(ast->scope())->addValue($3); 952 } 953 ; 954 955array_type_base 956 : fqtype { $$ = $1; } 957 | TEMPLATED '<' type '>' 958 { 959 if (!$1->isCompatibleElementType($3)) { 960 std::cerr << "ERROR: " << $1->typeName() << " of " << $3->typeName() 961 << " is not supported. at " << @3 << "\n"; 962 963 YYERROR; 964 } 965 $1->setElementType($3); 966 $$ = $1; 967 } 968 | TEMPLATED '<' TEMPLATED '<' type RSHIFT 969 { 970 if (!$3->isCompatibleElementType($5)) { 971 std::cerr << "ERROR: " << $3->typeName() << " of " << $5->typeName() 972 << " is not supported. at " << @3 << "\n"; 973 974 YYERROR; 975 } 976 $3->setElementType($5); 977 if (!$1->isCompatibleElementType($3)) { 978 std::cerr << "ERROR: " << $1->typeName() << " of " << $3->typeName() 979 << " is not supported. at " << @3 << "\n"; 980 981 YYERROR; 982 } 983 $1->setElementType($3); 984 $$ = $1; 985 } 986 ; 987 988array_type 989 : array_type_base '[' const_expr ']' 990 { 991 if ($1->isBinder()) { 992 std::cerr << "ERROR: Arrays of interface types are not supported." 993 << " at " << @1 << "\n"; 994 995 YYERROR; 996 } 997 if ($1->isArray()) { 998 $$ = new ArrayType(static_cast<ArrayType *>($1), $3); 999 } else { 1000 $$ = new ArrayType($1, $3); 1001 } 1002 } 1003 | array_type '[' const_expr ']' 1004 { 1005 $$ = $1; 1006 $$->appendDimension($3); 1007 } 1008 ; 1009 1010type 1011 : array_type_base { $$ = $1; } 1012 | array_type { $$ = $1; } 1013 | annotated_compound_declaration { $$ = $1; } 1014 | INTERFACE 1015 { 1016 // "interface" is a synonym of android.hidl.base@1.0::IBase 1017 $$ = ast->lookupType(gIBaseFqName); 1018 if ($$ == nullptr) { 1019 std::cerr << "FATAL: Cannot find " 1020 << gIBaseFqName.string() 1021 << " at " << @1 << "\n"; 1022 1023 YYERROR; 1024 } 1025 } 1026 ; 1027 1028%% 1029 1030#include <android-base/logging.h> 1031 1032void yy::parser::error( 1033 const yy::parser::location_type &where, 1034 const std::string &errstr) { 1035 std::cerr << "ERROR: " << errstr << " at " << where << "\n"; 1036} 1037 1038