blob: 9ced71faf699766410c6da4d875436a630564409 [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
32#include <stdio.h>
33
34using namespace android;
35
Andreas Huber0d0f9a22016-08-17 10:26:11 -070036extern int yylex(yy::parser::semantic_type *, yy::parser::location_type *, void *);
Andreas Huberc9410c72016-07-28 12:18:40 -070037
38#define scanner ast->scanner()
39
40%}
41
Andreas Huber0d0f9a22016-08-17 10:26:11 -070042%initial-action {
43 // Initialize the initial location.
44 @$.begin.filename = @$.end.filename =
45 const_cast<std::string *>(&ast->getFilename());
46}
47
Andreas Huberc9410c72016-07-28 12:18:40 -070048%parse-param { android::AST *ast }
49%lex-param { void *scanner }
50%pure-parser
Andreas Huber0d0f9a22016-08-17 10:26:11 -070051%skeleton "glr.cc"
Andreas Huberc9410c72016-07-28 12:18:40 -070052
Andreas Huberc9410c72016-07-28 12:18:40 -070053%token<str> ENUM
54%token<str> EXTENDS
Andreas Huber84f89de2016-07-28 15:39:51 -070055%token<str> FQNAME
Andreas Huberc9410c72016-07-28 12:18:40 -070056%token<str> GENERATES
57%token<str> IDENTIFIER
58%token<str> IMPORT
59%token<str> INTEGER
Yifan Hong52165692016-08-12 18:06:40 -070060%token<str> FLOAT
Andreas Huberc9410c72016-07-28 12:18:40 -070061%token<str> INTERFACE
62%token<str> PACKAGE
Andreas Huber84f89de2016-07-28 15:39:51 -070063%token<type> SCALAR
Andreas Huberc9410c72016-07-28 12:18:40 -070064%token<str> STRUCT
65%token<str> STRING_LITERAL
66%token<str> TYPEDEF
67%token<str> UNION
68%token<str> VEC
Iliyan Malchev639bff82016-08-13 14:24:11 -070069%token<void> ONEWAY
Andreas Huberc9410c72016-07-28 12:18:40 -070070
Yifan Hong52165692016-08-12 18:06:40 -070071/* Operator precedence and associativity, as per
72 * http://en.cppreference.com/w/cpp/language/operator_precedence */
73/* Precedence level 15 ternary operator */
74%right '?' ':'
75/* Precedence level 13 - 14, LTR, logical operators*/
76%left LOGICAL_OR
77%left LOGICAL_AND
78/* Precedence level 10 - 12, LTR, bitwise operators*/
79%left '|'
80%left '^'
81%left '&'
82/* Precedence level 9, LTR */
83%left EQUALITY NEQ
84/* Precedence level 8, LTR */
85%left '<' '>' LEQ GEQ
86/* Precedence level 7, LTR */
87%left LSHIFT RSHIFT
88/* Precedence level 6, LTR */
89%left '+' '-'
90/* Precedence level 5, LTR */
91%left '*' '/' '%'
92/* Precedence level 3, RTL; but we have to use %left here */
93%left UNARY_MINUS UNARY_PLUS '!' '~'
94
Andreas Huberc9410c72016-07-28 12:18:40 -070095%type<str> optIdentifier package
Andreas Huber84f89de2016-07-28 15:39:51 -070096%type<type> fqname
Andreas Huberc9410c72016-07-28 12:18:40 -070097
98%type<type> type opt_storage_type
99%type<type> enum_declaration
100%type<type> struct_or_union_declaration
101%type<type> opt_extends
102
103%type<field> field_declaration
104%type<fields> field_declarations struct_or_union_body
Yifan Hong52165692016-08-12 18:06:40 -0700105%type<constantExpression> const_expr
Andreas Huberc9410c72016-07-28 12:18:40 -0700106%type<enumValue> enum_value
107%type<enumValues> enum_values
108%type<typedVars> typed_vars
109%type<typedVar> typed_var
110%type<method> method_declaration
111%type<compoundStyle> struct_or_union_keyword
Andreas Huber3599d922016-08-09 10:42:57 -0700112%type<stringVec> annotation_string_values annotation_value
113%type<annotationParam> annotation_param
114%type<annotationParams> opt_annotation_params annotation_params
115%type<annotation> annotation
116%type<annotations> opt_annotations
Andreas Huberc9410c72016-07-28 12:18:40 -0700117
118%start program
119
120%union {
121 const char *str;
122 android::Type *type;
123 android::CompoundType *compoundType;
124 android::CompoundField *field;
Andreas Huber881227d2016-08-02 14:20:21 -0700125 std::vector<android::CompoundField *> *fields;
Andreas Huberc9410c72016-07-28 12:18:40 -0700126 android::EnumValue *enumValue;
Yifan Hong52165692016-08-12 18:06:40 -0700127 android::ConstantExpression *constantExpression;
Andreas Huber881227d2016-08-02 14:20:21 -0700128 std::vector<android::EnumValue *> *enumValues;
Andreas Huberc9410c72016-07-28 12:18:40 -0700129 android::TypedVar *typedVar;
Andreas Huber881227d2016-08-02 14:20:21 -0700130 std::vector<android::TypedVar *> *typedVars;
Andreas Huberc9410c72016-07-28 12:18:40 -0700131 android::Method *method;
132 android::CompoundType::Style compoundStyle;
Andreas Huber3599d922016-08-09 10:42:57 -0700133 std::vector<std::string> *stringVec;
Steven Morelandd537ab02016-09-12 10:32:01 -0700134 android::AnnotationParam *annotationParam;
135 android::AnnotationParamVector *annotationParams;
Andreas Huber3599d922016-08-09 10:42:57 -0700136 android::Annotation *annotation;
Steven Morelandd537ab02016-09-12 10:32:01 -0700137 std::vector<android::Annotation *> *annotations;
Andreas Huberc9410c72016-07-28 12:18:40 -0700138}
139
140%%
141
Andreas Huber3599d922016-08-09 10:42:57 -0700142opt_annotations
143 : /* empty */
144 {
Steven Morelandd537ab02016-09-12 10:32:01 -0700145 $$ = new std::vector<Annotation *>;
Andreas Huber3599d922016-08-09 10:42:57 -0700146 }
147 | opt_annotations annotation
148 {
149 $$ = $1;
Steven Morelandd537ab02016-09-12 10:32:01 -0700150 $$->push_back($2);
Andreas Huber3599d922016-08-09 10:42:57 -0700151 }
152 ;
153
154annotation
155 : '@' IDENTIFIER opt_annotation_params
156 {
157 $$ = new Annotation($2, $3);
158 }
159 ;
160
161opt_annotation_params
162 : /* empty */
163 {
Steven Morelandd537ab02016-09-12 10:32:01 -0700164 $$ = new AnnotationParamVector;
Andreas Huber3599d922016-08-09 10:42:57 -0700165 }
166 | '(' annotation_params ')'
167 {
168 $$ = $2;
169 }
170 ;
171
172annotation_params
173 : annotation_param
174 {
Steven Morelandd537ab02016-09-12 10:32:01 -0700175 $$ = new AnnotationParamVector;
176 $$->push_back($1);
Andreas Huber3599d922016-08-09 10:42:57 -0700177 }
178 | annotation_params ',' annotation_param
179 {
180 $$ = $1;
Steven Morelandd537ab02016-09-12 10:32:01 -0700181 $$->push_back($3);
Andreas Huber3599d922016-08-09 10:42:57 -0700182 }
183 ;
184
185annotation_param
186 : IDENTIFIER '=' annotation_value
187 {
Steven Morelandd537ab02016-09-12 10:32:01 -0700188 $$ = new AnnotationParam($1, $3);
Andreas Huber3599d922016-08-09 10:42:57 -0700189 }
190 ;
191
192annotation_value
193 : STRING_LITERAL
194 {
195 $$ = new std::vector<std::string>;
196 $$->push_back($1);
197 }
198 | '{' annotation_string_values '}' { $$ = $2; }
199 ;
200
201annotation_string_values
202 : STRING_LITERAL
203 {
204 $$ = new std::vector<std::string>;
205 $$->push_back($1);
206 }
207 | annotation_string_values ',' STRING_LITERAL
208 {
209 $$ = $1;
210 $$->push_back($3);
211 }
212 ;
213
Andreas Huberc9410c72016-07-28 12:18:40 -0700214program
Andreas Huberda51b8e2016-07-28 16:00:57 -0700215 : package imports body
Andreas Huber84f89de2016-07-28 15:39:51 -0700216 ;
217
218fqname
219 : FQNAME
220 {
221 $$ = ast->lookupType($1);
222 if ($$ == NULL) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700223 std::cerr << "ERROR: Failed to lookup type '" << $1 << "' at "
224 << @1
225 << "\n";
226
Andreas Huber84f89de2016-07-28 15:39:51 -0700227 YYERROR;
228 }
229 }
230 | IDENTIFIER
231 {
232 $$ = ast->lookupType($1);
233 if ($$ == NULL) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700234 std::cerr << "Failed to lookup type '" << $1 << "' at " << @1
235 << "\n";
236
Andreas Huber84f89de2016-07-28 15:39:51 -0700237 YYERROR;
238 }
239 }
240 | SCALAR
241 ;
Andreas Huberc9410c72016-07-28 12:18:40 -0700242
243package
Andreas Huber84f89de2016-07-28 15:39:51 -0700244 : PACKAGE FQNAME ';'
Andreas Hubereb1081f2016-07-28 13:13:24 -0700245 {
Andreas Huber84f89de2016-07-28 15:39:51 -0700246 if (!ast->setPackage($2)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700247 std::cerr << "ERROR: Malformed package identifier '"
248 << $2
249 << "' at "
250 << @2
251 << "\n";
252
Andreas Huber84f89de2016-07-28 15:39:51 -0700253 YYERROR;
254 }
Andreas Hubereb1081f2016-07-28 13:13:24 -0700255 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700256
Andreas Huberc9410c72016-07-28 12:18:40 -0700257imports
258 : /* empty */
Andreas Huber84f89de2016-07-28 15:39:51 -0700259 | imports IMPORT FQNAME ';'
Andreas Hubereb1081f2016-07-28 13:13:24 -0700260 {
Andreas Huber68f24592016-07-29 14:53:48 -0700261 if (!ast->addImport($3)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700262 std::cerr << "ERROR: Unable to import '" << $3 << "' at " << @3
263 << "\n";
Andreas Huber68f24592016-07-29 14:53:48 -0700264
265 YYERROR;
266 }
Andreas Hubereb1081f2016-07-28 13:13:24 -0700267 }
Andreas Huber5345ec22016-07-29 13:33:27 -0700268 | imports IMPORT IDENTIFIER ';'
269 {
Andreas Huber68f24592016-07-29 14:53:48 -0700270 if (!ast->addImport($3)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700271 std::cerr << "ERROR: Unable to import '" << $3 << "' at " << @3
272 << "\n";
Andreas Huber68f24592016-07-29 14:53:48 -0700273
274 YYERROR;
275 }
Andreas Huber5345ec22016-07-29 13:33:27 -0700276 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700277 ;
278
279opt_extends
280 : /* empty */ { $$ = NULL; }
Andreas Huber84f89de2016-07-28 15:39:51 -0700281 | EXTENDS fqname { $$ = $2; }
Andreas Huberc9410c72016-07-28 12:18:40 -0700282
283body
Zhuoyao Zhangba7e6e92016-08-10 12:19:02 -0700284 : opt_annotations INTERFACE IDENTIFIER opt_extends
Andreas Huberc9410c72016-07-28 12:18:40 -0700285 {
Zhuoyao Zhangba7e6e92016-08-10 12:19:02 -0700286 if ($4 != NULL && !$4->isInterface()) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700287 std::cerr << "ERROR: You can only extend interfaces. at" << @4
288 << "\n";
289
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700290 YYERROR;
291 }
292
Andreas Huber991b8642016-08-15 16:40:44 -0700293 if ($3[0] != 'I') {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700294 std::cerr << "ERROR: All interface names must start with an 'I' "
295 << "prefix. at " << @3 << "\n";
Andreas Huber991b8642016-08-15 16:40:44 -0700296
297 YYERROR;
298 }
299
Andreas Huber9ed827c2016-08-22 12:31:13 -0700300 Interface *iface = new Interface($3, static_cast<Interface *>($4), $1);
Andreas Hubereb1081f2016-07-28 13:13:24 -0700301
302 // Register interface immediately so it can be referenced inside
303 // definition.
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700304 std::string errorMsg;
Andreas Huber9ed827c2016-08-22 12:31:13 -0700305 if (!ast->addScopedType(iface, &errorMsg)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700306 std::cerr << "ERROR: " << errorMsg << " at " << @3 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700307 YYERROR;
308 }
Andreas Hubereb1081f2016-07-28 13:13:24 -0700309
Andreas Huberc9410c72016-07-28 12:18:40 -0700310 ast->enterScope(iface);
311 }
312 '{' interface_declarations '}' ';'
313 {
314 Interface *iface = static_cast<Interface *>(ast->scope());
315
316 ast->leaveScope();
Andreas Huberc9410c72016-07-28 12:18:40 -0700317 }
318 | type_declarations
319 ;
320
321interface_declarations
322 : /* empty */
323 | interface_declarations type_declaration
324 | interface_declarations method_declaration
325 {
326 Interface *iface = static_cast<Interface *>(ast->scope());
327 iface->addMethod($2);
328 }
329 ;
330
331type_declarations
Andreas Hubera2723d22016-07-29 15:36:07 -0700332 : /* empty */
Andreas Huberc9410c72016-07-28 12:18:40 -0700333 | type_declarations type_declaration
334 ;
335
336type_declaration
337 : named_struct_or_union_declaration ';'
338 | named_enum_declaration ';'
339 | typedef_declaration ';'
Andreas Huberc9410c72016-07-28 12:18:40 -0700340 ;
341
342typedef_declaration
343 : TYPEDEF type IDENTIFIER
344 {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700345 std::string errorMsg;
Andreas Huber39fa7182016-08-19 14:27:33 -0700346 if (!ast->addTypeDef($3, $2, &errorMsg)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700347 std::cerr << "ERROR: " << errorMsg << " at " << @3 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700348 YYERROR;
349 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700350 }
351 ;
352
Yifan Hong52165692016-08-12 18:06:40 -0700353const_expr
Yifan Hong57886972016-08-17 10:42:15 -0700354 : INTEGER { $$ = new ConstantExpression($1, ConstantExpression::kConstExprLiteral); }
355 | IDENTIFIER { $$ = new ConstantExpression($1, ConstantExpression::kConstExprUnknown); }
Yifan Hong52165692016-08-12 18:06:40 -0700356 | const_expr '?' const_expr ':' const_expr
357 {
358 $$ = new ConstantExpression($1, $3, $5);
359 }
360 | const_expr LOGICAL_OR const_expr { $$ = new ConstantExpression($1, "||", $3); }
361 | const_expr LOGICAL_AND const_expr { $$ = new ConstantExpression($1, "&&", $3); }
362 | const_expr '|' const_expr { $$ = new ConstantExpression($1, "|" , $3); }
363 | const_expr '^' const_expr { $$ = new ConstantExpression($1, "^" , $3); }
364 | const_expr '&' const_expr { $$ = new ConstantExpression($1, "&" , $3); }
365 | const_expr EQUALITY const_expr { $$ = new ConstantExpression($1, "==", $3); }
366 | const_expr NEQ const_expr { $$ = new ConstantExpression($1, "!=", $3); }
367 | const_expr '<' const_expr { $$ = new ConstantExpression($1, "<" , $3); }
368 | const_expr '>' const_expr { $$ = new ConstantExpression($1, ">" , $3); }
369 | const_expr LEQ const_expr { $$ = new ConstantExpression($1, "<=", $3); }
370 | const_expr GEQ const_expr { $$ = new ConstantExpression($1, ">=", $3); }
371 | const_expr LSHIFT const_expr { $$ = new ConstantExpression($1, "<<", $3); }
372 | const_expr RSHIFT const_expr { $$ = new ConstantExpression($1, ">>", $3); }
373 | const_expr '+' const_expr { $$ = new ConstantExpression($1, "+" , $3); }
374 | const_expr '-' const_expr { $$ = new ConstantExpression($1, "-" , $3); }
375 | const_expr '*' const_expr { $$ = new ConstantExpression($1, "*" , $3); }
376 | const_expr '/' const_expr { $$ = new ConstantExpression($1, "/" , $3); }
377 | const_expr '%' const_expr { $$ = new ConstantExpression($1, "%" , $3); }
378 | '+' const_expr %prec UNARY_PLUS { $$ = new ConstantExpression("+", $2); }
379 | '-' const_expr %prec UNARY_MINUS { $$ = new ConstantExpression("-", $2); }
380 | '!' const_expr { $$ = new ConstantExpression("!", $2); }
381 | '~' const_expr { $$ = new ConstantExpression("~", $2); }
382 | '(' const_expr ')' { $$ = $2; }
383 ;
384
Andreas Huberc9410c72016-07-28 12:18:40 -0700385method_declaration
Andreas Huber3599d922016-08-09 10:42:57 -0700386 : opt_annotations IDENTIFIER '(' typed_vars ')' ';'
Andreas Huberc9410c72016-07-28 12:18:40 -0700387 {
Iliyan Malchev639bff82016-08-13 14:24:11 -0700388 $$ = new Method($2, $4, new std::vector<TypedVar *>, false, $1);
389 }
390 | opt_annotations ONEWAY IDENTIFIER '(' typed_vars ')' ';'
391 {
392 $$ = new Method($3, $5, new std::vector<TypedVar *>, true, $1);
Andreas Huberc9410c72016-07-28 12:18:40 -0700393 }
Andreas Huber3599d922016-08-09 10:42:57 -0700394 | opt_annotations IDENTIFIER '(' typed_vars ')' GENERATES '(' typed_vars ')' ';'
Andreas Huberc9410c72016-07-28 12:18:40 -0700395 {
Iliyan Malchev639bff82016-08-13 14:24:11 -0700396 $$ = new Method($2, $4, $8, false, $1);
Andreas Huberc9410c72016-07-28 12:18:40 -0700397 }
398 ;
399
400typed_vars
401 : /* empty */
402 {
Andreas Huber881227d2016-08-02 14:20:21 -0700403 $$ = new std::vector<TypedVar *>;
Andreas Huberc9410c72016-07-28 12:18:40 -0700404 }
405 | typed_var
406 {
Andreas Huber881227d2016-08-02 14:20:21 -0700407 $$ = new std::vector<TypedVar *>;
Andreas Huberc9410c72016-07-28 12:18:40 -0700408 $$->push_back($1);
409 }
410 | typed_vars ',' typed_var
411 {
412 $$ = $1;
413 $$->push_back($3);
414 }
415 ;
416
417typed_var : type IDENTIFIER { $$ = new TypedVar($2, $1); }
418 ;
419
420
421struct_or_union_keyword
422 : STRUCT { $$ = CompoundType::STYLE_STRUCT; }
423 | UNION { $$ = CompoundType::STYLE_UNION; }
424 ;
425
426named_struct_or_union_declaration
427 : struct_or_union_keyword IDENTIFIER
428 {
Andreas Huber9ed827c2016-08-22 12:31:13 -0700429 CompoundType *container = new CompoundType($1, $2);
Andreas Huberc9410c72016-07-28 12:18:40 -0700430 ast->enterScope(container);
431 }
432 struct_or_union_body
433 {
434 CompoundType *container = static_cast<CompoundType *>(ast->scope());
435
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700436 std::string errorMsg;
437 if (!container->setFields($4, &errorMsg)) {
438 std::cerr << "ERROR: " << errorMsg << " at " << @4 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700439 YYERROR;
440 }
441
Andreas Huberc9410c72016-07-28 12:18:40 -0700442 ast->leaveScope();
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700443
Andreas Huber9ed827c2016-08-22 12:31:13 -0700444 if (!ast->addScopedType(container, &errorMsg)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700445 std::cerr << "ERROR: " << errorMsg << " at " << @2 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700446 YYERROR;
447 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700448 }
449 ;
450
451struct_or_union_declaration
452 : struct_or_union_keyword optIdentifier
453 {
Andreas Huber9ed827c2016-08-22 12:31:13 -0700454 const char *localName = $2;
455 std::string anonName;
456 if (localName == nullptr) {
457 anonName = ast->scope()->pickUniqueAnonymousName();
458 localName = anonName.c_str();
459 }
460
461 CompoundType *container = new CompoundType($1, localName);
Andreas Huberc9410c72016-07-28 12:18:40 -0700462 ast->enterScope(container);
463 }
464 struct_or_union_body
465 {
466 CompoundType *container = static_cast<CompoundType *>(ast->scope());
467
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700468 std::string errorMsg;
469 if (!container->setFields($4, &errorMsg)) {
470 std::cerr << "ERROR: " << errorMsg << " at " << @4 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700471 YYERROR;
472 }
473
Andreas Huberc9410c72016-07-28 12:18:40 -0700474 ast->leaveScope();
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700475
Andreas Huber9ed827c2016-08-22 12:31:13 -0700476 if (!ast->addScopedType(container, &errorMsg)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700477 std::cerr << "ERROR: " << errorMsg << " at " << @2 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700478 YYERROR;
479 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700480
Andreas Huberfd4afab2016-08-03 13:02:57 -0700481 $$ = container->ref();
Andreas Huberc9410c72016-07-28 12:18:40 -0700482 }
483 ;
484
485struct_or_union_body
486 : '{' field_declarations '}' { $$ = $2; }
487 ;
488
489field_declarations
Andreas Huber881227d2016-08-02 14:20:21 -0700490 : /* empty */ { $$ = new std::vector<CompoundField *>; }
Andreas Huberc9410c72016-07-28 12:18:40 -0700491 | field_declarations field_declaration
492 {
493 $$ = $1;
494
495 if ($2 != NULL) {
496 $$->push_back($2);
497 }
498 }
499 ;
500
501field_declaration
502 : type IDENTIFIER ';' { $$ = new CompoundField($2, $1); }
503 | struct_or_union_declaration ';' { $$ = NULL; }
504 | enum_declaration ';' { $$ = NULL; }
505 ;
506
507opt_storage_type
508 : /* empty */ { $$ = NULL; }
Andreas Huber8d3ac0c2016-08-04 14:49:23 -0700509 | ':' fqname
510 {
511 $$ = $2;
512
513 if ($$ != NULL && !$$->isValidEnumStorageType()) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700514 std::cerr << "ERROR: Invalid enum storage type specified. at "
515 << @2 << "\n";
516
Andreas Huber8d3ac0c2016-08-04 14:49:23 -0700517 YYABORT;
518 }
519 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700520 ;
521
522opt_comma
523 : /* empty */
524 | ','
525 ;
526
527named_enum_declaration
528 : ENUM IDENTIFIER opt_storage_type '{' enum_values opt_comma '}'
529 {
Andreas Huber9ed827c2016-08-22 12:31:13 -0700530 EnumType *enumType = new EnumType($2, $5, $3);
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700531
532 std::string errorMsg;
Andreas Huber9ed827c2016-08-22 12:31:13 -0700533 if (!ast->addScopedType(enumType, &errorMsg)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700534 std::cerr << "ERROR: " << errorMsg << " at " << @2 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700535 YYERROR;
536 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700537 }
538 ;
539
540enum_declaration
541 : ENUM '{' enum_values opt_comma '}'
542 {
Andreas Huber9ed827c2016-08-22 12:31:13 -0700543 std::string anonName = ast->scope()->pickUniqueAnonymousName();
544
545 EnumType *enumType = new EnumType(anonName.c_str(), $3);
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700546
547 std::string errorMsg;
Andreas Huber9ed827c2016-08-22 12:31:13 -0700548 if (!ast->addScopedType(enumType, &errorMsg)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700549 // This should never fail.
550 std::cerr << "ERROR: " << errorMsg << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700551 YYERROR;
552 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700553
Andreas Huberfd4afab2016-08-03 13:02:57 -0700554 $$ = enumType->ref();
Andreas Huberc9410c72016-07-28 12:18:40 -0700555 }
556 | ENUM IDENTIFIER opt_storage_type '{' enum_values opt_comma '}'
557 {
Andreas Huber9ed827c2016-08-22 12:31:13 -0700558 EnumType *enumType = new EnumType($2, $5, $3);
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700559
560 std::string errorMsg;
Andreas Huber9ed827c2016-08-22 12:31:13 -0700561 if (!ast->addScopedType(enumType, &errorMsg)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700562 std::cerr << "ERROR: " << errorMsg << " at " << @2 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700563 YYERROR;
564 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700565
Andreas Huberfd4afab2016-08-03 13:02:57 -0700566 $$ = enumType->ref();
Andreas Huberc9410c72016-07-28 12:18:40 -0700567 }
568 ;
569
570enum_value
571 : IDENTIFIER { $$ = new EnumValue($1); }
Yifan Hong57886972016-08-17 10:42:15 -0700572 | IDENTIFIER '=' const_expr { $$ = new EnumValue($1, $3); }
Andreas Huberc9410c72016-07-28 12:18:40 -0700573 ;
574
575enum_values
576 : /* empty */
577 {
Andreas Huber881227d2016-08-02 14:20:21 -0700578 $$ = new std::vector<EnumValue *>;
Andreas Huberc9410c72016-07-28 12:18:40 -0700579 }
580 | enum_value
581 {
Andreas Huber881227d2016-08-02 14:20:21 -0700582 $$ = new std::vector<EnumValue *>;
Andreas Huberc9410c72016-07-28 12:18:40 -0700583 $$->push_back($1);
584 }
585 | enum_values ',' enum_value
586 {
587 $$ = $1;
588 $$->push_back($3);
589 }
590 ;
591
592type
Andreas Huber84f89de2016-07-28 15:39:51 -0700593 : fqname { $$ = $1; }
Andreas Huberb95ea8a2016-08-15 15:35:42 -0700594 | fqname '[' INTEGER ']'
595 {
Andreas Huber295ad302016-08-16 11:35:00 -0700596 if ($1->isBinder()) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700597 std::cerr << "ERROR: Arrays of interface types are not supported."
598 << " at " << @1 << "\n";
Andreas Huber70a59e12016-08-16 12:57:01 -0700599
Andreas Huberb95ea8a2016-08-15 15:35:42 -0700600 YYERROR;
601 }
602
603 $$ = new ArrayType($1, $3);
604 }
605 | VEC '<' fqname '>'
606 {
Andreas Huber295ad302016-08-16 11:35:00 -0700607 if ($3->isBinder()) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700608 std::cerr << "ERROR: Vectors of interface types are not "
609 << "supported. at " << @3 << "\n";
Andreas Huber70a59e12016-08-16 12:57:01 -0700610
Andreas Huberb95ea8a2016-08-15 15:35:42 -0700611 YYERROR;
612 }
613
614 $$ = new VectorType($3);
615 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700616 | struct_or_union_declaration { $$ = $1; }
617 | enum_declaration { $$ = $1; }
Andreas Huber295ad302016-08-16 11:35:00 -0700618 | INTERFACE { $$ = new GenericBinder; }
Andreas Huberc9410c72016-07-28 12:18:40 -0700619 ;
620
621optIdentifier
622 : /* empty */ { $$ = NULL; }
623 | IDENTIFIER { $$ = $1; }
624 ;
625
626%%
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700627
628#include <android-base/logging.h>
629
630void yy::parser::error(
631 const yy::parser::location_type &where,
632 const std::string &errstr) {
633 std::cerr << "ERROR: " << errstr << " at " << where << "\n";
634}
635