blob: 3e1fb981f20432907e3ce96aa7e69ee86f8627dd [file] [log] [blame]
Andreas Huber1aec3972016-08-26 09:26:32 -07001/*
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
Andreas Huberc9410c72016-07-28 12:18:40 -070017%{
18
Andreas Huber3599d922016-08-09 10:42:57 -070019#include "Annotation.h"
Andreas Huberc9410c72016-07-28 12:18:40 -070020#include "AST.h"
21#include "ArrayType.h"
22#include "CompoundType.h"
Yifan Hong52165692016-08-12 18:06:40 -070023#include "ConstantExpression.h"
Andreas Huberc9410c72016-07-28 12:18:40 -070024#include "EnumType.h"
Yifan Hongf24fa852016-09-23 11:03:15 -070025#include "FQName.h"
Andreas Huber295ad302016-08-16 11:35:00 -070026#include "GenericBinder.h"
Andreas Huberc9410c72016-07-28 12:18:40 -070027#include "Interface.h"
28#include "Method.h"
Andreas Huberc9410c72016-07-28 12:18:40 -070029#include "VectorType.h"
Yifan Hongbf459bc2016-08-23 16:50:37 -070030#include "RefType.h"
Andreas Huberc9410c72016-07-28 12:18:40 -070031
32#include "hidl-gen_y.h"
33
Andreas Huber709b62d2016-09-19 11:21:18 -070034#include <android-base/logging.h>
Andreas Huberc9410c72016-07-28 12:18:40 -070035#include <stdio.h>
36
37using namespace android;
38
Andreas Huber0d0f9a22016-08-17 10:26:11 -070039extern int yylex(yy::parser::semantic_type *, yy::parser::location_type *, void *);
Andreas Huberc9410c72016-07-28 12:18:40 -070040
41#define scanner ast->scanner()
42
43%}
44
Andreas Huber0d0f9a22016-08-17 10:26:11 -070045%initial-action {
46 // Initialize the initial location.
47 @$.begin.filename = @$.end.filename =
48 const_cast<std::string *>(&ast->getFilename());
49}
50
Andreas Huberc9410c72016-07-28 12:18:40 -070051%parse-param { android::AST *ast }
52%lex-param { void *scanner }
53%pure-parser
Steven Moreland4ab9b792016-09-26 14:14:07 -070054%glr-parser
Andreas Huber0d0f9a22016-08-17 10:26:11 -070055%skeleton "glr.cc"
Andreas Huberc9410c72016-07-28 12:18:40 -070056
Steven Moreland4ab9b792016-09-26 14:14:07 -070057%expect-rr 0
58
Andreas Huberc9410c72016-07-28 12:18:40 -070059%token<str> ENUM
60%token<str> EXTENDS
Andreas Huber84f89de2016-07-28 15:39:51 -070061%token<str> FQNAME
Andreas Huberc9410c72016-07-28 12:18:40 -070062%token<str> GENERATES
63%token<str> IDENTIFIER
64%token<str> IMPORT
65%token<str> INTEGER
Yifan Hong52165692016-08-12 18:06:40 -070066%token<str> FLOAT
Andreas Huberc9410c72016-07-28 12:18:40 -070067%token<str> INTERFACE
68%token<str> PACKAGE
Andreas Huber84f89de2016-07-28 15:39:51 -070069%token<type> SCALAR
Andreas Huberc9410c72016-07-28 12:18:40 -070070%token<str> STRUCT
71%token<str> STRING_LITERAL
72%token<str> TYPEDEF
73%token<str> UNION
Yifan Hongbf459bc2016-08-23 16:50:37 -070074%token<templatedType> TEMPLATED
Iliyan Malchev639bff82016-08-13 14:24:11 -070075%token<void> ONEWAY
Andreas Huberc9410c72016-07-28 12:18:40 -070076
Yifan Hong52165692016-08-12 18:06:40 -070077/* Operator precedence and associativity, as per
78 * http://en.cppreference.com/w/cpp/language/operator_precedence */
79/* Precedence level 15 ternary operator */
80%right '?' ':'
81/* Precedence level 13 - 14, LTR, logical operators*/
82%left LOGICAL_OR
83%left LOGICAL_AND
84/* Precedence level 10 - 12, LTR, bitwise operators*/
85%left '|'
86%left '^'
87%left '&'
88/* Precedence level 9, LTR */
89%left EQUALITY NEQ
90/* Precedence level 8, LTR */
91%left '<' '>' LEQ GEQ
92/* Precedence level 7, LTR */
93%left LSHIFT RSHIFT
94/* Precedence level 6, LTR */
95%left '+' '-'
96/* Precedence level 5, LTR */
97%left '*' '/' '%'
98/* Precedence level 3, RTL; but we have to use %left here */
99%left UNARY_MINUS UNARY_PLUS '!' '~'
100
Yifan Hong6a2fedf2016-10-11 13:44:07 -0700101%type<str> package
Yifan Hongae16eed2016-09-23 13:25:25 -0700102%type<fqName> fqname
103%type<type> fqtype
Andreas Huberc9410c72016-07-28 12:18:40 -0700104
105%type<type> type opt_storage_type
Andreas Huberc9410c72016-07-28 12:18:40 -0700106%type<type> opt_extends
Andreas Huber7c5ddfb2016-09-29 13:45:22 -0700107%type<type> type_declaration_body interface_declaration typedef_declaration
108%type<type> named_struct_or_union_declaration named_enum_declaration
109%type<type> compound_declaration annotated_compound_declaration
Andreas Huberc9410c72016-07-28 12:18:40 -0700110
111%type<field> field_declaration
112%type<fields> field_declarations struct_or_union_body
Yifan Hong52165692016-08-12 18:06:40 -0700113%type<constantExpression> const_expr
Andreas Huberc9410c72016-07-28 12:18:40 -0700114%type<enumValue> enum_value
Yifan Hongf24fa852016-09-23 11:03:15 -0700115%type<enumValues> enum_values enum_declaration_body
Andreas Huberc9410c72016-07-28 12:18:40 -0700116%type<typedVars> typed_vars
117%type<typedVar> typed_var
118%type<method> method_declaration
119%type<compoundStyle> struct_or_union_keyword
Yifan Hongf24fa852016-09-23 11:03:15 -0700120%type<stringVec> annotation_string_values annotation_string_value
121%type<constExprVec> annotation_const_expr_values annotation_const_expr_value
Andreas Huber3599d922016-08-09 10:42:57 -0700122%type<annotationParam> annotation_param
123%type<annotationParams> opt_annotation_params annotation_params
124%type<annotation> annotation
125%type<annotations> opt_annotations
Andreas Huberc9410c72016-07-28 12:18:40 -0700126
127%start program
128
129%union {
130 const char *str;
131 android::Type *type;
Yifan Hongbf459bc2016-08-23 16:50:37 -0700132 android::TemplatedType *templatedType;
Yifan Hongae16eed2016-09-23 13:25:25 -0700133 android::FQName *fqName;
Andreas Huberc9410c72016-07-28 12:18:40 -0700134 android::CompoundType *compoundType;
135 android::CompoundField *field;
Andreas Huber881227d2016-08-02 14:20:21 -0700136 std::vector<android::CompoundField *> *fields;
Andreas Huberc9410c72016-07-28 12:18:40 -0700137 android::EnumValue *enumValue;
Yifan Hong52165692016-08-12 18:06:40 -0700138 android::ConstantExpression *constantExpression;
Andreas Huber881227d2016-08-02 14:20:21 -0700139 std::vector<android::EnumValue *> *enumValues;
Andreas Huberc9410c72016-07-28 12:18:40 -0700140 android::TypedVar *typedVar;
Andreas Huber881227d2016-08-02 14:20:21 -0700141 std::vector<android::TypedVar *> *typedVars;
Andreas Huberc9410c72016-07-28 12:18:40 -0700142 android::Method *method;
143 android::CompoundType::Style compoundStyle;
Andreas Huber3599d922016-08-09 10:42:57 -0700144 std::vector<std::string> *stringVec;
Yifan Hongf24fa852016-09-23 11:03:15 -0700145 std::vector<android::ConstantExpression *> *constExprVec;
Steven Morelandd537ab02016-09-12 10:32:01 -0700146 android::AnnotationParam *annotationParam;
147 android::AnnotationParamVector *annotationParams;
Andreas Huber3599d922016-08-09 10:42:57 -0700148 android::Annotation *annotation;
Steven Morelandd537ab02016-09-12 10:32:01 -0700149 std::vector<android::Annotation *> *annotations;
Andreas Huberc9410c72016-07-28 12:18:40 -0700150}
151
152%%
153
Andreas Huber3599d922016-08-09 10:42:57 -0700154opt_annotations
155 : /* empty */
156 {
Steven Morelandd537ab02016-09-12 10:32:01 -0700157 $$ = new std::vector<Annotation *>;
Andreas Huber3599d922016-08-09 10:42:57 -0700158 }
159 | opt_annotations annotation
160 {
161 $$ = $1;
Steven Morelandd537ab02016-09-12 10:32:01 -0700162 $$->push_back($2);
Andreas Huber3599d922016-08-09 10:42:57 -0700163 }
164 ;
165
166annotation
167 : '@' IDENTIFIER opt_annotation_params
168 {
169 $$ = new Annotation($2, $3);
170 }
171 ;
172
173opt_annotation_params
174 : /* empty */
175 {
Steven Morelandd537ab02016-09-12 10:32:01 -0700176 $$ = new AnnotationParamVector;
Andreas Huber3599d922016-08-09 10:42:57 -0700177 }
178 | '(' annotation_params ')'
179 {
180 $$ = $2;
181 }
182 ;
183
184annotation_params
185 : annotation_param
186 {
Steven Morelandd537ab02016-09-12 10:32:01 -0700187 $$ = new AnnotationParamVector;
188 $$->push_back($1);
Andreas Huber3599d922016-08-09 10:42:57 -0700189 }
190 | annotation_params ',' annotation_param
191 {
192 $$ = $1;
Steven Morelandd537ab02016-09-12 10:32:01 -0700193 $$->push_back($3);
Andreas Huber3599d922016-08-09 10:42:57 -0700194 }
195 ;
196
197annotation_param
Yifan Hongf24fa852016-09-23 11:03:15 -0700198 : IDENTIFIER '=' annotation_string_value
199 {
200 $$ = new AnnotationParam($1, $3);
201 }
202 | IDENTIFIER '=' annotation_const_expr_value
Andreas Huber3599d922016-08-09 10:42:57 -0700203 {
Steven Morelandd537ab02016-09-12 10:32:01 -0700204 $$ = new AnnotationParam($1, $3);
Andreas Huber3599d922016-08-09 10:42:57 -0700205 }
206 ;
207
Yifan Hongf24fa852016-09-23 11:03:15 -0700208annotation_string_value
Andreas Huber3599d922016-08-09 10:42:57 -0700209 : STRING_LITERAL
210 {
211 $$ = new std::vector<std::string>;
212 $$->push_back($1);
213 }
214 | '{' annotation_string_values '}' { $$ = $2; }
215 ;
216
217annotation_string_values
218 : STRING_LITERAL
219 {
220 $$ = new std::vector<std::string>;
221 $$->push_back($1);
222 }
223 | annotation_string_values ',' STRING_LITERAL
224 {
225 $$ = $1;
226 $$->push_back($3);
227 }
228 ;
229
Yifan Hongf24fa852016-09-23 11:03:15 -0700230annotation_const_expr_value
231 : const_expr
232 {
233 $$ = new std::vector<ConstantExpression *>;
234 $$->push_back($1);
235 }
236 | '{' annotation_const_expr_values '}' { $$ = $2; }
237 ;
238
239annotation_const_expr_values
240 : const_expr
241 {
242 $$ = new std::vector<ConstantExpression *>;
243 $$->push_back($1);
244 }
245 | annotation_const_expr_values ',' const_expr
246 {
247 $$ = $1;
248 $$->push_back($3);
249 }
250 ;
251
Andreas Huberc9410c72016-07-28 12:18:40 -0700252program
Andreas Huberda51b8e2016-07-28 16:00:57 -0700253 : package imports body
Andreas Huber84f89de2016-07-28 15:39:51 -0700254 ;
255
256fqname
257 : FQNAME
258 {
Yifan Hongae16eed2016-09-23 13:25:25 -0700259 $$ = new FQName($1);
260 if(!$$->isValid()) {
261 std::cerr << "ERROR: FQName '" << $1 << "' is not valid at "
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700262 << @1
Yifan Hongae16eed2016-09-23 13:25:25 -0700263 << ".\n";
Andreas Huber84f89de2016-07-28 15:39:51 -0700264 YYERROR;
265 }
266 }
267 | IDENTIFIER
268 {
Yifan Hongae16eed2016-09-23 13:25:25 -0700269 $$ = new FQName($1);
270 if(!$$->isValid()) {
271 std::cerr << "ERROR: FQName '" << $1 << "' is not valid at "
272 << @1
273 << ".\n";
274 YYERROR;
275 }
276 }
277 ;
278
279fqtype
280 : fqname
281 {
282 $$ = ast->lookupType(*($1));
Andreas Huber84f89de2016-07-28 15:39:51 -0700283 if ($$ == NULL) {
Yifan Hongae16eed2016-09-23 13:25:25 -0700284 std::cerr << "ERROR: Failed to lookup type '" << $1->string() << "' at "
285 << @1
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700286 << "\n";
287
Andreas Huber84f89de2016-07-28 15:39:51 -0700288 YYERROR;
289 }
290 }
291 | SCALAR
292 ;
Andreas Huberc9410c72016-07-28 12:18:40 -0700293
294package
Andreas Huber84f89de2016-07-28 15:39:51 -0700295 : PACKAGE FQNAME ';'
Andreas Hubereb1081f2016-07-28 13:13:24 -0700296 {
Andreas Huber84f89de2016-07-28 15:39:51 -0700297 if (!ast->setPackage($2)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700298 std::cerr << "ERROR: Malformed package identifier '"
299 << $2
300 << "' at "
301 << @2
302 << "\n";
303
Andreas Huber84f89de2016-07-28 15:39:51 -0700304 YYERROR;
305 }
Andreas Hubereb1081f2016-07-28 13:13:24 -0700306 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700307
Andreas Huberc9410c72016-07-28 12:18:40 -0700308imports
309 : /* empty */
Andreas Huber84f89de2016-07-28 15:39:51 -0700310 | imports IMPORT FQNAME ';'
Andreas Hubereb1081f2016-07-28 13:13:24 -0700311 {
Andreas Huber68f24592016-07-29 14:53:48 -0700312 if (!ast->addImport($3)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700313 std::cerr << "ERROR: Unable to import '" << $3 << "' at " << @3
314 << "\n";
Andreas Huber68f24592016-07-29 14:53:48 -0700315
316 YYERROR;
317 }
Andreas Hubereb1081f2016-07-28 13:13:24 -0700318 }
Andreas Huber5345ec22016-07-29 13:33:27 -0700319 | imports IMPORT IDENTIFIER ';'
320 {
Andreas Huber68f24592016-07-29 14:53:48 -0700321 if (!ast->addImport($3)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700322 std::cerr << "ERROR: Unable to import '" << $3 << "' at " << @3
323 << "\n";
Andreas Huber68f24592016-07-29 14:53:48 -0700324
325 YYERROR;
326 }
Andreas Huber5345ec22016-07-29 13:33:27 -0700327 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700328 ;
329
330opt_extends
331 : /* empty */ { $$ = NULL; }
Yifan Hongae16eed2016-09-23 13:25:25 -0700332 | EXTENDS fqtype { $$ = $2; }
Andreas Huberc9410c72016-07-28 12:18:40 -0700333
334body
Andreas Huber7c5ddfb2016-09-29 13:45:22 -0700335 : type_declarations
Andreas Huberc9410c72016-07-28 12:18:40 -0700336 ;
337
338interface_declarations
339 : /* empty */
340 | interface_declarations type_declaration
341 | interface_declarations method_declaration
342 {
343 Interface *iface = static_cast<Interface *>(ast->scope());
Steven Moreland14ee6742016-10-18 12:58:28 -0700344 if (!iface->addMethod($2)) {
345 std::cerr << "ERROR: Unable to add method '" << $2->name()
346 << "' at " << @2 << "\n";
347
348 YYERROR;
349 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700350 }
351 ;
352
353type_declarations
Andreas Hubera2723d22016-07-29 15:36:07 -0700354 : /* empty */
Andreas Huberc9410c72016-07-28 12:18:40 -0700355 | type_declarations type_declaration
356 ;
357
358type_declaration
Andreas Huber7c5ddfb2016-09-29 13:45:22 -0700359 : opt_annotations type_declaration_body
360 {
361 if ($2 != nullptr) {
362 $2->setAnnotations($1);
363 } else if (!$1->empty()) {
364 // Since typedefs are always resolved to their target it makes
365 // little sense to annotate them and have their annotations
366 // impose semantics other than their target type.
367 std::cerr << "ERROR: typedefs cannot be annotated. at " << @2
368 << "\n";
369
370 YYERROR;
371 }
372 }
373 ;
374
375type_declaration_body
Andreas Huberc9410c72016-07-28 12:18:40 -0700376 : named_struct_or_union_declaration ';'
377 | named_enum_declaration ';'
378 | typedef_declaration ';'
Andreas Huber7c5ddfb2016-09-29 13:45:22 -0700379 | interface_declaration ';'
380 ;
381
382interface_declaration
383 : INTERFACE IDENTIFIER opt_extends
384 {
385 if ($3 != NULL && !$3->isInterface()) {
386 std::cerr << "ERROR: You can only extend interfaces. at" << @3
387 << "\n";
388
389 YYERROR;
390 }
391
392 if ($2[0] != 'I') {
393 std::cerr << "ERROR: All interface names must start with an 'I' "
394 << "prefix. at " << @2 << "\n";
395
396 YYERROR;
397 }
398
399 Interface *iface = new Interface($2, static_cast<Interface *>($3));
400
401 // Register interface immediately so it can be referenced inside
402 // definition.
403 std::string errorMsg;
404 if (!ast->addScopedType(iface, &errorMsg)) {
405 std::cerr << "ERROR: " << errorMsg << " at " << @2 << "\n";
406 YYERROR;
407 }
408
409 ast->enterScope(iface);
410 }
411 '{' interface_declarations '}'
412 {
413 Interface *iface = static_cast<Interface *>(ast->scope());
414
415 ast->leaveScope();
416
417 $$ = iface;
418 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700419 ;
420
421typedef_declaration
422 : TYPEDEF type IDENTIFIER
423 {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700424 std::string errorMsg;
Andreas Huber39fa7182016-08-19 14:27:33 -0700425 if (!ast->addTypeDef($3, $2, &errorMsg)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700426 std::cerr << "ERROR: " << errorMsg << " at " << @3 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700427 YYERROR;
428 }
Andreas Huber7c5ddfb2016-09-29 13:45:22 -0700429
430 $$ = nullptr;
Andreas Huberc9410c72016-07-28 12:18:40 -0700431 }
432 ;
433
Yifan Hong52165692016-08-12 18:06:40 -0700434const_expr
Yifan Hongf24fa852016-09-23 11:03:15 -0700435 : INTEGER { $$ = new ConstantExpression($1); }
Yifan Hongb44a6c82016-09-22 15:50:18 -0700436 | fqname
437 {
Yifan Hongf24fa852016-09-23 11:03:15 -0700438 if(!$1->isValidValueName()) {
439 std::cerr << "ERROR: '" << $1->string()
440 << "' does not refer to an enum value at "
441 << @1 << ".\n";
442 YYERROR;
443 }
444 if($1->isIdentifier()) {
445 std::string identifier = $1->name();
446 LocalIdentifier *iden = ast->scope()->lookupIdentifier(identifier);
447 if(!iden) {
Steven Morelandc5908e62016-09-27 14:02:50 -0700448 std::cerr << "ERROR: at " << @1 << ", identifier " << $1->string()
Yifan Hongf24fa852016-09-23 11:03:15 -0700449 << " could not be found.\n";
450 YYERROR;
451 }
452 if(!iden->isEnumValue()) {
Steven Morelandc5908e62016-09-27 14:02:50 -0700453 std::cerr << "ERROR: at " << @1 << ", identifier " << $1->string()
Yifan Hongf24fa852016-09-23 11:03:15 -0700454 << " is not an enum value.\n";
455 YYERROR;
456 }
457 $$ = new ConstantExpression(
458 *(static_cast<EnumValue *>(iden)->constExpr()), $1->string());
459 } else {
460 std::string errorMsg;
461 EnumValue *v = ast->lookupEnumValue(*($1), &errorMsg);
462 if(v == nullptr) {
463 std::cerr << "ERROR: " << errorMsg << " at " << @1 << ".\n";
464 YYERROR;
465 }
466 $$ = new ConstantExpression(*(v->constExpr()), $1->string());
467 }
Yifan Hongb44a6c82016-09-22 15:50:18 -0700468 }
Yifan Hong52165692016-08-12 18:06:40 -0700469 | const_expr '?' const_expr ':' const_expr
470 {
Yifan Hongb44a6c82016-09-22 15:50:18 -0700471 $$ = new ConstantExpression($1, $3, $5);
Yifan Hong52165692016-08-12 18:06:40 -0700472 }
473 | const_expr LOGICAL_OR const_expr { $$ = new ConstantExpression($1, "||", $3); }
474 | const_expr LOGICAL_AND const_expr { $$ = new ConstantExpression($1, "&&", $3); }
475 | const_expr '|' const_expr { $$ = new ConstantExpression($1, "|" , $3); }
476 | const_expr '^' const_expr { $$ = new ConstantExpression($1, "^" , $3); }
477 | const_expr '&' const_expr { $$ = new ConstantExpression($1, "&" , $3); }
478 | const_expr EQUALITY const_expr { $$ = new ConstantExpression($1, "==", $3); }
479 | const_expr NEQ const_expr { $$ = new ConstantExpression($1, "!=", $3); }
480 | const_expr '<' const_expr { $$ = new ConstantExpression($1, "<" , $3); }
481 | const_expr '>' const_expr { $$ = new ConstantExpression($1, ">" , $3); }
482 | const_expr LEQ const_expr { $$ = new ConstantExpression($1, "<=", $3); }
483 | const_expr GEQ const_expr { $$ = new ConstantExpression($1, ">=", $3); }
484 | const_expr LSHIFT const_expr { $$ = new ConstantExpression($1, "<<", $3); }
485 | const_expr RSHIFT const_expr { $$ = new ConstantExpression($1, ">>", $3); }
486 | const_expr '+' const_expr { $$ = new ConstantExpression($1, "+" , $3); }
487 | const_expr '-' const_expr { $$ = new ConstantExpression($1, "-" , $3); }
488 | const_expr '*' const_expr { $$ = new ConstantExpression($1, "*" , $3); }
489 | const_expr '/' const_expr { $$ = new ConstantExpression($1, "/" , $3); }
490 | const_expr '%' const_expr { $$ = new ConstantExpression($1, "%" , $3); }
491 | '+' const_expr %prec UNARY_PLUS { $$ = new ConstantExpression("+", $2); }
492 | '-' const_expr %prec UNARY_MINUS { $$ = new ConstantExpression("-", $2); }
493 | '!' const_expr { $$ = new ConstantExpression("!", $2); }
494 | '~' const_expr { $$ = new ConstantExpression("~", $2); }
495 | '(' const_expr ')' { $$ = $2; }
496 ;
497
Andreas Huberc9410c72016-07-28 12:18:40 -0700498method_declaration
Andreas Huber3599d922016-08-09 10:42:57 -0700499 : opt_annotations IDENTIFIER '(' typed_vars ')' ';'
Andreas Huberc9410c72016-07-28 12:18:40 -0700500 {
Iliyan Malchev639bff82016-08-13 14:24:11 -0700501 $$ = new Method($2, $4, new std::vector<TypedVar *>, false, $1);
502 }
503 | opt_annotations ONEWAY IDENTIFIER '(' typed_vars ')' ';'
504 {
505 $$ = new Method($3, $5, new std::vector<TypedVar *>, true, $1);
Andreas Huberc9410c72016-07-28 12:18:40 -0700506 }
Andreas Huber3599d922016-08-09 10:42:57 -0700507 | opt_annotations IDENTIFIER '(' typed_vars ')' GENERATES '(' typed_vars ')' ';'
Andreas Huberc9410c72016-07-28 12:18:40 -0700508 {
Iliyan Malchev639bff82016-08-13 14:24:11 -0700509 $$ = new Method($2, $4, $8, false, $1);
Andreas Huberc9410c72016-07-28 12:18:40 -0700510 }
511 ;
512
513typed_vars
514 : /* empty */
515 {
Andreas Huber881227d2016-08-02 14:20:21 -0700516 $$ = new std::vector<TypedVar *>;
Andreas Huberc9410c72016-07-28 12:18:40 -0700517 }
518 | typed_var
519 {
Andreas Huber881227d2016-08-02 14:20:21 -0700520 $$ = new std::vector<TypedVar *>;
Andreas Huberc9410c72016-07-28 12:18:40 -0700521 $$->push_back($1);
522 }
523 | typed_vars ',' typed_var
524 {
525 $$ = $1;
526 $$->push_back($3);
527 }
528 ;
529
530typed_var : type IDENTIFIER { $$ = new TypedVar($2, $1); }
531 ;
532
533
534struct_or_union_keyword
535 : STRUCT { $$ = CompoundType::STYLE_STRUCT; }
536 | UNION { $$ = CompoundType::STYLE_UNION; }
537 ;
538
539named_struct_or_union_declaration
540 : struct_or_union_keyword IDENTIFIER
541 {
Andreas Huber9ed827c2016-08-22 12:31:13 -0700542 CompoundType *container = new CompoundType($1, $2);
Andreas Huberc9410c72016-07-28 12:18:40 -0700543 ast->enterScope(container);
544 }
545 struct_or_union_body
546 {
547 CompoundType *container = static_cast<CompoundType *>(ast->scope());
548
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700549 std::string errorMsg;
550 if (!container->setFields($4, &errorMsg)) {
551 std::cerr << "ERROR: " << errorMsg << " at " << @4 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700552 YYERROR;
553 }
554
Andreas Huberc9410c72016-07-28 12:18:40 -0700555 ast->leaveScope();
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700556
Andreas Huber9ed827c2016-08-22 12:31:13 -0700557 if (!ast->addScopedType(container, &errorMsg)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700558 std::cerr << "ERROR: " << errorMsg << " at " << @2 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700559 YYERROR;
560 }
Andreas Huber7c5ddfb2016-09-29 13:45:22 -0700561
562 $$ = container;
Andreas Huberc9410c72016-07-28 12:18:40 -0700563 }
564 ;
565
Andreas Huberc9410c72016-07-28 12:18:40 -0700566struct_or_union_body
567 : '{' field_declarations '}' { $$ = $2; }
568 ;
569
570field_declarations
Andreas Huber881227d2016-08-02 14:20:21 -0700571 : /* empty */ { $$ = new std::vector<CompoundField *>; }
Andreas Huberc9410c72016-07-28 12:18:40 -0700572 | field_declarations field_declaration
573 {
574 $$ = $1;
575
576 if ($2 != NULL) {
577 $$->push_back($2);
578 }
579 }
580 ;
581
582field_declaration
583 : type IDENTIFIER ';' { $$ = new CompoundField($2, $1); }
Andreas Huber7c5ddfb2016-09-29 13:45:22 -0700584 | annotated_compound_declaration ';' { $$ = NULL; }
585 ;
586
587annotated_compound_declaration
588 : opt_annotations compound_declaration
589 {
590 $2->setAnnotations($1);
591 $$ = $2;
592 }
593 ;
594
595compound_declaration
Yifan Honga2855012016-10-11 13:36:54 -0700596 : named_struct_or_union_declaration { $$ = $1; }
Yifan Hong6a2fedf2016-10-11 13:44:07 -0700597 | named_enum_declaration { $$ = $1; }
Andreas Huberc9410c72016-07-28 12:18:40 -0700598 ;
599
600opt_storage_type
601 : /* empty */ { $$ = NULL; }
Yifan Hongae16eed2016-09-23 13:25:25 -0700602 | ':' fqtype
Andreas Huber8d3ac0c2016-08-04 14:49:23 -0700603 {
604 $$ = $2;
605
606 if ($$ != NULL && !$$->isValidEnumStorageType()) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700607 std::cerr << "ERROR: Invalid enum storage type specified. at "
608 << @2 << "\n";
609
Andreas Huber8d3ac0c2016-08-04 14:49:23 -0700610 YYABORT;
611 }
612 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700613 ;
614
615opt_comma
616 : /* empty */
617 | ','
618 ;
619
620named_enum_declaration
Yifan Hongf24fa852016-09-23 11:03:15 -0700621 : ENUM IDENTIFIER opt_storage_type
Andreas Huberc9410c72016-07-28 12:18:40 -0700622 {
Yifan Hongf24fa852016-09-23 11:03:15 -0700623 ast->enterScope(new EnumType($2, $3));
624 }
625 enum_declaration_body
626 {
627 EnumType *enumType = static_cast<EnumType *>(ast->scope());
628 ast->leaveScope();
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700629
630 std::string errorMsg;
Andreas Huber9ed827c2016-08-22 12:31:13 -0700631 if (!ast->addScopedType(enumType, &errorMsg)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700632 std::cerr << "ERROR: " << errorMsg << " at " << @2 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700633 YYERROR;
634 }
Andreas Huber7c5ddfb2016-09-29 13:45:22 -0700635
636 $$ = enumType;
Andreas Huberc9410c72016-07-28 12:18:40 -0700637 }
638 ;
639
Yifan Hongf24fa852016-09-23 11:03:15 -0700640enum_declaration_body
641 : '{' enum_values opt_comma '}' { $$ = $2; }
642 ;
643
Andreas Huberc9410c72016-07-28 12:18:40 -0700644enum_value
645 : IDENTIFIER { $$ = new EnumValue($1); }
Yifan Hong57886972016-08-17 10:42:15 -0700646 | IDENTIFIER '=' const_expr { $$ = new EnumValue($1, $3); }
Andreas Huberc9410c72016-07-28 12:18:40 -0700647 ;
648
649enum_values
650 : /* empty */
Yifan Hongf24fa852016-09-23 11:03:15 -0700651 { /* do nothing */ }
Andreas Huberc9410c72016-07-28 12:18:40 -0700652 | enum_value
653 {
Yifan Hongf24fa852016-09-23 11:03:15 -0700654 static_cast<EnumType *>(ast->scope())->addValue($1);
Andreas Huberc9410c72016-07-28 12:18:40 -0700655 }
656 | enum_values ',' enum_value
657 {
Yifan Hongf24fa852016-09-23 11:03:15 -0700658 static_cast<EnumType *>(ast->scope())->addValue($3);
Andreas Huberc9410c72016-07-28 12:18:40 -0700659 }
660 ;
661
662type
Yifan Hongae16eed2016-09-23 13:25:25 -0700663 : fqtype { $$ = $1; }
Yifan Hongbf459bc2016-08-23 16:50:37 -0700664 | type '[' const_expr ']'
Andreas Huberb95ea8a2016-08-15 15:35:42 -0700665 {
Andreas Huber295ad302016-08-16 11:35:00 -0700666 if ($1->isBinder()) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700667 std::cerr << "ERROR: Arrays of interface types are not supported."
668 << " at " << @1 << "\n";
Andreas Huber70a59e12016-08-16 12:57:01 -0700669
Andreas Huberb95ea8a2016-08-15 15:35:42 -0700670 YYERROR;
671 }
672
Andreas Huber709b62d2016-09-19 11:21:18 -0700673 if ($1->isArray()) {
Yifan Hongf24fa852016-09-23 11:03:15 -0700674 $$ = new ArrayType(static_cast<ArrayType *>($1), $3);
Andreas Huber709b62d2016-09-19 11:21:18 -0700675 } else {
Yifan Hongf24fa852016-09-23 11:03:15 -0700676 $$ = new ArrayType($1, $3);
Andreas Huber709b62d2016-09-19 11:21:18 -0700677 }
Andreas Huberb95ea8a2016-08-15 15:35:42 -0700678 }
Yifan Hongbf459bc2016-08-23 16:50:37 -0700679 | TEMPLATED '<' type '>'
Andreas Huberb95ea8a2016-08-15 15:35:42 -0700680 {
Andreas Huber86a112b2016-10-19 14:25:16 -0700681 if (!$1->isVector() && $3->isBinder()) {
Yifan Hongbf459bc2016-08-23 16:50:37 -0700682 std::cerr << "ERROR: TemplatedType of interface types are not "
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700683 << "supported. at " << @3 << "\n";
Andreas Huber70a59e12016-08-16 12:57:01 -0700684
Andreas Huberb95ea8a2016-08-15 15:35:42 -0700685 YYERROR;
686 }
Yifan Hongbf459bc2016-08-23 16:50:37 -0700687 $1->setElementType($3);
688 $$ = $1;
689 }
690 | TEMPLATED '<' TEMPLATED '<' type RSHIFT
691 {
692 if ($5->isBinder()) {
693 std::cerr << "ERROR: TemplatedType of interface types are not "
694 << "supported. at " << @5 << "\n";
Andreas Huberb95ea8a2016-08-15 15:35:42 -0700695
Yifan Hongbf459bc2016-08-23 16:50:37 -0700696 YYERROR;
697 }
698 $3->setElementType($5);
699 $1->setElementType($3);
700 $$ = $1;
Andreas Huberb95ea8a2016-08-15 15:35:42 -0700701 }
Andreas Huber7c5ddfb2016-09-29 13:45:22 -0700702 | annotated_compound_declaration { $$ = $1; }
Andreas Huber295ad302016-08-16 11:35:00 -0700703 | INTERFACE { $$ = new GenericBinder; }
Andreas Huberc9410c72016-07-28 12:18:40 -0700704 ;
705
Andreas Huberc9410c72016-07-28 12:18:40 -0700706%%
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700707
708#include <android-base/logging.h>
709
710void yy::parser::error(
711 const yy::parser::location_type &where,
712 const std::string &errstr) {
713 std::cerr << "ERROR: " << errstr << " at " << where << "\n";
714}
715