blob: 9163aa38697368374fe316219904ff1cd7d4fd39 [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
Andreas Huberc9410c72016-07-28 12:18:40 -0700101%type<str> optIdentifier 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
106%type<type> enum_declaration
107%type<type> struct_or_union_declaration
108%type<type> opt_extends
Andreas Huber7c5ddfb2016-09-29 13:45:22 -0700109%type<type> type_declaration_body interface_declaration typedef_declaration
110%type<type> named_struct_or_union_declaration named_enum_declaration
111%type<type> compound_declaration annotated_compound_declaration
Andreas Huberc9410c72016-07-28 12:18:40 -0700112
113%type<field> field_declaration
114%type<fields> field_declarations struct_or_union_body
Yifan Hong52165692016-08-12 18:06:40 -0700115%type<constantExpression> const_expr
Andreas Huberc9410c72016-07-28 12:18:40 -0700116%type<enumValue> enum_value
Yifan Hongf24fa852016-09-23 11:03:15 -0700117%type<enumValues> enum_values enum_declaration_body
Andreas Huberc9410c72016-07-28 12:18:40 -0700118%type<typedVars> typed_vars
119%type<typedVar> typed_var
120%type<method> method_declaration
121%type<compoundStyle> struct_or_union_keyword
Yifan Hongf24fa852016-09-23 11:03:15 -0700122%type<stringVec> annotation_string_values annotation_string_value
123%type<constExprVec> annotation_const_expr_values annotation_const_expr_value
Andreas Huber3599d922016-08-09 10:42:57 -0700124%type<annotationParam> annotation_param
125%type<annotationParams> opt_annotation_params annotation_params
126%type<annotation> annotation
127%type<annotations> opt_annotations
Andreas Huberc9410c72016-07-28 12:18:40 -0700128
129%start program
130
131%union {
132 const char *str;
133 android::Type *type;
Yifan Hongbf459bc2016-08-23 16:50:37 -0700134 android::TemplatedType *templatedType;
Yifan Hongae16eed2016-09-23 13:25:25 -0700135 android::FQName *fqName;
Andreas Huberc9410c72016-07-28 12:18:40 -0700136 android::CompoundType *compoundType;
137 android::CompoundField *field;
Andreas Huber881227d2016-08-02 14:20:21 -0700138 std::vector<android::CompoundField *> *fields;
Andreas Huberc9410c72016-07-28 12:18:40 -0700139 android::EnumValue *enumValue;
Yifan Hong52165692016-08-12 18:06:40 -0700140 android::ConstantExpression *constantExpression;
Andreas Huber881227d2016-08-02 14:20:21 -0700141 std::vector<android::EnumValue *> *enumValues;
Andreas Huberc9410c72016-07-28 12:18:40 -0700142 android::TypedVar *typedVar;
Andreas Huber881227d2016-08-02 14:20:21 -0700143 std::vector<android::TypedVar *> *typedVars;
Andreas Huberc9410c72016-07-28 12:18:40 -0700144 android::Method *method;
145 android::CompoundType::Style compoundStyle;
Andreas Huber3599d922016-08-09 10:42:57 -0700146 std::vector<std::string> *stringVec;
Yifan Hongf24fa852016-09-23 11:03:15 -0700147 std::vector<android::ConstantExpression *> *constExprVec;
Steven Morelandd537ab02016-09-12 10:32:01 -0700148 android::AnnotationParam *annotationParam;
149 android::AnnotationParamVector *annotationParams;
Andreas Huber3599d922016-08-09 10:42:57 -0700150 android::Annotation *annotation;
Steven Morelandd537ab02016-09-12 10:32:01 -0700151 std::vector<android::Annotation *> *annotations;
Andreas Huberc9410c72016-07-28 12:18:40 -0700152}
153
154%%
155
Andreas Huber3599d922016-08-09 10:42:57 -0700156opt_annotations
157 : /* empty */
158 {
Steven Morelandd537ab02016-09-12 10:32:01 -0700159 $$ = new std::vector<Annotation *>;
Andreas Huber3599d922016-08-09 10:42:57 -0700160 }
161 | opt_annotations annotation
162 {
163 $$ = $1;
Steven Morelandd537ab02016-09-12 10:32:01 -0700164 $$->push_back($2);
Andreas Huber3599d922016-08-09 10:42:57 -0700165 }
166 ;
167
168annotation
169 : '@' IDENTIFIER opt_annotation_params
170 {
171 $$ = new Annotation($2, $3);
172 }
173 ;
174
175opt_annotation_params
176 : /* empty */
177 {
Steven Morelandd537ab02016-09-12 10:32:01 -0700178 $$ = new AnnotationParamVector;
Andreas Huber3599d922016-08-09 10:42:57 -0700179 }
180 | '(' annotation_params ')'
181 {
182 $$ = $2;
183 }
184 ;
185
186annotation_params
187 : annotation_param
188 {
Steven Morelandd537ab02016-09-12 10:32:01 -0700189 $$ = new AnnotationParamVector;
190 $$->push_back($1);
Andreas Huber3599d922016-08-09 10:42:57 -0700191 }
192 | annotation_params ',' annotation_param
193 {
194 $$ = $1;
Steven Morelandd537ab02016-09-12 10:32:01 -0700195 $$->push_back($3);
Andreas Huber3599d922016-08-09 10:42:57 -0700196 }
197 ;
198
199annotation_param
Yifan Hongf24fa852016-09-23 11:03:15 -0700200 : IDENTIFIER '=' annotation_string_value
201 {
202 $$ = new AnnotationParam($1, $3);
203 }
204 | IDENTIFIER '=' annotation_const_expr_value
Andreas Huber3599d922016-08-09 10:42:57 -0700205 {
Steven Morelandd537ab02016-09-12 10:32:01 -0700206 $$ = new AnnotationParam($1, $3);
Andreas Huber3599d922016-08-09 10:42:57 -0700207 }
208 ;
209
Yifan Hongf24fa852016-09-23 11:03:15 -0700210annotation_string_value
Andreas Huber3599d922016-08-09 10:42:57 -0700211 : STRING_LITERAL
212 {
213 $$ = new std::vector<std::string>;
214 $$->push_back($1);
215 }
216 | '{' annotation_string_values '}' { $$ = $2; }
217 ;
218
219annotation_string_values
220 : STRING_LITERAL
221 {
222 $$ = new std::vector<std::string>;
223 $$->push_back($1);
224 }
225 | annotation_string_values ',' STRING_LITERAL
226 {
227 $$ = $1;
228 $$->push_back($3);
229 }
230 ;
231
Yifan Hongf24fa852016-09-23 11:03:15 -0700232annotation_const_expr_value
233 : const_expr
234 {
235 $$ = new std::vector<ConstantExpression *>;
236 $$->push_back($1);
237 }
238 | '{' annotation_const_expr_values '}' { $$ = $2; }
239 ;
240
241annotation_const_expr_values
242 : const_expr
243 {
244 $$ = new std::vector<ConstantExpression *>;
245 $$->push_back($1);
246 }
247 | annotation_const_expr_values ',' const_expr
248 {
249 $$ = $1;
250 $$->push_back($3);
251 }
252 ;
253
Andreas Huberc9410c72016-07-28 12:18:40 -0700254program
Andreas Huberda51b8e2016-07-28 16:00:57 -0700255 : package imports body
Andreas Huber84f89de2016-07-28 15:39:51 -0700256 ;
257
258fqname
259 : FQNAME
260 {
Yifan Hongae16eed2016-09-23 13:25:25 -0700261 $$ = new FQName($1);
262 if(!$$->isValid()) {
263 std::cerr << "ERROR: FQName '" << $1 << "' is not valid at "
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700264 << @1
Yifan Hongae16eed2016-09-23 13:25:25 -0700265 << ".\n";
Andreas Huber84f89de2016-07-28 15:39:51 -0700266 YYERROR;
267 }
268 }
269 | IDENTIFIER
270 {
Yifan Hongae16eed2016-09-23 13:25:25 -0700271 $$ = new FQName($1);
272 if(!$$->isValid()) {
273 std::cerr << "ERROR: FQName '" << $1 << "' is not valid at "
274 << @1
275 << ".\n";
276 YYERROR;
277 }
278 }
279 ;
280
281fqtype
282 : fqname
283 {
284 $$ = ast->lookupType(*($1));
Andreas Huber84f89de2016-07-28 15:39:51 -0700285 if ($$ == NULL) {
Yifan Hongae16eed2016-09-23 13:25:25 -0700286 std::cerr << "ERROR: Failed to lookup type '" << $1->string() << "' at "
287 << @1
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700288 << "\n";
289
Andreas Huber84f89de2016-07-28 15:39:51 -0700290 YYERROR;
291 }
292 }
293 | SCALAR
294 ;
Andreas Huberc9410c72016-07-28 12:18:40 -0700295
296package
Andreas Huber84f89de2016-07-28 15:39:51 -0700297 : PACKAGE FQNAME ';'
Andreas Hubereb1081f2016-07-28 13:13:24 -0700298 {
Andreas Huber84f89de2016-07-28 15:39:51 -0700299 if (!ast->setPackage($2)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700300 std::cerr << "ERROR: Malformed package identifier '"
301 << $2
302 << "' at "
303 << @2
304 << "\n";
305
Andreas Huber84f89de2016-07-28 15:39:51 -0700306 YYERROR;
307 }
Andreas Hubereb1081f2016-07-28 13:13:24 -0700308 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700309
Andreas Huberc9410c72016-07-28 12:18:40 -0700310imports
311 : /* empty */
Andreas Huber84f89de2016-07-28 15:39:51 -0700312 | imports IMPORT FQNAME ';'
Andreas Hubereb1081f2016-07-28 13:13:24 -0700313 {
Andreas Huber68f24592016-07-29 14:53:48 -0700314 if (!ast->addImport($3)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700315 std::cerr << "ERROR: Unable to import '" << $3 << "' at " << @3
316 << "\n";
Andreas Huber68f24592016-07-29 14:53:48 -0700317
318 YYERROR;
319 }
Andreas Hubereb1081f2016-07-28 13:13:24 -0700320 }
Andreas Huber5345ec22016-07-29 13:33:27 -0700321 | imports IMPORT IDENTIFIER ';'
322 {
Andreas Huber68f24592016-07-29 14:53:48 -0700323 if (!ast->addImport($3)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700324 std::cerr << "ERROR: Unable to import '" << $3 << "' at " << @3
325 << "\n";
Andreas Huber68f24592016-07-29 14:53:48 -0700326
327 YYERROR;
328 }
Andreas Huber5345ec22016-07-29 13:33:27 -0700329 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700330 ;
331
332opt_extends
333 : /* empty */ { $$ = NULL; }
Yifan Hongae16eed2016-09-23 13:25:25 -0700334 | EXTENDS fqtype { $$ = $2; }
Andreas Huberc9410c72016-07-28 12:18:40 -0700335
336body
Andreas Huber7c5ddfb2016-09-29 13:45:22 -0700337 : type_declarations
Andreas Huberc9410c72016-07-28 12:18:40 -0700338 ;
339
340interface_declarations
341 : /* empty */
342 | interface_declarations type_declaration
343 | interface_declarations method_declaration
344 {
345 Interface *iface = static_cast<Interface *>(ast->scope());
346 iface->addMethod($2);
347 }
348 ;
349
350type_declarations
Andreas Hubera2723d22016-07-29 15:36:07 -0700351 : /* empty */
Andreas Huberc9410c72016-07-28 12:18:40 -0700352 | type_declarations type_declaration
353 ;
354
355type_declaration
Andreas Huber7c5ddfb2016-09-29 13:45:22 -0700356 : opt_annotations type_declaration_body
357 {
358 if ($2 != nullptr) {
359 $2->setAnnotations($1);
360 } else if (!$1->empty()) {
361 // Since typedefs are always resolved to their target it makes
362 // little sense to annotate them and have their annotations
363 // impose semantics other than their target type.
364 std::cerr << "ERROR: typedefs cannot be annotated. at " << @2
365 << "\n";
366
367 YYERROR;
368 }
369 }
370 ;
371
372type_declaration_body
Andreas Huberc9410c72016-07-28 12:18:40 -0700373 : named_struct_or_union_declaration ';'
374 | named_enum_declaration ';'
375 | typedef_declaration ';'
Andreas Huber7c5ddfb2016-09-29 13:45:22 -0700376 | interface_declaration ';'
377 ;
378
379interface_declaration
380 : INTERFACE IDENTIFIER opt_extends
381 {
382 if ($3 != NULL && !$3->isInterface()) {
383 std::cerr << "ERROR: You can only extend interfaces. at" << @3
384 << "\n";
385
386 YYERROR;
387 }
388
389 if ($2[0] != 'I') {
390 std::cerr << "ERROR: All interface names must start with an 'I' "
391 << "prefix. at " << @2 << "\n";
392
393 YYERROR;
394 }
395
396 Interface *iface = new Interface($2, static_cast<Interface *>($3));
397
398 // Register interface immediately so it can be referenced inside
399 // definition.
400 std::string errorMsg;
401 if (!ast->addScopedType(iface, &errorMsg)) {
402 std::cerr << "ERROR: " << errorMsg << " at " << @2 << "\n";
403 YYERROR;
404 }
405
406 ast->enterScope(iface);
407 }
408 '{' interface_declarations '}'
409 {
410 Interface *iface = static_cast<Interface *>(ast->scope());
411
412 ast->leaveScope();
413
414 $$ = iface;
415 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700416 ;
417
418typedef_declaration
419 : TYPEDEF type IDENTIFIER
420 {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700421 std::string errorMsg;
Andreas Huber39fa7182016-08-19 14:27:33 -0700422 if (!ast->addTypeDef($3, $2, &errorMsg)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700423 std::cerr << "ERROR: " << errorMsg << " at " << @3 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700424 YYERROR;
425 }
Andreas Huber7c5ddfb2016-09-29 13:45:22 -0700426
427 $$ = nullptr;
Andreas Huberc9410c72016-07-28 12:18:40 -0700428 }
429 ;
430
Yifan Hong52165692016-08-12 18:06:40 -0700431const_expr
Yifan Hongf24fa852016-09-23 11:03:15 -0700432 : INTEGER { $$ = new ConstantExpression($1); }
Yifan Hongb44a6c82016-09-22 15:50:18 -0700433 | fqname
434 {
Yifan Hongf24fa852016-09-23 11:03:15 -0700435 if(!$1->isValidValueName()) {
436 std::cerr << "ERROR: '" << $1->string()
437 << "' does not refer to an enum value at "
438 << @1 << ".\n";
439 YYERROR;
440 }
441 if($1->isIdentifier()) {
442 std::string identifier = $1->name();
443 LocalIdentifier *iden = ast->scope()->lookupIdentifier(identifier);
444 if(!iden) {
Steven Morelandc5908e62016-09-27 14:02:50 -0700445 std::cerr << "ERROR: at " << @1 << ", identifier " << $1->string()
Yifan Hongf24fa852016-09-23 11:03:15 -0700446 << " could not be found.\n";
447 YYERROR;
448 }
449 if(!iden->isEnumValue()) {
Steven Morelandc5908e62016-09-27 14:02:50 -0700450 std::cerr << "ERROR: at " << @1 << ", identifier " << $1->string()
Yifan Hongf24fa852016-09-23 11:03:15 -0700451 << " is not an enum value.\n";
452 YYERROR;
453 }
454 $$ = new ConstantExpression(
455 *(static_cast<EnumValue *>(iden)->constExpr()), $1->string());
456 } else {
457 std::string errorMsg;
458 EnumValue *v = ast->lookupEnumValue(*($1), &errorMsg);
459 if(v == nullptr) {
460 std::cerr << "ERROR: " << errorMsg << " at " << @1 << ".\n";
461 YYERROR;
462 }
463 $$ = new ConstantExpression(*(v->constExpr()), $1->string());
464 }
Yifan Hongb44a6c82016-09-22 15:50:18 -0700465 }
Yifan Hong52165692016-08-12 18:06:40 -0700466 | const_expr '?' const_expr ':' const_expr
467 {
Yifan Hongb44a6c82016-09-22 15:50:18 -0700468 $$ = new ConstantExpression($1, $3, $5);
Yifan Hong52165692016-08-12 18:06:40 -0700469 }
470 | const_expr LOGICAL_OR const_expr { $$ = new ConstantExpression($1, "||", $3); }
471 | const_expr LOGICAL_AND const_expr { $$ = new ConstantExpression($1, "&&", $3); }
472 | const_expr '|' const_expr { $$ = new ConstantExpression($1, "|" , $3); }
473 | const_expr '^' const_expr { $$ = new ConstantExpression($1, "^" , $3); }
474 | const_expr '&' const_expr { $$ = new ConstantExpression($1, "&" , $3); }
475 | const_expr EQUALITY const_expr { $$ = new ConstantExpression($1, "==", $3); }
476 | const_expr NEQ const_expr { $$ = new ConstantExpression($1, "!=", $3); }
477 | const_expr '<' const_expr { $$ = new ConstantExpression($1, "<" , $3); }
478 | const_expr '>' const_expr { $$ = new ConstantExpression($1, ">" , $3); }
479 | const_expr LEQ const_expr { $$ = new ConstantExpression($1, "<=", $3); }
480 | const_expr GEQ const_expr { $$ = new ConstantExpression($1, ">=", $3); }
481 | const_expr LSHIFT const_expr { $$ = new ConstantExpression($1, "<<", $3); }
482 | const_expr RSHIFT const_expr { $$ = new ConstantExpression($1, ">>", $3); }
483 | const_expr '+' const_expr { $$ = new ConstantExpression($1, "+" , $3); }
484 | const_expr '-' const_expr { $$ = new ConstantExpression($1, "-" , $3); }
485 | const_expr '*' 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 %prec UNARY_PLUS { $$ = new ConstantExpression("+", $2); }
489 | '-' const_expr %prec UNARY_MINUS { $$ = new ConstantExpression("-", $2); }
490 | '!' const_expr { $$ = new ConstantExpression("!", $2); }
491 | '~' const_expr { $$ = new ConstantExpression("~", $2); }
492 | '(' const_expr ')' { $$ = $2; }
493 ;
494
Andreas Huberc9410c72016-07-28 12:18:40 -0700495method_declaration
Andreas Huber3599d922016-08-09 10:42:57 -0700496 : opt_annotations IDENTIFIER '(' typed_vars ')' ';'
Andreas Huberc9410c72016-07-28 12:18:40 -0700497 {
Iliyan Malchev639bff82016-08-13 14:24:11 -0700498 $$ = new Method($2, $4, new std::vector<TypedVar *>, false, $1);
499 }
500 | opt_annotations ONEWAY IDENTIFIER '(' typed_vars ')' ';'
501 {
502 $$ = new Method($3, $5, new std::vector<TypedVar *>, true, $1);
Andreas Huberc9410c72016-07-28 12:18:40 -0700503 }
Andreas Huber3599d922016-08-09 10:42:57 -0700504 | opt_annotations IDENTIFIER '(' typed_vars ')' GENERATES '(' typed_vars ')' ';'
Andreas Huberc9410c72016-07-28 12:18:40 -0700505 {
Iliyan Malchev639bff82016-08-13 14:24:11 -0700506 $$ = new Method($2, $4, $8, false, $1);
Andreas Huberc9410c72016-07-28 12:18:40 -0700507 }
508 ;
509
510typed_vars
511 : /* empty */
512 {
Andreas Huber881227d2016-08-02 14:20:21 -0700513 $$ = new std::vector<TypedVar *>;
Andreas Huberc9410c72016-07-28 12:18:40 -0700514 }
515 | typed_var
516 {
Andreas Huber881227d2016-08-02 14:20:21 -0700517 $$ = new std::vector<TypedVar *>;
Andreas Huberc9410c72016-07-28 12:18:40 -0700518 $$->push_back($1);
519 }
520 | typed_vars ',' typed_var
521 {
522 $$ = $1;
523 $$->push_back($3);
524 }
525 ;
526
527typed_var : type IDENTIFIER { $$ = new TypedVar($2, $1); }
528 ;
529
530
531struct_or_union_keyword
532 : STRUCT { $$ = CompoundType::STYLE_STRUCT; }
533 | UNION { $$ = CompoundType::STYLE_UNION; }
534 ;
535
536named_struct_or_union_declaration
537 : struct_or_union_keyword IDENTIFIER
538 {
Andreas Huber9ed827c2016-08-22 12:31:13 -0700539 CompoundType *container = new CompoundType($1, $2);
Andreas Huberc9410c72016-07-28 12:18:40 -0700540 ast->enterScope(container);
541 }
542 struct_or_union_body
543 {
544 CompoundType *container = static_cast<CompoundType *>(ast->scope());
545
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700546 std::string errorMsg;
547 if (!container->setFields($4, &errorMsg)) {
548 std::cerr << "ERROR: " << errorMsg << " at " << @4 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700549 YYERROR;
550 }
551
Andreas Huberc9410c72016-07-28 12:18:40 -0700552 ast->leaveScope();
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700553
Andreas Huber9ed827c2016-08-22 12:31:13 -0700554 if (!ast->addScopedType(container, &errorMsg)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700555 std::cerr << "ERROR: " << errorMsg << " at " << @2 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700556 YYERROR;
557 }
Andreas Huber7c5ddfb2016-09-29 13:45:22 -0700558
559 $$ = container;
Andreas Huberc9410c72016-07-28 12:18:40 -0700560 }
561 ;
562
563struct_or_union_declaration
564 : struct_or_union_keyword optIdentifier
565 {
Andreas Huber9ed827c2016-08-22 12:31:13 -0700566 const char *localName = $2;
567 std::string anonName;
568 if (localName == nullptr) {
569 anonName = ast->scope()->pickUniqueAnonymousName();
570 localName = anonName.c_str();
571 }
572
573 CompoundType *container = new CompoundType($1, localName);
Andreas Huberc9410c72016-07-28 12:18:40 -0700574 ast->enterScope(container);
575 }
576 struct_or_union_body
577 {
578 CompoundType *container = static_cast<CompoundType *>(ast->scope());
579
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700580 std::string errorMsg;
581 if (!container->setFields($4, &errorMsg)) {
582 std::cerr << "ERROR: " << errorMsg << " at " << @4 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700583 YYERROR;
584 }
585
Andreas Huberc9410c72016-07-28 12:18:40 -0700586 ast->leaveScope();
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700587
Andreas Huber9ed827c2016-08-22 12:31:13 -0700588 if (!ast->addScopedType(container, &errorMsg)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700589 std::cerr << "ERROR: " << errorMsg << " at " << @2 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700590 YYERROR;
591 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700592
Steven Morelandbb5c80b2016-10-05 11:07:36 -0700593 $$ = container;
Andreas Huberc9410c72016-07-28 12:18:40 -0700594 }
595 ;
596
597struct_or_union_body
598 : '{' field_declarations '}' { $$ = $2; }
599 ;
600
601field_declarations
Andreas Huber881227d2016-08-02 14:20:21 -0700602 : /* empty */ { $$ = new std::vector<CompoundField *>; }
Andreas Huberc9410c72016-07-28 12:18:40 -0700603 | field_declarations field_declaration
604 {
605 $$ = $1;
606
607 if ($2 != NULL) {
608 $$->push_back($2);
609 }
610 }
611 ;
612
613field_declaration
614 : type IDENTIFIER ';' { $$ = new CompoundField($2, $1); }
Andreas Huber7c5ddfb2016-09-29 13:45:22 -0700615 | annotated_compound_declaration ';' { $$ = NULL; }
616 ;
617
618annotated_compound_declaration
619 : opt_annotations compound_declaration
620 {
621 $2->setAnnotations($1);
622 $$ = $2;
623 }
624 ;
625
626compound_declaration
627 : struct_or_union_declaration { $$ = $1; }
628 | enum_declaration { $$ = $1; }
Andreas Huberc9410c72016-07-28 12:18:40 -0700629 ;
630
631opt_storage_type
632 : /* empty */ { $$ = NULL; }
Yifan Hongae16eed2016-09-23 13:25:25 -0700633 | ':' fqtype
Andreas Huber8d3ac0c2016-08-04 14:49:23 -0700634 {
635 $$ = $2;
636
637 if ($$ != NULL && !$$->isValidEnumStorageType()) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700638 std::cerr << "ERROR: Invalid enum storage type specified. at "
639 << @2 << "\n";
640
Andreas Huber8d3ac0c2016-08-04 14:49:23 -0700641 YYABORT;
642 }
643 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700644 ;
645
646opt_comma
647 : /* empty */
648 | ','
649 ;
650
651named_enum_declaration
Yifan Hongf24fa852016-09-23 11:03:15 -0700652 : ENUM IDENTIFIER opt_storage_type
Andreas Huberc9410c72016-07-28 12:18:40 -0700653 {
Yifan Hongf24fa852016-09-23 11:03:15 -0700654 ast->enterScope(new EnumType($2, $3));
655 }
656 enum_declaration_body
657 {
658 EnumType *enumType = static_cast<EnumType *>(ast->scope());
659 ast->leaveScope();
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700660
661 std::string errorMsg;
Andreas Huber9ed827c2016-08-22 12:31:13 -0700662 if (!ast->addScopedType(enumType, &errorMsg)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700663 std::cerr << "ERROR: " << errorMsg << " at " << @2 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700664 YYERROR;
665 }
Andreas Huber7c5ddfb2016-09-29 13:45:22 -0700666
667 $$ = enumType;
Andreas Huberc9410c72016-07-28 12:18:40 -0700668 }
669 ;
670
671enum_declaration
Yifan Hongf24fa852016-09-23 11:03:15 -0700672 : ENUM
Andreas Huberc9410c72016-07-28 12:18:40 -0700673 {
Andreas Huber9ed827c2016-08-22 12:31:13 -0700674 std::string anonName = ast->scope()->pickUniqueAnonymousName();
Yifan Hongf24fa852016-09-23 11:03:15 -0700675 ast->enterScope(new EnumType(anonName.c_str()));
676 }
677 enum_declaration_body
678 {
Andreas Huber9ed827c2016-08-22 12:31:13 -0700679
Yifan Hongf24fa852016-09-23 11:03:15 -0700680 EnumType *enumType = static_cast<EnumType *>(ast->scope());
681 ast->leaveScope();
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700682
683 std::string errorMsg;
Andreas Huber9ed827c2016-08-22 12:31:13 -0700684 if (!ast->addScopedType(enumType, &errorMsg)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700685 // This should never fail.
686 std::cerr << "ERROR: " << errorMsg << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700687 YYERROR;
688 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700689
Steven Morelandbb5c80b2016-10-05 11:07:36 -0700690 $$ = enumType;
Andreas Huberc9410c72016-07-28 12:18:40 -0700691 }
Yifan Hongf24fa852016-09-23 11:03:15 -0700692 | ENUM IDENTIFIER opt_storage_type
Andreas Huberc9410c72016-07-28 12:18:40 -0700693 {
Yifan Hongf24fa852016-09-23 11:03:15 -0700694 ast->enterScope(new EnumType($2, $3));
695 }
696 enum_declaration_body
697 {
698 EnumType *enumType = static_cast<EnumType *>(ast->scope());
699 ast->leaveScope();
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700700
701 std::string errorMsg;
Andreas Huber9ed827c2016-08-22 12:31:13 -0700702 if (!ast->addScopedType(enumType, &errorMsg)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700703 std::cerr << "ERROR: " << errorMsg << " at " << @2 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700704 YYERROR;
705 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700706
Steven Morelandbb5c80b2016-10-05 11:07:36 -0700707 $$ = enumType;
Andreas Huberc9410c72016-07-28 12:18:40 -0700708 }
709 ;
710
Yifan Hongf24fa852016-09-23 11:03:15 -0700711enum_declaration_body
712 : '{' enum_values opt_comma '}' { $$ = $2; }
713 ;
714
Andreas Huberc9410c72016-07-28 12:18:40 -0700715enum_value
716 : IDENTIFIER { $$ = new EnumValue($1); }
Yifan Hong57886972016-08-17 10:42:15 -0700717 | IDENTIFIER '=' const_expr { $$ = new EnumValue($1, $3); }
Andreas Huberc9410c72016-07-28 12:18:40 -0700718 ;
719
720enum_values
721 : /* empty */
Yifan Hongf24fa852016-09-23 11:03:15 -0700722 { /* do nothing */ }
Andreas Huberc9410c72016-07-28 12:18:40 -0700723 | enum_value
724 {
Yifan Hongf24fa852016-09-23 11:03:15 -0700725 static_cast<EnumType *>(ast->scope())->addValue($1);
Andreas Huberc9410c72016-07-28 12:18:40 -0700726 }
727 | enum_values ',' enum_value
728 {
Yifan Hongf24fa852016-09-23 11:03:15 -0700729 static_cast<EnumType *>(ast->scope())->addValue($3);
Andreas Huberc9410c72016-07-28 12:18:40 -0700730 }
731 ;
732
733type
Yifan Hongae16eed2016-09-23 13:25:25 -0700734 : fqtype { $$ = $1; }
Yifan Hongbf459bc2016-08-23 16:50:37 -0700735 | type '[' const_expr ']'
Andreas Huberb95ea8a2016-08-15 15:35:42 -0700736 {
Andreas Huber295ad302016-08-16 11:35:00 -0700737 if ($1->isBinder()) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700738 std::cerr << "ERROR: Arrays of interface types are not supported."
739 << " at " << @1 << "\n";
Andreas Huber70a59e12016-08-16 12:57:01 -0700740
Andreas Huberb95ea8a2016-08-15 15:35:42 -0700741 YYERROR;
742 }
743
Andreas Huber709b62d2016-09-19 11:21:18 -0700744 if ($1->isArray()) {
Yifan Hongf24fa852016-09-23 11:03:15 -0700745 $$ = new ArrayType(static_cast<ArrayType *>($1), $3);
Andreas Huber709b62d2016-09-19 11:21:18 -0700746 } else {
Yifan Hongf24fa852016-09-23 11:03:15 -0700747 $$ = new ArrayType($1, $3);
Andreas Huber709b62d2016-09-19 11:21:18 -0700748 }
Andreas Huberb95ea8a2016-08-15 15:35:42 -0700749 }
Yifan Hongbf459bc2016-08-23 16:50:37 -0700750 | TEMPLATED '<' type '>'
Andreas Huberb95ea8a2016-08-15 15:35:42 -0700751 {
Andreas Huber295ad302016-08-16 11:35:00 -0700752 if ($3->isBinder()) {
Yifan Hongbf459bc2016-08-23 16:50:37 -0700753 std::cerr << "ERROR: TemplatedType of interface types are not "
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700754 << "supported. at " << @3 << "\n";
Andreas Huber70a59e12016-08-16 12:57:01 -0700755
Andreas Huberb95ea8a2016-08-15 15:35:42 -0700756 YYERROR;
757 }
Yifan Hongbf459bc2016-08-23 16:50:37 -0700758 $1->setElementType($3);
759 $$ = $1;
760 }
761 | TEMPLATED '<' TEMPLATED '<' type RSHIFT
762 {
763 if ($5->isBinder()) {
764 std::cerr << "ERROR: TemplatedType of interface types are not "
765 << "supported. at " << @5 << "\n";
Andreas Huberb95ea8a2016-08-15 15:35:42 -0700766
Yifan Hongbf459bc2016-08-23 16:50:37 -0700767 YYERROR;
768 }
769 $3->setElementType($5);
770 $1->setElementType($3);
771 $$ = $1;
Andreas Huberb95ea8a2016-08-15 15:35:42 -0700772 }
Andreas Huber7c5ddfb2016-09-29 13:45:22 -0700773 | annotated_compound_declaration { $$ = $1; }
Andreas Huber295ad302016-08-16 11:35:00 -0700774 | INTERFACE { $$ = new GenericBinder; }
Andreas Huberc9410c72016-07-28 12:18:40 -0700775 ;
776
777optIdentifier
778 : /* empty */ { $$ = NULL; }
779 | IDENTIFIER { $$ = $1; }
780 ;
781
782%%
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700783
784#include <android-base/logging.h>
785
786void yy::parser::error(
787 const yy::parser::location_type &where,
788 const std::string &errstr) {
789 std::cerr << "ERROR: " << errstr << " at " << where << "\n";
790}
791