blob: ce6a49a7af34056b9ba9ce18a5172b8c6b1a9fa0 [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"
Andreas Huber295ad302016-08-16 11:35:00 -070025#include "GenericBinder.h"
Andreas Huberc9410c72016-07-28 12:18:40 -070026#include "Interface.h"
27#include "Method.h"
Andreas Huberc9410c72016-07-28 12:18:40 -070028#include "VectorType.h"
29
30#include "hidl-gen_y.h"
31
Andreas Huber709b62d2016-09-19 11:21:18 -070032#include <android-base/logging.h>
Andreas Huberc9410c72016-07-28 12:18:40 -070033#include <stdio.h>
34
35using namespace android;
36
Andreas Huber0d0f9a22016-08-17 10:26:11 -070037extern int yylex(yy::parser::semantic_type *, yy::parser::location_type *, void *);
Andreas Huberc9410c72016-07-28 12:18:40 -070038
39#define scanner ast->scanner()
40
41%}
42
Andreas Huber0d0f9a22016-08-17 10:26:11 -070043%initial-action {
44 // Initialize the initial location.
45 @$.begin.filename = @$.end.filename =
46 const_cast<std::string *>(&ast->getFilename());
47}
48
Andreas Huberc9410c72016-07-28 12:18:40 -070049%parse-param { android::AST *ast }
50%lex-param { void *scanner }
51%pure-parser
Andreas Huber0d0f9a22016-08-17 10:26:11 -070052%skeleton "glr.cc"
Andreas Huberc9410c72016-07-28 12:18:40 -070053
Andreas Huberc9410c72016-07-28 12:18:40 -070054%token<str> ENUM
55%token<str> EXTENDS
Andreas Huber84f89de2016-07-28 15:39:51 -070056%token<str> FQNAME
Andreas Huberc9410c72016-07-28 12:18:40 -070057%token<str> GENERATES
58%token<str> IDENTIFIER
59%token<str> IMPORT
60%token<str> INTEGER
Yifan Hong52165692016-08-12 18:06:40 -070061%token<str> FLOAT
Andreas Huberc9410c72016-07-28 12:18:40 -070062%token<str> INTERFACE
63%token<str> PACKAGE
Andreas Huber84f89de2016-07-28 15:39:51 -070064%token<type> SCALAR
Andreas Huberc9410c72016-07-28 12:18:40 -070065%token<str> STRUCT
66%token<str> STRING_LITERAL
67%token<str> TYPEDEF
68%token<str> UNION
69%token<str> VEC
Iliyan Malchev639bff82016-08-13 14:24:11 -070070%token<void> ONEWAY
Andreas Huberc9410c72016-07-28 12:18:40 -070071
Yifan Hong52165692016-08-12 18:06:40 -070072/* Operator precedence and associativity, as per
73 * http://en.cppreference.com/w/cpp/language/operator_precedence */
74/* Precedence level 15 ternary operator */
75%right '?' ':'
76/* Precedence level 13 - 14, LTR, logical operators*/
77%left LOGICAL_OR
78%left LOGICAL_AND
79/* Precedence level 10 - 12, LTR, bitwise operators*/
80%left '|'
81%left '^'
82%left '&'
83/* Precedence level 9, LTR */
84%left EQUALITY NEQ
85/* Precedence level 8, LTR */
86%left '<' '>' LEQ GEQ
87/* Precedence level 7, LTR */
88%left LSHIFT RSHIFT
89/* Precedence level 6, LTR */
90%left '+' '-'
91/* Precedence level 5, LTR */
92%left '*' '/' '%'
93/* Precedence level 3, RTL; but we have to use %left here */
94%left UNARY_MINUS UNARY_PLUS '!' '~'
95
Andreas Huberc9410c72016-07-28 12:18:40 -070096%type<str> optIdentifier package
Yifan Hongae16eed2016-09-23 13:25:25 -070097%type<fqName> fqname
98%type<type> fqtype
Andreas Huberc9410c72016-07-28 12:18:40 -070099
100%type<type> type opt_storage_type
101%type<type> enum_declaration
102%type<type> struct_or_union_declaration
103%type<type> opt_extends
104
105%type<field> field_declaration
106%type<fields> field_declarations struct_or_union_body
Yifan Hong52165692016-08-12 18:06:40 -0700107%type<constantExpression> const_expr
Andreas Huberc9410c72016-07-28 12:18:40 -0700108%type<enumValue> enum_value
109%type<enumValues> enum_values
110%type<typedVars> typed_vars
111%type<typedVar> typed_var
112%type<method> method_declaration
113%type<compoundStyle> struct_or_union_keyword
Andreas Huber3599d922016-08-09 10:42:57 -0700114%type<stringVec> annotation_string_values annotation_value
115%type<annotationParam> annotation_param
116%type<annotationParams> opt_annotation_params annotation_params
117%type<annotation> annotation
118%type<annotations> opt_annotations
Andreas Huberc9410c72016-07-28 12:18:40 -0700119
120%start program
121
122%union {
123 const char *str;
124 android::Type *type;
Yifan Hongae16eed2016-09-23 13:25:25 -0700125 android::FQName *fqName;
Andreas Huberc9410c72016-07-28 12:18:40 -0700126 android::CompoundType *compoundType;
127 android::CompoundField *field;
Andreas Huber881227d2016-08-02 14:20:21 -0700128 std::vector<android::CompoundField *> *fields;
Andreas Huberc9410c72016-07-28 12:18:40 -0700129 android::EnumValue *enumValue;
Yifan Hong52165692016-08-12 18:06:40 -0700130 android::ConstantExpression *constantExpression;
Andreas Huber881227d2016-08-02 14:20:21 -0700131 std::vector<android::EnumValue *> *enumValues;
Andreas Huberc9410c72016-07-28 12:18:40 -0700132 android::TypedVar *typedVar;
Andreas Huber881227d2016-08-02 14:20:21 -0700133 std::vector<android::TypedVar *> *typedVars;
Andreas Huberc9410c72016-07-28 12:18:40 -0700134 android::Method *method;
135 android::CompoundType::Style compoundStyle;
Andreas Huber3599d922016-08-09 10:42:57 -0700136 std::vector<std::string> *stringVec;
Steven Morelandd537ab02016-09-12 10:32:01 -0700137 android::AnnotationParam *annotationParam;
138 android::AnnotationParamVector *annotationParams;
Andreas Huber3599d922016-08-09 10:42:57 -0700139 android::Annotation *annotation;
Steven Morelandd537ab02016-09-12 10:32:01 -0700140 std::vector<android::Annotation *> *annotations;
Andreas Huberc9410c72016-07-28 12:18:40 -0700141}
142
143%%
144
Andreas Huber3599d922016-08-09 10:42:57 -0700145opt_annotations
146 : /* empty */
147 {
Steven Morelandd537ab02016-09-12 10:32:01 -0700148 $$ = new std::vector<Annotation *>;
Andreas Huber3599d922016-08-09 10:42:57 -0700149 }
150 | opt_annotations annotation
151 {
152 $$ = $1;
Steven Morelandd537ab02016-09-12 10:32:01 -0700153 $$->push_back($2);
Andreas Huber3599d922016-08-09 10:42:57 -0700154 }
155 ;
156
157annotation
158 : '@' IDENTIFIER opt_annotation_params
159 {
160 $$ = new Annotation($2, $3);
161 }
162 ;
163
164opt_annotation_params
165 : /* empty */
166 {
Steven Morelandd537ab02016-09-12 10:32:01 -0700167 $$ = new AnnotationParamVector;
Andreas Huber3599d922016-08-09 10:42:57 -0700168 }
169 | '(' annotation_params ')'
170 {
171 $$ = $2;
172 }
173 ;
174
175annotation_params
176 : annotation_param
177 {
Steven Morelandd537ab02016-09-12 10:32:01 -0700178 $$ = new AnnotationParamVector;
179 $$->push_back($1);
Andreas Huber3599d922016-08-09 10:42:57 -0700180 }
181 | annotation_params ',' annotation_param
182 {
183 $$ = $1;
Steven Morelandd537ab02016-09-12 10:32:01 -0700184 $$->push_back($3);
Andreas Huber3599d922016-08-09 10:42:57 -0700185 }
186 ;
187
188annotation_param
189 : IDENTIFIER '=' annotation_value
190 {
Steven Morelandd537ab02016-09-12 10:32:01 -0700191 $$ = new AnnotationParam($1, $3);
Andreas Huber3599d922016-08-09 10:42:57 -0700192 }
193 ;
194
195annotation_value
196 : STRING_LITERAL
197 {
198 $$ = new std::vector<std::string>;
199 $$->push_back($1);
200 }
201 | '{' annotation_string_values '}' { $$ = $2; }
202 ;
203
204annotation_string_values
205 : STRING_LITERAL
206 {
207 $$ = new std::vector<std::string>;
208 $$->push_back($1);
209 }
210 | annotation_string_values ',' STRING_LITERAL
211 {
212 $$ = $1;
213 $$->push_back($3);
214 }
215 ;
216
Andreas Huberc9410c72016-07-28 12:18:40 -0700217program
Andreas Huberda51b8e2016-07-28 16:00:57 -0700218 : package imports body
Andreas Huber84f89de2016-07-28 15:39:51 -0700219 ;
220
221fqname
222 : FQNAME
223 {
Yifan Hongae16eed2016-09-23 13:25:25 -0700224 $$ = new FQName($1);
225 if(!$$->isValid()) {
226 std::cerr << "ERROR: FQName '" << $1 << "' is not valid at "
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700227 << @1
Yifan Hongae16eed2016-09-23 13:25:25 -0700228 << ".\n";
Andreas Huber84f89de2016-07-28 15:39:51 -0700229 YYERROR;
230 }
231 }
232 | IDENTIFIER
233 {
Yifan Hongae16eed2016-09-23 13:25:25 -0700234 $$ = new FQName($1);
235 if(!$$->isValid()) {
236 std::cerr << "ERROR: FQName '" << $1 << "' is not valid at "
237 << @1
238 << ".\n";
239 YYERROR;
240 }
241 }
242 ;
243
244fqtype
245 : fqname
246 {
247 $$ = ast->lookupType(*($1));
Andreas Huber84f89de2016-07-28 15:39:51 -0700248 if ($$ == NULL) {
Yifan Hongae16eed2016-09-23 13:25:25 -0700249 std::cerr << "ERROR: Failed to lookup type '" << $1->string() << "' at "
250 << @1
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700251 << "\n";
252
Andreas Huber84f89de2016-07-28 15:39:51 -0700253 YYERROR;
254 }
255 }
256 | SCALAR
257 ;
Andreas Huberc9410c72016-07-28 12:18:40 -0700258
259package
Andreas Huber84f89de2016-07-28 15:39:51 -0700260 : PACKAGE FQNAME ';'
Andreas Hubereb1081f2016-07-28 13:13:24 -0700261 {
Andreas Huber84f89de2016-07-28 15:39:51 -0700262 if (!ast->setPackage($2)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700263 std::cerr << "ERROR: Malformed package identifier '"
264 << $2
265 << "' at "
266 << @2
267 << "\n";
268
Andreas Huber84f89de2016-07-28 15:39:51 -0700269 YYERROR;
270 }
Andreas Hubereb1081f2016-07-28 13:13:24 -0700271 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700272
Andreas Huberc9410c72016-07-28 12:18:40 -0700273imports
274 : /* empty */
Andreas Huber84f89de2016-07-28 15:39:51 -0700275 | imports IMPORT FQNAME ';'
Andreas Hubereb1081f2016-07-28 13:13:24 -0700276 {
Andreas Huber68f24592016-07-29 14:53:48 -0700277 if (!ast->addImport($3)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700278 std::cerr << "ERROR: Unable to import '" << $3 << "' at " << @3
279 << "\n";
Andreas Huber68f24592016-07-29 14:53:48 -0700280
281 YYERROR;
282 }
Andreas Hubereb1081f2016-07-28 13:13:24 -0700283 }
Andreas Huber5345ec22016-07-29 13:33:27 -0700284 | imports IMPORT IDENTIFIER ';'
285 {
Andreas Huber68f24592016-07-29 14:53:48 -0700286 if (!ast->addImport($3)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700287 std::cerr << "ERROR: Unable to import '" << $3 << "' at " << @3
288 << "\n";
Andreas Huber68f24592016-07-29 14:53:48 -0700289
290 YYERROR;
291 }
Andreas Huber5345ec22016-07-29 13:33:27 -0700292 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700293 ;
294
295opt_extends
296 : /* empty */ { $$ = NULL; }
Yifan Hongae16eed2016-09-23 13:25:25 -0700297 | EXTENDS fqtype { $$ = $2; }
Andreas Huberc9410c72016-07-28 12:18:40 -0700298
299body
Zhuoyao Zhangba7e6e92016-08-10 12:19:02 -0700300 : opt_annotations INTERFACE IDENTIFIER opt_extends
Andreas Huberc9410c72016-07-28 12:18:40 -0700301 {
Zhuoyao Zhangba7e6e92016-08-10 12:19:02 -0700302 if ($4 != NULL && !$4->isInterface()) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700303 std::cerr << "ERROR: You can only extend interfaces. at" << @4
304 << "\n";
305
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700306 YYERROR;
307 }
308
Andreas Huber991b8642016-08-15 16:40:44 -0700309 if ($3[0] != 'I') {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700310 std::cerr << "ERROR: All interface names must start with an 'I' "
311 << "prefix. at " << @3 << "\n";
Andreas Huber991b8642016-08-15 16:40:44 -0700312
313 YYERROR;
314 }
315
Andreas Huber9ed827c2016-08-22 12:31:13 -0700316 Interface *iface = new Interface($3, static_cast<Interface *>($4), $1);
Andreas Hubereb1081f2016-07-28 13:13:24 -0700317
318 // Register interface immediately so it can be referenced inside
319 // definition.
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700320 std::string errorMsg;
Andreas Huber9ed827c2016-08-22 12:31:13 -0700321 if (!ast->addScopedType(iface, &errorMsg)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700322 std::cerr << "ERROR: " << errorMsg << " at " << @3 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700323 YYERROR;
324 }
Andreas Hubereb1081f2016-07-28 13:13:24 -0700325
Andreas Huberc9410c72016-07-28 12:18:40 -0700326 ast->enterScope(iface);
327 }
328 '{' interface_declarations '}' ';'
329 {
330 Interface *iface = static_cast<Interface *>(ast->scope());
331
332 ast->leaveScope();
Andreas Huberc9410c72016-07-28 12:18:40 -0700333 }
334 | type_declarations
335 ;
336
337interface_declarations
338 : /* empty */
339 | interface_declarations type_declaration
340 | interface_declarations method_declaration
341 {
342 Interface *iface = static_cast<Interface *>(ast->scope());
343 iface->addMethod($2);
344 }
345 ;
346
347type_declarations
Andreas Hubera2723d22016-07-29 15:36:07 -0700348 : /* empty */
Andreas Huberc9410c72016-07-28 12:18:40 -0700349 | type_declarations type_declaration
350 ;
351
352type_declaration
353 : named_struct_or_union_declaration ';'
354 | named_enum_declaration ';'
355 | typedef_declaration ';'
Andreas Huberc9410c72016-07-28 12:18:40 -0700356 ;
357
358typedef_declaration
359 : TYPEDEF type IDENTIFIER
360 {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700361 std::string errorMsg;
Andreas Huber39fa7182016-08-19 14:27:33 -0700362 if (!ast->addTypeDef($3, $2, &errorMsg)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700363 std::cerr << "ERROR: " << errorMsg << " at " << @3 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700364 YYERROR;
365 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700366 }
367 ;
368
Yifan Hong52165692016-08-12 18:06:40 -0700369const_expr
Yifan Hong57886972016-08-17 10:42:15 -0700370 : INTEGER { $$ = new ConstantExpression($1, ConstantExpression::kConstExprLiteral); }
Yifan Hongb44a6c82016-09-22 15:50:18 -0700371 | fqname
372 {
373 $$ = new ConstantExpression($1->string().c_str(), ConstantExpression::kConstExprUnknown);
374 }
Yifan Hong52165692016-08-12 18:06:40 -0700375 | const_expr '?' const_expr ':' const_expr
376 {
Yifan Hongb44a6c82016-09-22 15:50:18 -0700377 $$ = new ConstantExpression($1, $3, $5);
Yifan Hong52165692016-08-12 18:06:40 -0700378 }
379 | const_expr LOGICAL_OR const_expr { $$ = new ConstantExpression($1, "||", $3); }
380 | const_expr LOGICAL_AND const_expr { $$ = new ConstantExpression($1, "&&", $3); }
381 | const_expr '|' const_expr { $$ = new ConstantExpression($1, "|" , $3); }
382 | const_expr '^' const_expr { $$ = new ConstantExpression($1, "^" , $3); }
383 | const_expr '&' const_expr { $$ = new ConstantExpression($1, "&" , $3); }
384 | const_expr EQUALITY const_expr { $$ = new ConstantExpression($1, "==", $3); }
385 | const_expr NEQ const_expr { $$ = new ConstantExpression($1, "!=", $3); }
386 | const_expr '<' const_expr { $$ = new ConstantExpression($1, "<" , $3); }
387 | const_expr '>' const_expr { $$ = new ConstantExpression($1, ">" , $3); }
388 | const_expr LEQ const_expr { $$ = new ConstantExpression($1, "<=", $3); }
389 | const_expr GEQ const_expr { $$ = new ConstantExpression($1, ">=", $3); }
390 | const_expr LSHIFT const_expr { $$ = new ConstantExpression($1, "<<", $3); }
391 | const_expr RSHIFT const_expr { $$ = new ConstantExpression($1, ">>", $3); }
392 | const_expr '+' const_expr { $$ = new ConstantExpression($1, "+" , $3); }
393 | const_expr '-' const_expr { $$ = new ConstantExpression($1, "-" , $3); }
394 | const_expr '*' const_expr { $$ = new ConstantExpression($1, "*" , $3); }
395 | const_expr '/' const_expr { $$ = new ConstantExpression($1, "/" , $3); }
396 | const_expr '%' const_expr { $$ = new ConstantExpression($1, "%" , $3); }
397 | '+' const_expr %prec UNARY_PLUS { $$ = new ConstantExpression("+", $2); }
398 | '-' const_expr %prec UNARY_MINUS { $$ = new ConstantExpression("-", $2); }
399 | '!' const_expr { $$ = new ConstantExpression("!", $2); }
400 | '~' const_expr { $$ = new ConstantExpression("~", $2); }
401 | '(' const_expr ')' { $$ = $2; }
402 ;
403
Andreas Huberc9410c72016-07-28 12:18:40 -0700404method_declaration
Andreas Huber3599d922016-08-09 10:42:57 -0700405 : opt_annotations IDENTIFIER '(' typed_vars ')' ';'
Andreas Huberc9410c72016-07-28 12:18:40 -0700406 {
Iliyan Malchev639bff82016-08-13 14:24:11 -0700407 $$ = new Method($2, $4, new std::vector<TypedVar *>, false, $1);
408 }
409 | opt_annotations ONEWAY IDENTIFIER '(' typed_vars ')' ';'
410 {
411 $$ = new Method($3, $5, new std::vector<TypedVar *>, true, $1);
Andreas Huberc9410c72016-07-28 12:18:40 -0700412 }
Andreas Huber3599d922016-08-09 10:42:57 -0700413 | opt_annotations IDENTIFIER '(' typed_vars ')' GENERATES '(' typed_vars ')' ';'
Andreas Huberc9410c72016-07-28 12:18:40 -0700414 {
Iliyan Malchev639bff82016-08-13 14:24:11 -0700415 $$ = new Method($2, $4, $8, false, $1);
Andreas Huberc9410c72016-07-28 12:18:40 -0700416 }
417 ;
418
419typed_vars
420 : /* empty */
421 {
Andreas Huber881227d2016-08-02 14:20:21 -0700422 $$ = new std::vector<TypedVar *>;
Andreas Huberc9410c72016-07-28 12:18:40 -0700423 }
424 | typed_var
425 {
Andreas Huber881227d2016-08-02 14:20:21 -0700426 $$ = new std::vector<TypedVar *>;
Andreas Huberc9410c72016-07-28 12:18:40 -0700427 $$->push_back($1);
428 }
429 | typed_vars ',' typed_var
430 {
431 $$ = $1;
432 $$->push_back($3);
433 }
434 ;
435
436typed_var : type IDENTIFIER { $$ = new TypedVar($2, $1); }
437 ;
438
439
440struct_or_union_keyword
441 : STRUCT { $$ = CompoundType::STYLE_STRUCT; }
442 | UNION { $$ = CompoundType::STYLE_UNION; }
443 ;
444
445named_struct_or_union_declaration
446 : struct_or_union_keyword IDENTIFIER
447 {
Andreas Huber9ed827c2016-08-22 12:31:13 -0700448 CompoundType *container = new CompoundType($1, $2);
Andreas Huberc9410c72016-07-28 12:18:40 -0700449 ast->enterScope(container);
450 }
451 struct_or_union_body
452 {
453 CompoundType *container = static_cast<CompoundType *>(ast->scope());
454
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700455 std::string errorMsg;
456 if (!container->setFields($4, &errorMsg)) {
457 std::cerr << "ERROR: " << errorMsg << " at " << @4 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700458 YYERROR;
459 }
460
Andreas Huberc9410c72016-07-28 12:18:40 -0700461 ast->leaveScope();
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700462
Andreas Huber9ed827c2016-08-22 12:31:13 -0700463 if (!ast->addScopedType(container, &errorMsg)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700464 std::cerr << "ERROR: " << errorMsg << " at " << @2 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700465 YYERROR;
466 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700467 }
468 ;
469
470struct_or_union_declaration
471 : struct_or_union_keyword optIdentifier
472 {
Andreas Huber9ed827c2016-08-22 12:31:13 -0700473 const char *localName = $2;
474 std::string anonName;
475 if (localName == nullptr) {
476 anonName = ast->scope()->pickUniqueAnonymousName();
477 localName = anonName.c_str();
478 }
479
480 CompoundType *container = new CompoundType($1, localName);
Andreas Huberc9410c72016-07-28 12:18:40 -0700481 ast->enterScope(container);
482 }
483 struct_or_union_body
484 {
485 CompoundType *container = static_cast<CompoundType *>(ast->scope());
486
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700487 std::string errorMsg;
488 if (!container->setFields($4, &errorMsg)) {
489 std::cerr << "ERROR: " << errorMsg << " at " << @4 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700490 YYERROR;
491 }
492
Andreas Huberc9410c72016-07-28 12:18:40 -0700493 ast->leaveScope();
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700494
Andreas Huber9ed827c2016-08-22 12:31:13 -0700495 if (!ast->addScopedType(container, &errorMsg)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700496 std::cerr << "ERROR: " << errorMsg << " at " << @2 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700497 YYERROR;
498 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700499
Andreas Huberfd4afab2016-08-03 13:02:57 -0700500 $$ = container->ref();
Andreas Huberc9410c72016-07-28 12:18:40 -0700501 }
502 ;
503
504struct_or_union_body
505 : '{' field_declarations '}' { $$ = $2; }
506 ;
507
508field_declarations
Andreas Huber881227d2016-08-02 14:20:21 -0700509 : /* empty */ { $$ = new std::vector<CompoundField *>; }
Andreas Huberc9410c72016-07-28 12:18:40 -0700510 | field_declarations field_declaration
511 {
512 $$ = $1;
513
514 if ($2 != NULL) {
515 $$->push_back($2);
516 }
517 }
518 ;
519
520field_declaration
521 : type IDENTIFIER ';' { $$ = new CompoundField($2, $1); }
522 | struct_or_union_declaration ';' { $$ = NULL; }
523 | enum_declaration ';' { $$ = NULL; }
524 ;
525
526opt_storage_type
527 : /* empty */ { $$ = NULL; }
Yifan Hongae16eed2016-09-23 13:25:25 -0700528 | ':' fqtype
Andreas Huber8d3ac0c2016-08-04 14:49:23 -0700529 {
530 $$ = $2;
531
532 if ($$ != NULL && !$$->isValidEnumStorageType()) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700533 std::cerr << "ERROR: Invalid enum storage type specified. at "
534 << @2 << "\n";
535
Andreas Huber8d3ac0c2016-08-04 14:49:23 -0700536 YYABORT;
537 }
538 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700539 ;
540
541opt_comma
542 : /* empty */
543 | ','
544 ;
545
546named_enum_declaration
547 : ENUM IDENTIFIER opt_storage_type '{' enum_values opt_comma '}'
548 {
Andreas Huber9ed827c2016-08-22 12:31:13 -0700549 EnumType *enumType = new EnumType($2, $5, $3);
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700550
551 std::string errorMsg;
Andreas Huber9ed827c2016-08-22 12:31:13 -0700552 if (!ast->addScopedType(enumType, &errorMsg)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700553 std::cerr << "ERROR: " << errorMsg << " at " << @2 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700554 YYERROR;
555 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700556 }
557 ;
558
559enum_declaration
560 : ENUM '{' enum_values opt_comma '}'
561 {
Andreas Huber9ed827c2016-08-22 12:31:13 -0700562 std::string anonName = ast->scope()->pickUniqueAnonymousName();
563
564 EnumType *enumType = new EnumType(anonName.c_str(), $3);
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700565
566 std::string errorMsg;
Andreas Huber9ed827c2016-08-22 12:31:13 -0700567 if (!ast->addScopedType(enumType, &errorMsg)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700568 // This should never fail.
569 std::cerr << "ERROR: " << errorMsg << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700570 YYERROR;
571 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700572
Andreas Huberfd4afab2016-08-03 13:02:57 -0700573 $$ = enumType->ref();
Andreas Huberc9410c72016-07-28 12:18:40 -0700574 }
575 | ENUM IDENTIFIER opt_storage_type '{' enum_values opt_comma '}'
576 {
Andreas Huber9ed827c2016-08-22 12:31:13 -0700577 EnumType *enumType = new EnumType($2, $5, $3);
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700578
579 std::string errorMsg;
Andreas Huber9ed827c2016-08-22 12:31:13 -0700580 if (!ast->addScopedType(enumType, &errorMsg)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700581 std::cerr << "ERROR: " << errorMsg << " at " << @2 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700582 YYERROR;
583 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700584
Andreas Huberfd4afab2016-08-03 13:02:57 -0700585 $$ = enumType->ref();
Andreas Huberc9410c72016-07-28 12:18:40 -0700586 }
587 ;
588
589enum_value
590 : IDENTIFIER { $$ = new EnumValue($1); }
Yifan Hong57886972016-08-17 10:42:15 -0700591 | IDENTIFIER '=' const_expr { $$ = new EnumValue($1, $3); }
Andreas Huberc9410c72016-07-28 12:18:40 -0700592 ;
593
594enum_values
595 : /* empty */
596 {
Andreas Huber881227d2016-08-02 14:20:21 -0700597 $$ = new std::vector<EnumValue *>;
Andreas Huberc9410c72016-07-28 12:18:40 -0700598 }
599 | enum_value
600 {
Andreas Huber881227d2016-08-02 14:20:21 -0700601 $$ = new std::vector<EnumValue *>;
Andreas Huberc9410c72016-07-28 12:18:40 -0700602 $$->push_back($1);
603 }
604 | enum_values ',' enum_value
605 {
606 $$ = $1;
607 $$->push_back($3);
608 }
609 ;
610
611type
Yifan Hongae16eed2016-09-23 13:25:25 -0700612 : fqtype { $$ = $1; }
613 | fqtype '[' INTEGER ']'
Andreas Huberb95ea8a2016-08-15 15:35:42 -0700614 {
Andreas Huber295ad302016-08-16 11:35:00 -0700615 if ($1->isBinder()) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700616 std::cerr << "ERROR: Arrays of interface types are not supported."
617 << " at " << @1 << "\n";
Andreas Huber70a59e12016-08-16 12:57:01 -0700618
Andreas Huberb95ea8a2016-08-15 15:35:42 -0700619 YYERROR;
620 }
621
Andreas Huber709b62d2016-09-19 11:21:18 -0700622 char *end;
623 unsigned long size = strtoul($3, &end, 10);
624 CHECK(end > $3 && *end == '\0');
625
626 if ($1->isArray()) {
627 $$ = new ArrayType(static_cast<ArrayType *>($1), size);
628 } else {
629 $$ = new ArrayType($1, size);
630 }
Andreas Huberb95ea8a2016-08-15 15:35:42 -0700631 }
Yifan Hongae16eed2016-09-23 13:25:25 -0700632 | VEC '<' fqtype '>'
Andreas Huberb95ea8a2016-08-15 15:35:42 -0700633 {
Andreas Huber295ad302016-08-16 11:35:00 -0700634 if ($3->isBinder()) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700635 std::cerr << "ERROR: Vectors of interface types are not "
636 << "supported. at " << @3 << "\n";
Andreas Huber70a59e12016-08-16 12:57:01 -0700637
Andreas Huberb95ea8a2016-08-15 15:35:42 -0700638 YYERROR;
639 }
640
641 $$ = new VectorType($3);
642 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700643 | struct_or_union_declaration { $$ = $1; }
644 | enum_declaration { $$ = $1; }
Andreas Huber295ad302016-08-16 11:35:00 -0700645 | INTERFACE { $$ = new GenericBinder; }
Andreas Huberc9410c72016-07-28 12:18:40 -0700646 ;
647
648optIdentifier
649 : /* empty */ { $$ = NULL; }
650 | IDENTIFIER { $$ = $1; }
651 ;
652
653%%
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700654
655#include <android-base/logging.h>
656
657void yy::parser::error(
658 const yy::parser::location_type &where,
659 const std::string &errstr) {
660 std::cerr << "ERROR: " << errstr << " at " << where << "\n";
661}
662