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#include "aidl_language.h" 19#include "parser.h" 20#include "aidl_language_y.h" 21#include "logging.h" 22#include <android-base/parseint.h> 23#include <set> 24#include <map> 25#include <stdio.h> 26#include <stdlib.h> 27#include <string.h> 28 29int yylex(yy::parser::semantic_type *, yy::parser::location_type *, void *); 30 31AidlLocation loc(const yy::parser::location_type& begin, const yy::parser::location_type& end) { 32 AIDL_FATAL_IF(begin.begin.filename != begin.end.filename, AIDL_LOCATION_HERE); 33 AIDL_FATAL_IF(begin.end.filename != end.begin.filename, AIDL_LOCATION_HERE); 34 AIDL_FATAL_IF(end.begin.filename != end.end.filename, AIDL_LOCATION_HERE); 35 AidlLocation::Point begin_point { 36 .line = begin.begin.line, 37 .column = begin.begin.column, 38 }; 39 AidlLocation::Point end_point { 40 .line = end.end.line, 41 .column = end.end.column, 42 }; 43 return AidlLocation(*begin.begin.filename, begin_point, end_point, AidlLocation::Source::EXTERNAL); 44} 45 46AidlLocation loc(const yy::parser::location_type& l) { 47 return loc(l, l); 48} 49 50#define lex_scanner ps->Scanner() 51 52%} 53 54%initial-action { 55 @$.begin.filename = @$.end.filename = 56 const_cast<std::string *>(&ps->FileName()); 57} 58 59%parse-param { Parser* ps } 60%lex-param { void *lex_scanner } 61 62%glr-parser 63%skeleton "glr.cc" 64 65%expect-rr 0 66 67%define parse.error verbose 68%locations 69 70%union { 71 AidlToken* token; 72 char character; 73 std::string *str; 74 std::vector<std::unique_ptr<AidlToken>> *token_list; 75 AidlAnnotation* annotation; 76 AidlAnnotationParameter* param; 77 std::map<std::string, std::shared_ptr<AidlConstantValue>>* param_list; 78 std::vector<std::unique_ptr<AidlAnnotation>>* annotation_list; 79 AidlTypeSpecifier* type; 80 AidlArgument* arg; 81 AidlArgument::Direction direction; 82 AidlConstantValue* const_expr; 83 AidlEnumerator* enumerator; 84 std::vector<std::unique_ptr<AidlEnumerator>>* enumerators; 85 std::vector<std::unique_ptr<AidlConstantValue>>* constant_value_list; 86 std::vector<std::unique_ptr<AidlArgument>>* arg_list; 87 AidlVariableDeclaration* variable; 88 AidlMethod* method; 89 AidlMember* constant; 90 std::vector<std::unique_ptr<AidlMember>>* members; 91 AidlDefinedType* declaration; 92 std::vector<std::unique_ptr<AidlTypeSpecifier>>* type_args; 93 std::vector<std::string>* type_params; 94 std::vector<std::unique_ptr<AidlDefinedType>>* declarations; 95 AidlUnstructuredHeaders* unstructured_headers; 96} 97 98%destructor { } <direction> 99%destructor { delete ($$); } <*> 100 101%token<token> PACKAGE "package" 102%token<token> IMPORT "import" 103%token<token> ANNOTATION "annotation" 104%token<token> C_STR "string literal" 105%token<token> IDENTIFIER "identifier" 106%token<token> INTERFACE "interface" 107%token<token> PARCELABLE "parcelable" 108%token<token> ONEWAY "oneway" 109%token<token> ENUM "enum" 110%token<token> UNION "union" 111%token<token> CONST "const" 112 113%token<token> CHARVALUE "char literal" 114%token<token> FLOATVALUE "float literal" 115%token<token> HEXVALUE "hex literal" 116%token<token> INTVALUE "int literal" 117 118%token '(' ')' ',' '=' '[' ']' '.' '{' '}' ';' 119%token UNKNOWN "unrecognized character" 120%token<token> CPP_HEADER "cpp_header (which can also be used as an identifier)" 121%token<token> NDK_HEADER "ndk_header (which can also be used as an identifier)" 122%token<token> RUST_TYPE "rust_type (which can also be used as an identifier)" 123%token IN "in" 124%token INOUT "inout" 125%token OUT "out" 126%token TRUE_LITERAL "true" 127%token FALSE_LITERAL "false" 128 129/* Operator precedence and associativity, as per 130 * http://en.cppreference.com/w/cpp/language/operator_precedence */ 131/* Precedence level 13 - 14, LTR, logical operators*/ 132%left LOGICAL_OR 133%left LOGICAL_AND 134/* Precedence level 10 - 12, LTR, bitwise operators*/ 135%left '|' 136%left '^' 137%left '&' 138/* Precedence level 9, LTR */ 139%left EQUALITY NEQ 140/* Precedence level 8, LTR */ 141%left '<' '>' LEQ GEQ 142/* Precedence level 7, LTR */ 143%left LSHIFT RSHIFT 144/* Precedence level 6, LTR */ 145%left '+' '-' 146/* Precedence level 5, LTR */ 147%left '*' '/' '%' 148/* Precedence level 3, RTL; but we have to use %left here */ 149%right UNARY_PLUS UNARY_MINUS '!' '~' 150 151%type<declaration> decl 152%type<declaration> unannotated_decl 153%type<declaration> interface_decl 154%type<declaration> parcelable_decl 155%type<declaration> enum_decl 156%type<declaration> union_decl 157%type<members> parcelable_members interface_members 158%type<variable> variable_decl 159%type<type_params> optional_type_params 160%type<method> method_decl 161%type<constant> constant_decl 162%type<enumerator> enumerator 163%type<enumerators> enumerators enum_decl_body 164%type<param> parameter 165%type<param_list> parameter_list 166%type<param_list> parameter_non_empty_list 167%type<annotation> annotation 168%type<annotation_list>annotation_list 169%type<type> type 170%type<type> non_array_type 171%type<arg_list> arg_list arg_non_empty_list 172%type<arg> arg 173%type<direction> direction 174%type<type_args> type_args 175%type<type_params> type_params 176%type<const_expr> const_expr 177%type<constant_value_list> constant_value_list 178%type<constant_value_list> constant_value_non_empty_list 179%type<token_list> imports 180%type<declarations> decls 181%type<token> import identifier error qualified_name optional_package 182%type<unstructured_headers> optional_unstructured_headers 183 184%% 185 186document 187 : optional_package imports decls { 188 std::vector<std::string> imports; 189 for (const auto& import : *$2) { 190 imports.push_back(import->GetText()); 191 } 192 193 ps->MakeDocument(loc(@1), Comments(), std::move(imports), std::move(*$3)); 194 195 for (auto i = $2->rbegin(); i != $2->rend(); ++i) { 196 ps->GetDocument()->PrependComments((*i)->GetComments()); 197 } 198 if ($1) { 199 ps->GetDocument()->PrependComments($1->GetComments()); 200 } 201 202 delete $1; 203 delete $2; 204 delete $3; 205 } 206 ; 207 208/* A couple of tokens that are keywords elsewhere are identifiers when 209 * occurring in the identifier position. Therefore identifier is a 210 * non-terminal, which is either an IDENTIFIER token, or one of the 211 * aforementioned keyword tokens. 212 */ 213identifier 214 : IDENTIFIER 215 | CPP_HEADER 216 | NDK_HEADER 217 | RUST_TYPE 218 ; 219 220optional_package 221 : { 222 $$ = nullptr; 223 } 224 | PACKAGE qualified_name ';' { 225 ps->SetPackage($2->GetText()); 226 $$ = $1; // for comments 227 delete $2; 228 } 229 ; 230 231imports 232 : { $$ = new std::vector<std::unique_ptr<AidlToken>>(); } 233 | imports import 234 { 235 $$ = $1; 236 $$->emplace_back($2); 237 } 238 239import 240 : IMPORT qualified_name ';' { 241 // carry the comments before "import" token 242 $$ = new AidlToken($2->GetText(), $1->GetComments()); 243 delete $1; 244 delete $2; 245 }; 246 247qualified_name 248 : identifier { 249 $$ = $1; 250 } 251 | qualified_name '.' identifier 252 { $$ = $1; 253 $$->Append('.'); 254 $$->Append($3->GetText()); 255 delete $3; 256 }; 257 258decls 259 : decl 260 { $$ = new std::vector<std::unique_ptr<AidlDefinedType>>(); 261 if ($1 != nullptr) { 262 $$->emplace_back($1); 263 } 264 } 265 | decls decl 266 { $$ = $1; 267 if ($2 != nullptr) { 268 $$->emplace_back($2); 269 } 270 } 271 272decl 273 : annotation_list unannotated_decl 274 { 275 $$ = $2; 276 277 if ($$ != nullptr) { 278 $$->Annotate(std::move(*$1)); 279 } 280 281 delete $1; 282 } 283 ; 284 285unannotated_decl 286 : parcelable_decl 287 | interface_decl 288 | enum_decl 289 | union_decl 290 ; 291 292type_params 293 : identifier { 294 $$ = new std::vector<std::string>(); 295 $$->emplace_back($1->GetText()); 296 delete $1; 297 } 298 | type_params ',' identifier { 299 $1->emplace_back($3->GetText()); 300 $$ = $1; 301 delete $3; 302 }; 303 304optional_type_params 305 : /* none */ { $$ = nullptr; } 306 | '<' type_params '>' { 307 $$ = $2; 308 }; 309 310optional_unstructured_headers 311 : /* none */ { $$ = new AidlUnstructuredHeaders; } 312 | optional_unstructured_headers CPP_HEADER C_STR { 313 $$ = $1; 314 $$->cpp = $3->GetText(); 315 delete $2; 316 delete $3; 317 } 318 | optional_unstructured_headers NDK_HEADER C_STR { 319 $$ = $1; 320 $$->ndk = $3->GetText(); 321 delete $2; 322 delete $3; 323 } 324 | optional_unstructured_headers RUST_TYPE C_STR { 325 $$ = $1; 326 $$->rust_type = $3->GetText(); 327 delete $2; 328 delete $3; 329 } 330 ; 331 332parcelable_decl 333 : PARCELABLE qualified_name optional_type_params optional_unstructured_headers ';' { 334 // No check for type name here. We allow nested types for unstructured parcelables. 335 $$ = new AidlParcelable(loc(@2), $2->GetText(), ps->Package(), $1->GetComments(), *$4, $3); 336 delete $1; 337 delete $2; 338 delete $4; 339 } 340 | PARCELABLE qualified_name optional_type_params '{' parcelable_members '}' { 341 ps->CheckValidTypeName(*$2, loc(@2)); 342 $$ = new AidlStructuredParcelable(loc(@2), $2->GetText(), ps->Package(), $1->GetComments(), $3, $5); 343 delete $1; 344 delete $2; 345 } 346 | PARCELABLE error ';' { 347 ps->AddError(); 348 $$ = nullptr; 349 delete $1; 350 }; 351 352parcelable_members 353 : /* empty */ { 354 $$ = new std::vector<std::unique_ptr<AidlMember>>(); 355 } 356 | parcelable_members variable_decl { 357 $1->emplace_back($2); 358 $$ = $1; 359 } 360 | parcelable_members constant_decl { 361 $1->emplace_back($2); 362 $$ = $1; 363 } 364 | parcelable_members decl { 365 if ($2) $1->emplace_back($2); // decl may be nullptr on error 366 $$ = $1; 367 } 368 | parcelable_members error ';' { 369 ps->AddError(); 370 $$ = $1; 371 }; 372 373variable_decl 374 : type identifier ';' { 375 $$ = new AidlVariableDeclaration(loc(@2), $1, $2->GetText()); 376 delete $2; 377 } 378 | type identifier '=' const_expr ';' { 379 // TODO(b/123321528): Support enum type default assignments (TestEnum foo = TestEnum.FOO). 380 $$ = new AidlVariableDeclaration(loc(@2), $1, $2->GetText(), $4); 381 delete $2; 382 } 383 ; 384 385interface_decl 386 : INTERFACE qualified_name ';' { 387 ps->CheckValidTypeName(*$2, loc(@2)); 388 $$ = new AidlInterface(loc(@1), $2->GetText(), $1->GetComments(), false, ps->Package(), nullptr); 389 delete $1; 390 delete $2; 391 } 392 | INTERFACE qualified_name '{' interface_members '}' { 393 ps->CheckValidTypeName(*$2, loc(@2)); 394 $$ = new AidlInterface(loc(@1), $2->GetText(), $1->GetComments(), false, ps->Package(), $4); 395 delete $1; 396 delete $2; 397 } 398 | ONEWAY INTERFACE qualified_name '{' interface_members '}' { 399 ps->CheckValidTypeName(*$3, loc(@3)); 400 $$ = new AidlInterface(loc(@2), $3->GetText(), $1->GetComments(), true, ps->Package(), $5); 401 delete $1; 402 delete $2; 403 delete $3; 404 } 405 | INTERFACE error '{' interface_members '}' { 406 ps->AddError(); 407 $$ = nullptr; 408 delete $1; 409 delete $4; 410 }; 411 412interface_members 413 : 414 { $$ = new std::vector<std::unique_ptr<AidlMember>>(); } 415 | interface_members method_decl 416 { $1->push_back(std::unique_ptr<AidlMember>($2)); $$ = $1; } 417 | interface_members constant_decl 418 { $1->push_back(std::unique_ptr<AidlMember>($2)); $$ = $1; } 419 | interface_members decl 420 { 421 if ($2) $1->emplace_back($2); // decl may be nullptr on error 422 $$ = $1; 423 } 424 | interface_members error ';' { 425 ps->AddError(); 426 $$ = $1; 427 }; 428 429const_expr 430 : TRUE_LITERAL { $$ = AidlConstantValue::Boolean(loc(@1), true); } 431 | FALSE_LITERAL { $$ = AidlConstantValue::Boolean(loc(@1), false); } 432 | CHARVALUE { 433 $$ = AidlConstantValue::Character(loc(@1), $1->GetText()); 434 delete $1; 435 } 436 | INTVALUE { 437 $$ = AidlConstantValue::Integral(loc(@1), $1->GetText()); 438 if ($$ == nullptr) { 439 AIDL_ERROR(loc(@1)) << "Could not parse integer: " 440 << $1->GetText(); 441 ps->AddError(); 442 $$ = AidlConstantValue::Integral(loc(@1), "0"); 443 } 444 delete $1; 445 } 446 | FLOATVALUE { 447 $$ = AidlConstantValue::Floating(loc(@1), $1->GetText()); 448 delete $1; 449 } 450 | HEXVALUE { 451 $$ = AidlConstantValue::Integral(loc(@1), $1->GetText()); 452 if ($$ == nullptr) { 453 AIDL_ERROR(loc(@1)) << "Could not parse hexvalue: " 454 << $1->GetText(); 455 ps->AddError(); 456 $$ = AidlConstantValue::Integral(loc(@1), "0"); 457 } 458 delete $1; 459 } 460 | C_STR { 461 $$ = AidlConstantValue::String(loc(@1), $1->GetText()); 462 delete $1; 463 } 464 | qualified_name { 465 $$ = new AidlConstantReference(loc(@1), $1->GetText()); 466 delete $1; 467 } 468 | '{' constant_value_list '}' { 469 $$ = AidlConstantValue::Array(loc(@1), std::unique_ptr<vector<unique_ptr<AidlConstantValue>>>($2)); 470 } 471 | const_expr LOGICAL_OR const_expr { 472 $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), "||", std::unique_ptr<AidlConstantValue>($3)); 473 } 474 | const_expr LOGICAL_AND const_expr { 475 $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), "&&", std::unique_ptr<AidlConstantValue>($3)); 476 } 477 | const_expr '|' const_expr { 478 $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), "|" , std::unique_ptr<AidlConstantValue>($3)); 479 } 480 | const_expr '^' const_expr { 481 $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), "^" , std::unique_ptr<AidlConstantValue>($3)); 482 } 483 | const_expr '&' const_expr { 484 $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), "&" , std::unique_ptr<AidlConstantValue>($3)); 485 } 486 | const_expr EQUALITY const_expr { 487 $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), "==", std::unique_ptr<AidlConstantValue>($3)); 488 } 489 | const_expr NEQ const_expr { 490 $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), "!=", std::unique_ptr<AidlConstantValue>($3)); 491 } 492 | const_expr '<' const_expr { 493 $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), "<" , std::unique_ptr<AidlConstantValue>($3)); 494 } 495 | const_expr '>' const_expr { 496 $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), ">" , std::unique_ptr<AidlConstantValue>($3)); 497 } 498 | const_expr LEQ const_expr { 499 $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), "<=", std::unique_ptr<AidlConstantValue>($3)); 500 } 501 | const_expr GEQ const_expr { 502 $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), ">=", std::unique_ptr<AidlConstantValue>($3)); 503 } 504 | const_expr LSHIFT const_expr { 505 $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), "<<", std::unique_ptr<AidlConstantValue>($3)); 506 } 507 | const_expr RSHIFT const_expr { 508 $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), ">>", std::unique_ptr<AidlConstantValue>($3)); 509 } 510 | const_expr '+' const_expr { 511 $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), "+" , std::unique_ptr<AidlConstantValue>($3)); 512 } 513 | const_expr '-' const_expr { 514 $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), "-" , std::unique_ptr<AidlConstantValue>($3)); 515 } 516 | const_expr '*' const_expr { 517 $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), "*" , std::unique_ptr<AidlConstantValue>($3)); 518 } 519 | const_expr '/' const_expr { 520 $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), "/" , std::unique_ptr<AidlConstantValue>($3)); 521 } 522 | const_expr '%' const_expr { 523 $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), "%" , std::unique_ptr<AidlConstantValue>($3)); 524 } 525 | '+' const_expr %prec UNARY_PLUS { 526 $$ = new AidlUnaryConstExpression(loc(@1), "+", std::unique_ptr<AidlConstantValue>($2)); 527 } 528 | '-' const_expr %prec UNARY_MINUS { 529 $$ = new AidlUnaryConstExpression(loc(@1), "-", std::unique_ptr<AidlConstantValue>($2)); 530 } 531 | '!' const_expr { 532 $$ = new AidlUnaryConstExpression(loc(@1), "!", std::unique_ptr<AidlConstantValue>($2)); 533 } 534 | '~' const_expr { 535 $$ = new AidlUnaryConstExpression(loc(@1), "~", std::unique_ptr<AidlConstantValue>($2)); 536 } 537 | '(' const_expr ')' 538 { 539 $$ = $2; 540 } 541 | '(' error ')' 542 { 543 AIDL_ERROR(loc(@1)) << "invalid const expression within parenthesis"; 544 ps->AddError(); 545 // to avoid segfaults 546 $$ = AidlConstantValue::Integral(loc(@1), "0"); 547 } 548 ; 549 550constant_value_list 551 : /* empty */ { 552 $$ = new std::vector<std::unique_ptr<AidlConstantValue>>; 553 } 554 | constant_value_non_empty_list { 555 $$ = $1; 556 } 557 | constant_value_non_empty_list ',' { 558 $$ = $1; 559 } 560 ; 561 562constant_value_non_empty_list 563 : const_expr { 564 $$ = new std::vector<std::unique_ptr<AidlConstantValue>>; 565 $$->push_back(std::unique_ptr<AidlConstantValue>($1)); 566 } 567 | constant_value_non_empty_list ',' const_expr { 568 $$ = $1; 569 $$->push_back(std::unique_ptr<AidlConstantValue>($3)); 570 } 571 ; 572 573constant_decl 574 : annotation_list CONST type identifier '=' const_expr ';' { 575 $3->PrependComments($2->GetComments()); 576 // TODO(b/151102494) do not merge annotations. 577 $3->Annotate(std::move(*$1)); 578 $$ = new AidlConstantDeclaration(loc(@4), $3, $4->GetText(), $6); 579 delete $1; 580 delete $2; 581 delete $4; 582 } 583 ; 584 585enumerator 586 : identifier '=' const_expr { 587 $$ = new AidlEnumerator(loc(@1), $1->GetText(), $3, $1->GetComments()); 588 delete $1; 589 } 590 | identifier { 591 $$ = new AidlEnumerator(loc(@1), $1->GetText(), nullptr, $1->GetComments()); 592 delete $1; 593 } 594 ; 595 596enumerators 597 : enumerator { 598 $$ = new std::vector<std::unique_ptr<AidlEnumerator>>(); 599 $$->push_back(std::unique_ptr<AidlEnumerator>($1)); 600 } 601 | enumerators ',' enumerator { 602 $1->push_back(std::unique_ptr<AidlEnumerator>($3)); 603 $$ = $1; 604 } 605 ; 606 607enum_decl_body 608 : '{' enumerators '}' { $$ = $2; } 609 | '{' enumerators ',' '}' { $$ = $2; } 610 ; 611 612enum_decl 613 : ENUM qualified_name enum_decl_body { 614 ps->CheckValidTypeName(*$2, loc(@2)); 615 $$ = new AidlEnumDeclaration(loc(@2), $2->GetText(), $3, ps->Package(), $1->GetComments()); 616 delete $1; 617 delete $2; 618 delete $3; 619 } 620 ; 621 622union_decl 623 : UNION qualified_name optional_type_params '{' parcelable_members '}' { 624 ps->CheckValidTypeName(*$2, loc(@2)); 625 $$ = new AidlUnionDecl(loc(@2), $2->GetText(), ps->Package(), $1->GetComments(), $3, $5); 626 delete $1; 627 delete $2; 628 } 629 ; 630 631method_decl 632 : type identifier '(' arg_list ')' ';' { 633 $$ = new AidlMethod(loc(@2), false, $1, $2->GetText(), $4, $2->GetComments()); 634 $$->PrependComments($1->GetComments()); 635 delete $2; 636 } 637 | annotation_list ONEWAY type identifier '(' arg_list ')' ';' { 638 $$ = new AidlMethod(loc(@4), true, $3, $4->GetText(), $6, $4->GetComments()); 639 $3->PrependComments($2->GetComments()); 640 $3->Annotate(std::move(*$1)); 641 $$->PrependComments($3->GetComments()); 642 delete $1; 643 delete $2; 644 delete $4; 645 } 646 | type identifier '(' arg_list ')' '=' INTVALUE ';' { 647 int32_t serial = 0; 648 if (!android::base::ParseInt($7->GetText(), &serial)) { 649 AIDL_ERROR(loc(@7)) << "Could not parse int value: " << $7->GetText(); 650 ps->AddError(); 651 } 652 $$ = new AidlMethod(loc(@2), false, $1, $2->GetText(), $4, $2->GetComments(), serial); 653 $$->PrependComments($1->GetComments()); 654 delete $2; 655 delete $7; 656 } 657 | annotation_list ONEWAY type identifier '(' arg_list ')' '=' INTVALUE ';' { 658 int32_t serial = 0; 659 if (!android::base::ParseInt($9->GetText(), &serial)) { 660 AIDL_ERROR(loc(@9)) << "Could not parse int value: " << $9->GetText(); 661 ps->AddError(); 662 } 663 $$ = new AidlMethod(loc(@4), true, $3, $4->GetText(), $6, $4->GetComments(), serial); 664 $3->PrependComments($2->GetComments()); 665 $3->Annotate(std::move(*$1)); 666 $$->PrependComments($3->GetComments()); 667 delete $1; 668 delete $2; 669 delete $4; 670 delete $9; 671 }; 672 673arg_non_empty_list 674 : arg { 675 $$ = new std::vector<std::unique_ptr<AidlArgument>>(); 676 $$->push_back(std::unique_ptr<AidlArgument>($1)); 677 } 678 | arg_non_empty_list ',' arg { 679 $$ = $1; 680 $$->push_back(std::unique_ptr<AidlArgument>($3)); 681 }; 682 683arg_list 684 : /*empty*/ 685 { $$ = new std::vector<std::unique_ptr<AidlArgument>>(); } 686 | arg_non_empty_list { $$ = $1; } 687 ; 688 689arg 690 : direction type identifier { 691 $$ = new AidlArgument(loc(@3), $1, $2, $3->GetText()); 692 delete $3; 693 } 694 | type identifier { 695 $$ = new AidlArgument(loc(@2), $1, $2->GetText()); 696 delete $2; 697 }; 698 699non_array_type 700 : annotation_list qualified_name { 701 $$ = new AidlTypeSpecifier(loc(@2), $2->GetText(), /*array=*/std::nullopt, nullptr, $2->GetComments()); 702 $$->Annotate(std::move(*$1)); 703 delete $1; 704 delete $2; 705 } 706 | non_array_type '<' type_args '>' { 707 ps->SetTypeParameters($1, $3); 708 $$ = $1; 709 } 710 | non_array_type '<' non_array_type '<' type_args RSHIFT { 711 ps->SetTypeParameters($3, $5); 712 auto params = new std::vector<std::unique_ptr<AidlTypeSpecifier>>(); 713 params->emplace_back($3); 714 ps->SetTypeParameters($1, params); 715 $$ = $1; 716 } 717 | non_array_type '<' type_args ',' non_array_type '<' type_args RSHIFT { 718 ps->SetTypeParameters($5, $7); 719 $3->emplace_back($5); 720 ps->SetTypeParameters($1, $3); 721 $$ = $1; 722 }; 723 724type 725 : non_array_type 726 | type annotation_list '[' ']' { 727 if (!$2->empty()) { 728 AIDL_ERROR(loc(@2)) << "Annotations for arrays are not supported."; 729 ps->AddError(); 730 } 731 if (!$1->MakeArray(DynamicArray{})) { 732 AIDL_ERROR(loc(@1)) << "Multi-dimensional arrays must be fixed size."; 733 ps->AddError(); 734 } 735 $$ = $1; 736 delete $2; 737 } 738 | type annotation_list '[' const_expr ']' { 739 if (!$2->empty()) { 740 AIDL_ERROR(loc(@2)) << "Annotations for arrays are not supported."; 741 ps->AddError(); 742 } 743 if (!$1->MakeArray(FixedSizeArray{std::unique_ptr<AidlConstantValue>($4)})) { 744 AIDL_ERROR(loc(@1)) << "Multi-dimensional arrays must be fixed size."; 745 ps->AddError(); 746 } 747 $$ = $1; 748 delete $2; 749 } 750 ; 751 752type_args 753 : type { 754 if (!$1->GetAnnotations().empty()) { 755 AIDL_ERROR(loc(@1)) << "Annotations for type arguments are not supported."; 756 ps->AddError(); 757 } 758 $$ = new std::vector<std::unique_ptr<AidlTypeSpecifier>>(); 759 $$->emplace_back($1); 760 } 761 | type_args ',' type { 762 $1->emplace_back($3); 763 $$ = $1; 764 }; 765 766annotation_list 767 : 768 { $$ = new std::vector<std::unique_ptr<AidlAnnotation>>(); } 769 | annotation_list annotation 770 { 771 if ($2 != nullptr) { 772 $1->emplace_back(std::unique_ptr<AidlAnnotation>($2)); 773 } 774 $$ = $1; 775 }; 776 777parameter 778 : identifier '=' const_expr { 779 $$ = new AidlAnnotationParameter{$1->GetText(), std::unique_ptr<AidlConstantValue>($3)}; 780 delete $1; 781 }; 782 783parameter_list 784 : /*empty*/{ 785 $$ = new std::map<std::string, std::shared_ptr<AidlConstantValue>>(); 786 } 787 | parameter_non_empty_list { 788 $$ = $1; 789 }; 790 791parameter_non_empty_list 792 : parameter { 793 $$ = new std::map<std::string, std::shared_ptr<AidlConstantValue>>(); 794 $$->emplace(std::move($1->name), $1->value.release()); 795 delete $1; 796 } 797 | parameter_non_empty_list ',' parameter { 798 $$ = $1; 799 if ($$->find($3->name) != $$->end()) { 800 AIDL_ERROR(loc(@3)) << "Trying to redefine parameter " << $3->name << "."; 801 ps->AddError(); 802 } 803 $$->emplace(std::move($3->name), std::move($3->value)); 804 delete $3; 805 }; 806 807annotation 808 : ANNOTATION { 809 // release() returns nullptr if unique_ptr is empty. 810 $$ = AidlAnnotation::Parse(loc(@1), $1->GetText(), {}, $1->GetComments()).release(); 811 if (!$$) { 812 ps->AddError(); 813 } 814 delete $1; 815 } 816 | ANNOTATION '(' const_expr ')' { 817 auto value = std::shared_ptr<AidlConstantValue>($3); 818 std::map<std::string, std::shared_ptr<AidlConstantValue>> parameter_list {{"value" , value}}; 819 $$ = AidlAnnotation::Parse(loc(@1, @4), $1->GetText(), std::move(parameter_list), $1->GetComments()).release(); 820 if (!$$) { 821 ps->AddError(); 822 } 823 delete $1; 824 } 825 | ANNOTATION '(' parameter_list ')' { 826 // release() returns nullptr if unique_ptr is empty. 827 $$ = AidlAnnotation::Parse(loc(@1, @4), $1->GetText(), std::move(*$3), $1->GetComments()).release(); 828 if (!$$) { 829 ps->AddError(); 830 } 831 delete $1; 832 delete $3; 833 } 834 ; 835 836direction 837 : IN 838 { $$ = AidlArgument::IN_DIR; } 839 | OUT 840 { $$ = AidlArgument::OUT_DIR; } 841 | INOUT 842 { $$ = AidlArgument::INOUT_DIR; }; 843 844%% 845 846#include <ctype.h> 847#include <stdio.h> 848 849void yy::parser::error(const yy::parser::location_type& l, const std::string& errstr) { 850 AIDL_ERROR(loc(l)) << errstr; 851 // parser will return error value 852} 853