blob: 65dfaee75b93ce11d1b3db8bac90dca88f46c635 [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); }
371 | IDENTIFIER { $$ = new ConstantExpression($1, ConstantExpression::kConstExprUnknown); }
Yifan Hong52165692016-08-12 18:06:40 -0700372 | const_expr '?' const_expr ':' const_expr
373 {
374 $$ = new ConstantExpression($1, $3, $5);
375 }
376 | const_expr LOGICAL_OR const_expr { $$ = new ConstantExpression($1, "||", $3); }
377 | const_expr LOGICAL_AND const_expr { $$ = new ConstantExpression($1, "&&", $3); }
378 | const_expr '|' const_expr { $$ = new ConstantExpression($1, "|" , $3); }
379 | const_expr '^' const_expr { $$ = new ConstantExpression($1, "^" , $3); }
380 | const_expr '&' const_expr { $$ = new ConstantExpression($1, "&" , $3); }
381 | const_expr EQUALITY const_expr { $$ = new ConstantExpression($1, "==", $3); }
382 | const_expr NEQ const_expr { $$ = new ConstantExpression($1, "!=", $3); }
383 | const_expr '<' const_expr { $$ = new ConstantExpression($1, "<" , $3); }
384 | const_expr '>' const_expr { $$ = new ConstantExpression($1, ">" , $3); }
385 | const_expr LEQ const_expr { $$ = new ConstantExpression($1, "<=", $3); }
386 | const_expr GEQ const_expr { $$ = new ConstantExpression($1, ">=", $3); }
387 | const_expr LSHIFT const_expr { $$ = new ConstantExpression($1, "<<", $3); }
388 | const_expr RSHIFT const_expr { $$ = new ConstantExpression($1, ">>", $3); }
389 | const_expr '+' const_expr { $$ = new ConstantExpression($1, "+" , $3); }
390 | const_expr '-' const_expr { $$ = new ConstantExpression($1, "-" , $3); }
391 | const_expr '*' 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 %prec UNARY_PLUS { $$ = new ConstantExpression("+", $2); }
395 | '-' const_expr %prec UNARY_MINUS { $$ = new ConstantExpression("-", $2); }
396 | '!' const_expr { $$ = new ConstantExpression("!", $2); }
397 | '~' const_expr { $$ = new ConstantExpression("~", $2); }
398 | '(' const_expr ')' { $$ = $2; }
399 ;
400
Andreas Huberc9410c72016-07-28 12:18:40 -0700401method_declaration
Andreas Huber3599d922016-08-09 10:42:57 -0700402 : opt_annotations IDENTIFIER '(' typed_vars ')' ';'
Andreas Huberc9410c72016-07-28 12:18:40 -0700403 {
Iliyan Malchev639bff82016-08-13 14:24:11 -0700404 $$ = new Method($2, $4, new std::vector<TypedVar *>, false, $1);
405 }
406 | opt_annotations ONEWAY IDENTIFIER '(' typed_vars ')' ';'
407 {
408 $$ = new Method($3, $5, new std::vector<TypedVar *>, true, $1);
Andreas Huberc9410c72016-07-28 12:18:40 -0700409 }
Andreas Huber3599d922016-08-09 10:42:57 -0700410 | opt_annotations IDENTIFIER '(' typed_vars ')' GENERATES '(' typed_vars ')' ';'
Andreas Huberc9410c72016-07-28 12:18:40 -0700411 {
Iliyan Malchev639bff82016-08-13 14:24:11 -0700412 $$ = new Method($2, $4, $8, false, $1);
Andreas Huberc9410c72016-07-28 12:18:40 -0700413 }
414 ;
415
416typed_vars
417 : /* empty */
418 {
Andreas Huber881227d2016-08-02 14:20:21 -0700419 $$ = new std::vector<TypedVar *>;
Andreas Huberc9410c72016-07-28 12:18:40 -0700420 }
421 | typed_var
422 {
Andreas Huber881227d2016-08-02 14:20:21 -0700423 $$ = new std::vector<TypedVar *>;
Andreas Huberc9410c72016-07-28 12:18:40 -0700424 $$->push_back($1);
425 }
426 | typed_vars ',' typed_var
427 {
428 $$ = $1;
429 $$->push_back($3);
430 }
431 ;
432
433typed_var : type IDENTIFIER { $$ = new TypedVar($2, $1); }
434 ;
435
436
437struct_or_union_keyword
438 : STRUCT { $$ = CompoundType::STYLE_STRUCT; }
439 | UNION { $$ = CompoundType::STYLE_UNION; }
440 ;
441
442named_struct_or_union_declaration
443 : struct_or_union_keyword IDENTIFIER
444 {
Andreas Huber9ed827c2016-08-22 12:31:13 -0700445 CompoundType *container = new CompoundType($1, $2);
Andreas Huberc9410c72016-07-28 12:18:40 -0700446 ast->enterScope(container);
447 }
448 struct_or_union_body
449 {
450 CompoundType *container = static_cast<CompoundType *>(ast->scope());
451
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700452 std::string errorMsg;
453 if (!container->setFields($4, &errorMsg)) {
454 std::cerr << "ERROR: " << errorMsg << " at " << @4 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700455 YYERROR;
456 }
457
Andreas Huberc9410c72016-07-28 12:18:40 -0700458 ast->leaveScope();
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700459
Andreas Huber9ed827c2016-08-22 12:31:13 -0700460 if (!ast->addScopedType(container, &errorMsg)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700461 std::cerr << "ERROR: " << errorMsg << " at " << @2 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700462 YYERROR;
463 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700464 }
465 ;
466
467struct_or_union_declaration
468 : struct_or_union_keyword optIdentifier
469 {
Andreas Huber9ed827c2016-08-22 12:31:13 -0700470 const char *localName = $2;
471 std::string anonName;
472 if (localName == nullptr) {
473 anonName = ast->scope()->pickUniqueAnonymousName();
474 localName = anonName.c_str();
475 }
476
477 CompoundType *container = new CompoundType($1, localName);
Andreas Huberc9410c72016-07-28 12:18:40 -0700478 ast->enterScope(container);
479 }
480 struct_or_union_body
481 {
482 CompoundType *container = static_cast<CompoundType *>(ast->scope());
483
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700484 std::string errorMsg;
485 if (!container->setFields($4, &errorMsg)) {
486 std::cerr << "ERROR: " << errorMsg << " at " << @4 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700487 YYERROR;
488 }
489
Andreas Huberc9410c72016-07-28 12:18:40 -0700490 ast->leaveScope();
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700491
Andreas Huber9ed827c2016-08-22 12:31:13 -0700492 if (!ast->addScopedType(container, &errorMsg)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700493 std::cerr << "ERROR: " << errorMsg << " at " << @2 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700494 YYERROR;
495 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700496
Andreas Huberfd4afab2016-08-03 13:02:57 -0700497 $$ = container->ref();
Andreas Huberc9410c72016-07-28 12:18:40 -0700498 }
499 ;
500
501struct_or_union_body
502 : '{' field_declarations '}' { $$ = $2; }
503 ;
504
505field_declarations
Andreas Huber881227d2016-08-02 14:20:21 -0700506 : /* empty */ { $$ = new std::vector<CompoundField *>; }
Andreas Huberc9410c72016-07-28 12:18:40 -0700507 | field_declarations field_declaration
508 {
509 $$ = $1;
510
511 if ($2 != NULL) {
512 $$->push_back($2);
513 }
514 }
515 ;
516
517field_declaration
518 : type IDENTIFIER ';' { $$ = new CompoundField($2, $1); }
519 | struct_or_union_declaration ';' { $$ = NULL; }
520 | enum_declaration ';' { $$ = NULL; }
521 ;
522
523opt_storage_type
524 : /* empty */ { $$ = NULL; }
Yifan Hongae16eed2016-09-23 13:25:25 -0700525 | ':' fqtype
Andreas Huber8d3ac0c2016-08-04 14:49:23 -0700526 {
527 $$ = $2;
528
529 if ($$ != NULL && !$$->isValidEnumStorageType()) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700530 std::cerr << "ERROR: Invalid enum storage type specified. at "
531 << @2 << "\n";
532
Andreas Huber8d3ac0c2016-08-04 14:49:23 -0700533 YYABORT;
534 }
535 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700536 ;
537
538opt_comma
539 : /* empty */
540 | ','
541 ;
542
543named_enum_declaration
544 : ENUM IDENTIFIER opt_storage_type '{' enum_values opt_comma '}'
545 {
Andreas Huber9ed827c2016-08-22 12:31:13 -0700546 EnumType *enumType = new EnumType($2, $5, $3);
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700547
548 std::string errorMsg;
Andreas Huber9ed827c2016-08-22 12:31:13 -0700549 if (!ast->addScopedType(enumType, &errorMsg)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700550 std::cerr << "ERROR: " << errorMsg << " at " << @2 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700551 YYERROR;
552 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700553 }
554 ;
555
556enum_declaration
557 : ENUM '{' enum_values opt_comma '}'
558 {
Andreas Huber9ed827c2016-08-22 12:31:13 -0700559 std::string anonName = ast->scope()->pickUniqueAnonymousName();
560
561 EnumType *enumType = new EnumType(anonName.c_str(), $3);
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700562
563 std::string errorMsg;
Andreas Huber9ed827c2016-08-22 12:31:13 -0700564 if (!ast->addScopedType(enumType, &errorMsg)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700565 // This should never fail.
566 std::cerr << "ERROR: " << errorMsg << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700567 YYERROR;
568 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700569
Andreas Huberfd4afab2016-08-03 13:02:57 -0700570 $$ = enumType->ref();
Andreas Huberc9410c72016-07-28 12:18:40 -0700571 }
572 | ENUM IDENTIFIER opt_storage_type '{' enum_values opt_comma '}'
573 {
Andreas Huber9ed827c2016-08-22 12:31:13 -0700574 EnumType *enumType = new EnumType($2, $5, $3);
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700575
576 std::string errorMsg;
Andreas Huber9ed827c2016-08-22 12:31:13 -0700577 if (!ast->addScopedType(enumType, &errorMsg)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700578 std::cerr << "ERROR: " << errorMsg << " at " << @2 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700579 YYERROR;
580 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700581
Andreas Huberfd4afab2016-08-03 13:02:57 -0700582 $$ = enumType->ref();
Andreas Huberc9410c72016-07-28 12:18:40 -0700583 }
584 ;
585
586enum_value
587 : IDENTIFIER { $$ = new EnumValue($1); }
Yifan Hong57886972016-08-17 10:42:15 -0700588 | IDENTIFIER '=' const_expr { $$ = new EnumValue($1, $3); }
Andreas Huberc9410c72016-07-28 12:18:40 -0700589 ;
590
591enum_values
592 : /* empty */
593 {
Andreas Huber881227d2016-08-02 14:20:21 -0700594 $$ = new std::vector<EnumValue *>;
Andreas Huberc9410c72016-07-28 12:18:40 -0700595 }
596 | enum_value
597 {
Andreas Huber881227d2016-08-02 14:20:21 -0700598 $$ = new std::vector<EnumValue *>;
Andreas Huberc9410c72016-07-28 12:18:40 -0700599 $$->push_back($1);
600 }
601 | enum_values ',' enum_value
602 {
603 $$ = $1;
604 $$->push_back($3);
605 }
606 ;
607
608type
Yifan Hongae16eed2016-09-23 13:25:25 -0700609 : fqtype { $$ = $1; }
610 | fqtype '[' INTEGER ']'
Andreas Huberb95ea8a2016-08-15 15:35:42 -0700611 {
Andreas Huber295ad302016-08-16 11:35:00 -0700612 if ($1->isBinder()) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700613 std::cerr << "ERROR: Arrays of interface types are not supported."
614 << " at " << @1 << "\n";
Andreas Huber70a59e12016-08-16 12:57:01 -0700615
Andreas Huberb95ea8a2016-08-15 15:35:42 -0700616 YYERROR;
617 }
618
Andreas Huber709b62d2016-09-19 11:21:18 -0700619 char *end;
620 unsigned long size = strtoul($3, &end, 10);
621 CHECK(end > $3 && *end == '\0');
622
623 if ($1->isArray()) {
624 $$ = new ArrayType(static_cast<ArrayType *>($1), size);
625 } else {
626 $$ = new ArrayType($1, size);
627 }
Andreas Huberb95ea8a2016-08-15 15:35:42 -0700628 }
Yifan Hongae16eed2016-09-23 13:25:25 -0700629 | VEC '<' fqtype '>'
Andreas Huberb95ea8a2016-08-15 15:35:42 -0700630 {
Andreas Huber295ad302016-08-16 11:35:00 -0700631 if ($3->isBinder()) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700632 std::cerr << "ERROR: Vectors of interface types are not "
633 << "supported. at " << @3 << "\n";
Andreas Huber70a59e12016-08-16 12:57:01 -0700634
Andreas Huberb95ea8a2016-08-15 15:35:42 -0700635 YYERROR;
636 }
637
638 $$ = new VectorType($3);
639 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700640 | struct_or_union_declaration { $$ = $1; }
641 | enum_declaration { $$ = $1; }
Andreas Huber295ad302016-08-16 11:35:00 -0700642 | INTERFACE { $$ = new GenericBinder; }
Andreas Huberc9410c72016-07-28 12:18:40 -0700643 ;
644
645optIdentifier
646 : /* empty */ { $$ = NULL; }
647 | IDENTIFIER { $$ = $1; }
648 ;
649
650%%
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700651
652#include <android-base/logging.h>
653
654void yy::parser::error(
655 const yy::parser::location_type &where,
656 const std::string &errstr) {
657 std::cerr << "ERROR: " << errstr << " at " << where << "\n";
658}
659