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 "AST.h" 20#include "Declaration.h" 21#include "Type.h" 22#include "VarDeclaration.h" 23#include "FunctionDeclaration.h" 24#include "CompositeDeclaration.h" 25#include "Define.h" 26#include "Include.h" 27#include "EnumVarDeclaration.h" 28#include "Note.h" 29#include "TypeDef.h" 30#include "Expression.h" 31 32#include "c2hal_y.h" 33 34#include <stdio.h> 35#include <algorithm> 36 37using namespace android; 38 39extern int yylex(YYSTYPE *yylval_param, YYLTYPE *llocp, void *); 40 41int yyerror(YYLTYPE *llocp, AST *, const char *s) { 42 extern bool should_report_errors; 43 44 if (!should_report_errors) { 45 return 0; 46 } 47 48 fflush(stdout); 49 LOG(ERROR) << " " 50 << s 51 << " near line " 52 << llocp->first_line; 53 54 return 0; 55} 56 57#define scanner ast->scanner() 58 59std::string get_last_comment() { 60 extern std::string last_comment; 61 62 std::string ret{last_comment}; 63 64 // clear the last comment now that it's been taken 65 last_comment = ""; 66 67 return ret; 68} 69 70%} 71 72%parse-param { android::AST *ast } 73%lex-param { void *scanner } 74%locations 75%define api.pure 76%glr-parser 77 78/* These have to do with the fact that 79 * struct_or_union_declaration and enum_declaration 80 * both start with STRUCT/UNION/ENUM opt_id 81 * and type_qualifiers contain these. 82 */ 83%expect 3 84 85%token START_HEADER 86%token START_EXPR 87 88%token STRUCT 89%token UNION 90%token ENUM 91%token CLASS 92%token CONST 93%token VOID 94%token INCLUDE 95%token DEFINE 96%token TYPEDEF 97%token UNSIGNED 98%token SIGNED 99%token LSHIFT 100%token RSHIFT 101%token VARARGS 102%token NAMESPACE 103%token EXTERN 104%token C_STRING 105 106%left ',' 107%right '?' ':' 108%left '|' 109%left '^' 110%left '&' 111%left RSHIFT LSHIFT 112%left '+' '-' 113%left '*' '/' '%' 114%right '~' '!' UMINUS UPLUS 115%left ARRAY_SUBSCRIPT FUNCTION_CALL 116 117%right STRUCT ENUM 118 119%token<str> ID 120%token<str> COMMENT 121%token<str> VALUE 122%token<str> INTEGRAL_VALUE 123%token<str> INCLUDE_FILE 124%token<str> FUNCTION 125%token<str> DEFINE_SLURP 126%token<str> OTHER_STATEMENT 127 128%type<expression> array 129%type<expressions> arrays 130%type<expression> expr 131%type<expressions> args 132%type<type> type 133%type<type> opt_enum_base_type 134%type<qualifier> type_qualifier 135%type<qualifiers> type_qualifiers 136%type<declaration> declaration 137%type<declarations> declarations 138%type<composite> struct_or_union_declaration 139%type<composite> enum_declaration 140%type<param> param 141%type<params> params 142%type<qualification> struct_or_union 143%type<str> opt_id 144%type<include> include 145%type<enum_var> enum_var 146%type<declarations> enum_vars enum_vars_all_but_last 147%type<declaration> enum_var_line enum_var_last_line 148 149%start parse_selector 150 151%union { 152 const char *str; 153 int count; 154 android::Declaration *declaration; 155 android::CompositeDeclaration *composite; 156 std::vector<android::Declaration *> *declarations; 157 android::EnumVarDeclaration *enum_var; 158 android::Declaration *param; 159 std::vector<android::Declaration *> *params; 160 android::Type *type; 161 android::Type::Qualifier *qualifier; 162 android::Type::Qualifier::Qualification qualification; 163 std::vector<android::Type::Qualifier*> *qualifiers; 164 android::Include *include; 165 std::vector<android::Include *> *includes; 166 android::Expression *expression; 167 std::vector<android::Expression *> *expressions; 168} 169 170%% 171 172parse_selector 173 : START_HEADER header 174 | START_EXPR expr_parser 175 ; 176 177expr_parser 178 : expr 179 { 180 ast->setExpression($1); 181 } 182 ; 183 184header 185 : declarations /* well, we are a header file */ 186 { 187 ast->setDeclarations($1); 188 } 189 ; 190 191declarations 192 : /* EMPTY */ 193 { 194 $$ = new std::vector<Declaration *>; 195 } 196 | declarations declaration 197 { 198 $$ = $1; 199 $$->push_back($2); 200 } 201 | declarations EXTERN C_STRING '{' declarations '}' 202 { 203 $1->push_back(new Note("extern \"C\" { ")); 204 $1->insert($1->end(), $5->begin(), $5->end()); 205 $1->push_back(new Note("} // end of extern C")); 206 delete $5; 207 208 $$ = $1; 209 } 210 ; 211 212declaration 213 : param ';' 214 { 215 $$ = $1; 216 $$->setComment(get_last_comment()); 217 } 218 | struct_or_union_declaration ';' 219 { 220 $$ = $1; 221 } 222 | enum_declaration ';' 223 { 224 $$ = $1; 225 } 226 | TYPEDEF struct_or_union_declaration ';' 227 { 228 // ignore that it is a typedef, for our purposes it doesn't matter 229 $$ = $2; 230 } 231 | TYPEDEF enum_declaration ';' 232 { 233 // ignore that it is a typedef, for our purposes it doesn't matter 234 $$ = $2; 235 } 236 | TYPEDEF param ';' /* looks like 'typedef const int8_t store;' */ 237 { 238 $$ = new TypeDef($2->getName(), $2); 239 $$->setComment(get_last_comment()); 240 } 241 | DEFINE ID DEFINE_SLURP 242 { 243 $$ = new Define($2, $3); 244 $$->setComment(get_last_comment()); 245 } 246 | OTHER_STATEMENT 247 { 248 $$ = new Note($1); 249 $$->setComment(get_last_comment()); 250 } 251 | FUNCTION 252 { 253 $$ = new Note($1); 254 $$->setComment(get_last_comment()); 255 } 256 | type ID '=' expr ';' 257 { 258 $$ = new Note($1->decorateName($2) + " = " + $4->toString()); 259 } 260 | include 261 { 262 $$ = $1; 263 $$->setComment(get_last_comment()); 264 } 265 | NAMESPACE ID '{' declarations '}' 266 { 267 $$ = new CompositeDeclaration(Type::Qualifier::STRUCT, 268 $2, 269 $4); 270 271 get_last_comment(); // clear it 272 $$->setComment("/* from namespace declaration */"); 273 } 274 ; 275 276include 277 : INCLUDE '<' INCLUDE_FILE '>' 278 { 279 $$ = new Include($3, true /* isLibrary */); 280 } 281 | INCLUDE '"' INCLUDE_FILE '"' 282 { 283 $$ = new Include($3, false /* isLibrary */); 284 } 285 ; 286 287struct_or_union_declaration 288 : struct_or_union opt_id 289 { 290 $<str>$ = strdup(get_last_comment().c_str()); 291 } 292 '{' declarations '}' opt_id 293 { 294 $$ = new CompositeDeclaration($1, $2, $5); 295 $$->setComment($<str>3); 296 297 if(!std::string($7).empty()) { 298 $$->setName($7); 299 } 300 } 301 ; 302 303opt_comma 304 : /* EMPTY */ 305 | ',' 306 ; 307 308enum_key 309 : ENUM 310 | ENUM CLASS /* c++11 */ 311 | ENUM STRUCT /* c++11 */ 312 ; 313 314opt_enum_base_type 315 : /* EMPTY */ { $$ = NULL; } 316 | ':' type { $$ = $2; } 317 ; 318 319enum_declaration 320 : enum_key opt_id 321 { 322 $<str>$ = strdup(get_last_comment().c_str()); 323 } 324 opt_enum_base_type '{' enum_vars '}' opt_id 325 { 326 $$ = new CompositeDeclaration(Type::Qualifier::ENUM, $2, $6); 327 $$->setComment($<str>3); 328 329 if($4) { 330 $$->setEnumTypeName($4->decorateName("")); 331 delete $4; 332 } 333 334 if(!std::string($8).empty()) { 335 $$->setName($8); 336 } 337 } 338 ; 339 340enum_vars 341 : /* EMPTY */ 342 { 343 $$ = new std::vector<Declaration *>; 344 } 345 | enum_vars_all_but_last enum_var_last_line 346 { 347 $$ = $1; 348 $$->push_back($2); 349 } 350 351enum_vars_all_but_last 352 : /* EMPTY */ 353 { 354 $$ = new std::vector<Declaration *>; 355 } 356 | enum_vars_all_but_last enum_var_line 357 { 358 $$ = $1; 359 $$->push_back($2); 360 } 361 ; 362 363enum_var_last_line 364 : enum_var opt_comma { $$ = $1; } 365 | OTHER_STATEMENT 366 { 367 $$ = new Note($1); 368 $$->setComment(get_last_comment()); 369 } 370 ; 371 372enum_var_line 373 : enum_var ',' { $$ = $1; } 374 | OTHER_STATEMENT 375 { 376 $$ = new Note($1); 377 $$->setComment(get_last_comment()); 378 } 379 ; 380 381enum_var 382 : ID 383 { 384 $$ = new EnumVarDeclaration($1, NULL); 385 $$->setComment(get_last_comment()); 386 } 387 | ID '=' expr 388 { 389 $$ = new EnumVarDeclaration($1, $3); 390 $$->setComment(get_last_comment()); 391 } 392 ; 393 394params 395 : /* EMPTY */ 396 { 397 $$ = new std::vector<Declaration *>; 398 } 399 | param 400 { 401 $$ = new std::vector<Declaration *>; 402 $$->push_back($1); 403 } 404 | params ',' param 405 { 406 $$ = $1; 407 $$->push_back($3); 408 } 409 ; 410 411param 412 : type arrays 413 { 414 $1->setArrays($2); 415 416 // allow for either "const int myvar" or "const int" 417 // as a parameter declaration 418 std::string lastId = $1->removeLastId(); 419 420 $$ = new VarDeclaration($1, lastId); 421 } 422 | type '(' '*' ID arrays ')' '(' params ')' 423 { 424 $1->setArrays($5); 425 $$ = new FunctionDeclaration($1, $4, $8); 426 } 427 | type ID '(' params ')' 428 { 429 $$ = new FunctionDeclaration($1, $2, $4); 430 } 431 | type '(' ID ')' '(' params ')' 432 { 433 $$ = new FunctionDeclaration($1, $3, $6); 434 } 435 | VARARGS 436 { 437 $$ = new VarDeclaration(new Type(NULL), "..."); 438 } 439 ; 440 441type 442 : type_qualifiers 443 { 444 $$ = new Type($1); 445 } 446 ; 447 448type_qualifiers 449 : type_qualifier 450 { 451 $$ = new std::vector<Type::Qualifier *>; 452 $$->push_back($1); 453 } 454 | type_qualifiers type_qualifier 455 { 456 $$ = $1; 457 $$->push_back($2); 458 } 459 ; 460 461opt_id 462 : /* EMPTY */ { $$ = ""; } 463 | 464 ID { $$ = $1; } 465 ; 466 467expr 468 : ID 469 { 470 $$ = Expression::atom(Expression::Type::UNKNOWN, $1, true /* isId*/ ); 471 } 472 | VALUE { $$ = Expression::atom(Expression::Type::UNKNOWN, $1); } 473 | INTEGRAL_VALUE { $$ = Expression::atom(Expression::integralType($1), $1); } 474 | '(' expr ')' { $$ = Expression::parenthesize($2); } 475 | ID '[' expr ']' %prec ARRAY_SUBSCRIPT { 476 $$ = Expression::arraySubscript($1, $3); 477 } 478 | ID '(' args ')' %prec FUNCTION_CALL { 479 $$ = Expression::functionCall($1, $3); 480 } 481 | expr '?' expr ':' expr { $$ = Expression::ternary($1, $3, $5); } 482 | expr '+' expr { $$ = Expression::binary($1, "+", $3); } 483 | expr '-' expr { $$ = Expression::binary($1, "-", $3); } 484 | expr '/' expr { $$ = Expression::binary($1, "/", $3); } 485 | expr '*' expr { $$ = Expression::binary($1, "*", $3); } 486 | expr '%' expr { $$ = Expression::binary($1, "%%", $3); } 487 | expr '&' expr { $$ = Expression::binary($1, "&", $3); } 488 | expr '|' expr { $$ = Expression::binary($1, "|", $3); } 489 | expr '^' expr { $$ = Expression::binary($1, "^", $3); } 490 | expr LSHIFT expr { $$ = Expression::binary($1, "<<", $3); } 491 | expr RSHIFT expr { $$ = Expression::binary($1, ">>", $3); } 492 | '~' expr { $$ = Expression::unary("~", $2); } 493 | '-' expr %prec UMINUS { $$ = Expression::unary("-", $2); } 494 | '+' expr %prec UPLUS { $$ = Expression::unary("+", $2); } 495 ; 496 497args 498 : /* empty */ 499 { 500 $$ = new std::vector<Expression *>; 501 } 502 | expr 503 { 504 $$ = new std::vector<Expression *>; 505 $$->push_back($1); 506 } 507 | args ',' expr 508 { 509 $$ = $1; 510 $$->push_back($3); 511 } 512 ; 513 514type_qualifier 515 : UNSIGNED { $$ = new Type::Qualifier(Type::Qualifier::UNSIGNED); } 516 | SIGNED { $$ = new Type::Qualifier(Type::Qualifier::SIGNED); } 517 | VOID { $$ = new Type::Qualifier(Type::Qualifier::VOID); } 518 | '*' { $$ = new Type::Qualifier(Type::Qualifier::POINTER); } 519 | CONST { $$ = new Type::Qualifier(Type::Qualifier::CONST); } 520 | ID { $$ = new Type::Qualifier(Type::Qualifier::ID, $1); } 521 | '<' type '>' { $$ = new Type::Qualifier(Type::Qualifier::GENERICS, $2); } 522 | enum_key { $$ = new Type::Qualifier(Type::Qualifier::ENUM); } 523 | struct_or_union { $$ = new Type::Qualifier($1); } 524 ; 525 526struct_or_union 527 : STRUCT { $$ = android::Type::Qualifier::STRUCT; } 528 | UNION { $$ = android::Type::Qualifier::UNION; } 529 ; 530 531arrays 532 : /* empty */ { $$ = new std::vector<Expression *>; } 533 | arrays array { 534 $$ = $1; 535 $$->push_back($2); 536 } 537 ; 538 539array 540 : '[' ']' { $$ = Expression::atom(Expression::Type::UNKNOWN, " "); } 541 | '[' expr ']' { $$ = $2; } 542 ; 543 544%% 545