blob: 4da811d0241fcffaa3bbc203b63adbd7bb96f821 [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>
Andreas Huber84f89de2016-07-28 15:39:51 -070033#include <utils/String8.h>
Andreas Huberc9410c72016-07-28 12:18:40 -070034
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
Andreas Huber84f89de2016-07-28 15:39:51 -070097%type<type> fqname
Andreas Huberc9410c72016-07-28 12:18:40 -070098
99%type<type> type opt_storage_type
100%type<type> enum_declaration
101%type<type> struct_or_union_declaration
102%type<type> opt_extends
103
104%type<field> field_declaration
105%type<fields> field_declarations struct_or_union_body
Yifan Hong52165692016-08-12 18:06:40 -0700106%type<constantExpression> const_expr
Andreas Huberc9410c72016-07-28 12:18:40 -0700107%type<enumValue> enum_value
108%type<enumValues> enum_values
109%type<typedVars> typed_vars
110%type<typedVar> typed_var
111%type<method> method_declaration
112%type<compoundStyle> struct_or_union_keyword
Andreas Huber3599d922016-08-09 10:42:57 -0700113%type<stringVec> annotation_string_values annotation_value
114%type<annotationParam> annotation_param
115%type<annotationParams> opt_annotation_params annotation_params
116%type<annotation> annotation
117%type<annotations> opt_annotations
Andreas Huberc9410c72016-07-28 12:18:40 -0700118
119%start program
120
121%union {
122 const char *str;
123 android::Type *type;
124 android::CompoundType *compoundType;
125 android::CompoundField *field;
Andreas Huber881227d2016-08-02 14:20:21 -0700126 std::vector<android::CompoundField *> *fields;
Andreas Huberc9410c72016-07-28 12:18:40 -0700127 android::EnumValue *enumValue;
Yifan Hong52165692016-08-12 18:06:40 -0700128 android::ConstantExpression *constantExpression;
Andreas Huber881227d2016-08-02 14:20:21 -0700129 std::vector<android::EnumValue *> *enumValues;
Andreas Huberc9410c72016-07-28 12:18:40 -0700130 android::TypedVar *typedVar;
Andreas Huber881227d2016-08-02 14:20:21 -0700131 std::vector<android::TypedVar *> *typedVars;
Andreas Huberc9410c72016-07-28 12:18:40 -0700132 android::Method *method;
133 android::CompoundType::Style compoundStyle;
Andreas Huber3599d922016-08-09 10:42:57 -0700134 std::vector<std::string> *stringVec;
135 std::pair<std::string, std::vector<std::string> *> *annotationParam;
Zhuoyao Zhang5158db42016-08-10 10:25:20 -0700136 android::DefaultKeyedVector<std::string, std::vector<std::string> *> *annotationParams;
Andreas Huber3599d922016-08-09 10:42:57 -0700137 android::Annotation *annotation;
Zhuoyao Zhang5158db42016-08-10 10:25:20 -0700138 android::DefaultKeyedVector<std::string, android::Annotation *> *annotations;
Andreas Huberc9410c72016-07-28 12:18:40 -0700139}
140
141%%
142
Andreas Huber3599d922016-08-09 10:42:57 -0700143opt_annotations
144 : /* empty */
145 {
Zhuoyao Zhang5158db42016-08-10 10:25:20 -0700146 $$ = new DefaultKeyedVector<std::string, Annotation *>;
Andreas Huber3599d922016-08-09 10:42:57 -0700147 }
148 | opt_annotations annotation
149 {
150 $$ = $1;
151 $$->add($2->name(), $2);
152 }
153 ;
154
155annotation
156 : '@' IDENTIFIER opt_annotation_params
157 {
158 $$ = new Annotation($2, $3);
159 }
160 ;
161
162opt_annotation_params
163 : /* empty */
164 {
Zhuoyao Zhang5158db42016-08-10 10:25:20 -0700165 $$ = new DefaultKeyedVector<std::string, std::vector<std::string> *>;
Andreas Huber3599d922016-08-09 10:42:57 -0700166 }
167 | '(' annotation_params ')'
168 {
169 $$ = $2;
170 }
171 ;
172
173annotation_params
174 : annotation_param
175 {
Zhuoyao Zhang5158db42016-08-10 10:25:20 -0700176 $$ = new DefaultKeyedVector<std::string, std::vector<std::string> *>;
Andreas Huber3599d922016-08-09 10:42:57 -0700177 $$->add($1->first, $1->second);
178 }
179 | annotation_params ',' annotation_param
180 {
181 $$ = $1;
182 $$->add($3->first, $3->second);
183 }
184 ;
185
186annotation_param
187 : IDENTIFIER '=' annotation_value
188 {
189 $$ = new std::pair<std::string, std::vector<std::string> *>($1, $3);
190 }
191 ;
192
193annotation_value
194 : STRING_LITERAL
195 {
196 $$ = new std::vector<std::string>;
197 $$->push_back($1);
198 }
199 | '{' annotation_string_values '}' { $$ = $2; }
200 ;
201
202annotation_string_values
203 : STRING_LITERAL
204 {
205 $$ = new std::vector<std::string>;
206 $$->push_back($1);
207 }
208 | annotation_string_values ',' STRING_LITERAL
209 {
210 $$ = $1;
211 $$->push_back($3);
212 }
213 ;
214
Andreas Huberc9410c72016-07-28 12:18:40 -0700215program
Andreas Huberda51b8e2016-07-28 16:00:57 -0700216 : package imports body
Andreas Huber84f89de2016-07-28 15:39:51 -0700217 ;
218
219fqname
220 : FQNAME
221 {
222 $$ = ast->lookupType($1);
223 if ($$ == NULL) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700224 std::cerr << "ERROR: Failed to lookup type '" << $1 << "' at "
225 << @1
226 << "\n";
227
Andreas Huber84f89de2016-07-28 15:39:51 -0700228 YYERROR;
229 }
230 }
231 | IDENTIFIER
232 {
233 $$ = ast->lookupType($1);
234 if ($$ == NULL) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700235 std::cerr << "Failed to lookup type '" << $1 << "' at " << @1
236 << "\n";
237
Andreas Huber84f89de2016-07-28 15:39:51 -0700238 YYERROR;
239 }
240 }
241 | SCALAR
242 ;
Andreas Huberc9410c72016-07-28 12:18:40 -0700243
244package
Andreas Huber84f89de2016-07-28 15:39:51 -0700245 : PACKAGE FQNAME ';'
Andreas Hubereb1081f2016-07-28 13:13:24 -0700246 {
Andreas Huber84f89de2016-07-28 15:39:51 -0700247 if (!ast->setPackage($2)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700248 std::cerr << "ERROR: Malformed package identifier '"
249 << $2
250 << "' at "
251 << @2
252 << "\n";
253
Andreas Huber84f89de2016-07-28 15:39:51 -0700254 YYERROR;
255 }
Andreas Hubereb1081f2016-07-28 13:13:24 -0700256 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700257
Andreas Huberc9410c72016-07-28 12:18:40 -0700258imports
259 : /* empty */
Andreas Huber84f89de2016-07-28 15:39:51 -0700260 | imports IMPORT FQNAME ';'
Andreas Hubereb1081f2016-07-28 13:13:24 -0700261 {
Andreas Huber68f24592016-07-29 14:53:48 -0700262 if (!ast->addImport($3)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700263 std::cerr << "ERROR: Unable to import '" << $3 << "' at " << @3
264 << "\n";
Andreas Huber68f24592016-07-29 14:53:48 -0700265
266 YYERROR;
267 }
Andreas Hubereb1081f2016-07-28 13:13:24 -0700268 }
Andreas Huber5345ec22016-07-29 13:33:27 -0700269 | imports IMPORT IDENTIFIER ';'
270 {
Andreas Huber68f24592016-07-29 14:53:48 -0700271 if (!ast->addImport($3)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700272 std::cerr << "ERROR: Unable to import '" << $3 << "' at " << @3
273 << "\n";
Andreas Huber68f24592016-07-29 14:53:48 -0700274
275 YYERROR;
276 }
Andreas Huber5345ec22016-07-29 13:33:27 -0700277 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700278 ;
279
280opt_extends
281 : /* empty */ { $$ = NULL; }
Andreas Huber84f89de2016-07-28 15:39:51 -0700282 | EXTENDS fqname { $$ = $2; }
Andreas Huberc9410c72016-07-28 12:18:40 -0700283
284body
Zhuoyao Zhangba7e6e92016-08-10 12:19:02 -0700285 : opt_annotations INTERFACE IDENTIFIER opt_extends
Andreas Huberc9410c72016-07-28 12:18:40 -0700286 {
Zhuoyao Zhangba7e6e92016-08-10 12:19:02 -0700287 if ($4 != NULL && !$4->isInterface()) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700288 std::cerr << "ERROR: You can only extend interfaces. at" << @4
289 << "\n";
290
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700291 YYERROR;
292 }
293
Andreas Huber991b8642016-08-15 16:40:44 -0700294 if ($3[0] != 'I') {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700295 std::cerr << "ERROR: All interface names must start with an 'I' "
296 << "prefix. at " << @3 << "\n";
Andreas Huber991b8642016-08-15 16:40:44 -0700297
298 YYERROR;
299 }
300
Andreas Huber9ed827c2016-08-22 12:31:13 -0700301 Interface *iface = new Interface($3, static_cast<Interface *>($4), $1);
Andreas Hubereb1081f2016-07-28 13:13:24 -0700302
303 // Register interface immediately so it can be referenced inside
304 // definition.
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700305 std::string errorMsg;
Andreas Huber9ed827c2016-08-22 12:31:13 -0700306 if (!ast->addScopedType(iface, &errorMsg)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700307 std::cerr << "ERROR: " << errorMsg << " at " << @3 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700308 YYERROR;
309 }
Andreas Hubereb1081f2016-07-28 13:13:24 -0700310
Andreas Huberc9410c72016-07-28 12:18:40 -0700311 ast->enterScope(iface);
312 }
313 '{' interface_declarations '}' ';'
314 {
315 Interface *iface = static_cast<Interface *>(ast->scope());
316
317 ast->leaveScope();
Andreas Huberc9410c72016-07-28 12:18:40 -0700318 }
319 | type_declarations
320 ;
321
322interface_declarations
323 : /* empty */
324 | interface_declarations type_declaration
325 | interface_declarations method_declaration
326 {
327 Interface *iface = static_cast<Interface *>(ast->scope());
328 iface->addMethod($2);
329 }
330 ;
331
332type_declarations
Andreas Hubera2723d22016-07-29 15:36:07 -0700333 : /* empty */
Andreas Huberc9410c72016-07-28 12:18:40 -0700334 | type_declarations type_declaration
335 ;
336
337type_declaration
338 : named_struct_or_union_declaration ';'
339 | named_enum_declaration ';'
340 | typedef_declaration ';'
Andreas Huberc9410c72016-07-28 12:18:40 -0700341 ;
342
343typedef_declaration
344 : TYPEDEF type IDENTIFIER
345 {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700346 std::string errorMsg;
Andreas Huber39fa7182016-08-19 14:27:33 -0700347 if (!ast->addTypeDef($3, $2, &errorMsg)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700348 std::cerr << "ERROR: " << errorMsg << " at " << @3 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700349 YYERROR;
350 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700351 }
352 ;
353
Yifan Hong52165692016-08-12 18:06:40 -0700354const_expr
355 : INTEGER { $$ = new ConstantExpression($1); }
356 | IDENTIFIER { $$ = new ConstantExpression($1); }
357 | const_expr '?' const_expr ':' const_expr
358 {
359 $$ = new ConstantExpression($1, $3, $5);
360 }
361 | const_expr LOGICAL_OR const_expr { $$ = new ConstantExpression($1, "||", $3); }
362 | const_expr LOGICAL_AND 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 '&' const_expr { $$ = new ConstantExpression($1, "&" , $3); }
366 | const_expr EQUALITY const_expr { $$ = new ConstantExpression($1, "==", $3); }
367 | const_expr NEQ const_expr { $$ = new ConstantExpression($1, "!=", $3); }
368 | const_expr '<' const_expr { $$ = new ConstantExpression($1, "<" , $3); }
369 | const_expr '>' const_expr { $$ = new ConstantExpression($1, ">" , $3); }
370 | const_expr LEQ const_expr { $$ = new ConstantExpression($1, "<=", $3); }
371 | const_expr GEQ const_expr { $$ = new ConstantExpression($1, ">=", $3); }
372 | const_expr LSHIFT const_expr { $$ = new ConstantExpression($1, "<<", $3); }
373 | const_expr RSHIFT 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 '%' const_expr { $$ = new ConstantExpression($1, "%" , $3); }
379 | '+' const_expr %prec UNARY_PLUS { $$ = new ConstantExpression("+", $2); }
380 | '-' const_expr %prec UNARY_MINUS { $$ = new ConstantExpression("-", $2); }
381 | '!' const_expr { $$ = new ConstantExpression("!", $2); }
382 | '~' const_expr { $$ = new ConstantExpression("~", $2); }
383 | '(' const_expr ')' { $$ = $2; }
384 ;
385
Andreas Huberc9410c72016-07-28 12:18:40 -0700386method_declaration
Andreas Huber3599d922016-08-09 10:42:57 -0700387 : opt_annotations IDENTIFIER '(' typed_vars ')' ';'
Andreas Huberc9410c72016-07-28 12:18:40 -0700388 {
Iliyan Malchev639bff82016-08-13 14:24:11 -0700389 $$ = new Method($2, $4, new std::vector<TypedVar *>, false, $1);
390 }
391 | opt_annotations ONEWAY IDENTIFIER '(' typed_vars ')' ';'
392 {
393 $$ = new Method($3, $5, new std::vector<TypedVar *>, true, $1);
Andreas Huberc9410c72016-07-28 12:18:40 -0700394 }
Andreas Huber3599d922016-08-09 10:42:57 -0700395 | opt_annotations IDENTIFIER '(' typed_vars ')' GENERATES '(' typed_vars ')' ';'
Andreas Huberc9410c72016-07-28 12:18:40 -0700396 {
Iliyan Malchev639bff82016-08-13 14:24:11 -0700397 $$ = new Method($2, $4, $8, false, $1);
Andreas Huberc9410c72016-07-28 12:18:40 -0700398 }
399 ;
400
401typed_vars
402 : /* empty */
403 {
Andreas Huber881227d2016-08-02 14:20:21 -0700404 $$ = new std::vector<TypedVar *>;
Andreas Huberc9410c72016-07-28 12:18:40 -0700405 }
406 | typed_var
407 {
Andreas Huber881227d2016-08-02 14:20:21 -0700408 $$ = new std::vector<TypedVar *>;
Andreas Huberc9410c72016-07-28 12:18:40 -0700409 $$->push_back($1);
410 }
411 | typed_vars ',' typed_var
412 {
413 $$ = $1;
414 $$->push_back($3);
415 }
416 ;
417
418typed_var : type IDENTIFIER { $$ = new TypedVar($2, $1); }
419 ;
420
421
422struct_or_union_keyword
423 : STRUCT { $$ = CompoundType::STYLE_STRUCT; }
424 | UNION { $$ = CompoundType::STYLE_UNION; }
425 ;
426
427named_struct_or_union_declaration
428 : struct_or_union_keyword IDENTIFIER
429 {
Andreas Huber9ed827c2016-08-22 12:31:13 -0700430 CompoundType *container = new CompoundType($1, $2);
Andreas Huberc9410c72016-07-28 12:18:40 -0700431 ast->enterScope(container);
432 }
433 struct_or_union_body
434 {
435 CompoundType *container = static_cast<CompoundType *>(ast->scope());
436
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700437 std::string errorMsg;
438 if (!container->setFields($4, &errorMsg)) {
439 std::cerr << "ERROR: " << errorMsg << " at " << @4 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700440 YYERROR;
441 }
442
Andreas Huberc9410c72016-07-28 12:18:40 -0700443 ast->leaveScope();
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700444
Andreas Huber9ed827c2016-08-22 12:31:13 -0700445 if (!ast->addScopedType(container, &errorMsg)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700446 std::cerr << "ERROR: " << errorMsg << " at " << @2 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700447 YYERROR;
448 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700449 }
450 ;
451
452struct_or_union_declaration
453 : struct_or_union_keyword optIdentifier
454 {
Andreas Huber9ed827c2016-08-22 12:31:13 -0700455 const char *localName = $2;
456 std::string anonName;
457 if (localName == nullptr) {
458 anonName = ast->scope()->pickUniqueAnonymousName();
459 localName = anonName.c_str();
460 }
461
462 CompoundType *container = new CompoundType($1, localName);
Andreas Huberc9410c72016-07-28 12:18:40 -0700463 ast->enterScope(container);
464 }
465 struct_or_union_body
466 {
467 CompoundType *container = static_cast<CompoundType *>(ast->scope());
468
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700469 std::string errorMsg;
470 if (!container->setFields($4, &errorMsg)) {
471 std::cerr << "ERROR: " << errorMsg << " at " << @4 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700472 YYERROR;
473 }
474
Andreas Huberc9410c72016-07-28 12:18:40 -0700475 ast->leaveScope();
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700476
Andreas Huber9ed827c2016-08-22 12:31:13 -0700477 if (!ast->addScopedType(container, &errorMsg)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700478 std::cerr << "ERROR: " << errorMsg << " at " << @2 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700479 YYERROR;
480 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700481
Andreas Huberfd4afab2016-08-03 13:02:57 -0700482 $$ = container->ref();
Andreas Huberc9410c72016-07-28 12:18:40 -0700483 }
484 ;
485
486struct_or_union_body
487 : '{' field_declarations '}' { $$ = $2; }
488 ;
489
490field_declarations
Andreas Huber881227d2016-08-02 14:20:21 -0700491 : /* empty */ { $$ = new std::vector<CompoundField *>; }
Andreas Huberc9410c72016-07-28 12:18:40 -0700492 | field_declarations field_declaration
493 {
494 $$ = $1;
495
496 if ($2 != NULL) {
497 $$->push_back($2);
498 }
499 }
500 ;
501
502field_declaration
503 : type IDENTIFIER ';' { $$ = new CompoundField($2, $1); }
504 | struct_or_union_declaration ';' { $$ = NULL; }
505 | enum_declaration ';' { $$ = NULL; }
506 ;
507
508opt_storage_type
509 : /* empty */ { $$ = NULL; }
Andreas Huber8d3ac0c2016-08-04 14:49:23 -0700510 | ':' fqname
511 {
512 $$ = $2;
513
514 if ($$ != NULL && !$$->isValidEnumStorageType()) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700515 std::cerr << "ERROR: Invalid enum storage type specified. at "
516 << @2 << "\n";
517
Andreas Huber8d3ac0c2016-08-04 14:49:23 -0700518 YYABORT;
519 }
520 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700521 ;
522
523opt_comma
524 : /* empty */
525 | ','
526 ;
527
528named_enum_declaration
529 : ENUM IDENTIFIER opt_storage_type '{' enum_values opt_comma '}'
530 {
Andreas Huber9ed827c2016-08-22 12:31:13 -0700531 EnumType *enumType = new EnumType($2, $5, $3);
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700532
533 std::string errorMsg;
Andreas Huber9ed827c2016-08-22 12:31:13 -0700534 if (!ast->addScopedType(enumType, &errorMsg)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700535 std::cerr << "ERROR: " << errorMsg << " at " << @2 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700536 YYERROR;
537 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700538 }
539 ;
540
541enum_declaration
542 : ENUM '{' enum_values opt_comma '}'
543 {
Andreas Huber9ed827c2016-08-22 12:31:13 -0700544 std::string anonName = ast->scope()->pickUniqueAnonymousName();
545
546 EnumType *enumType = new EnumType(anonName.c_str(), $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 // This should never fail.
551 std::cerr << "ERROR: " << errorMsg << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700552 YYERROR;
553 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700554
Andreas Huberfd4afab2016-08-03 13:02:57 -0700555 $$ = enumType->ref();
Andreas Huberc9410c72016-07-28 12:18:40 -0700556 }
557 | ENUM IDENTIFIER opt_storage_type '{' enum_values opt_comma '}'
558 {
Andreas Huber9ed827c2016-08-22 12:31:13 -0700559 EnumType *enumType = new EnumType($2, $5, $3);
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700560
561 std::string errorMsg;
Andreas Huber9ed827c2016-08-22 12:31:13 -0700562 if (!ast->addScopedType(enumType, &errorMsg)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700563 std::cerr << "ERROR: " << errorMsg << " at " << @2 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700564 YYERROR;
565 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700566
Andreas Huberfd4afab2016-08-03 13:02:57 -0700567 $$ = enumType->ref();
Andreas Huberc9410c72016-07-28 12:18:40 -0700568 }
569 ;
570
571enum_value
572 : IDENTIFIER { $$ = new EnumValue($1); }
Yifan Hong52165692016-08-12 18:06:40 -0700573 | IDENTIFIER '=' const_expr { $$ = new EnumValue($1, $3->value()); }
Andreas Huberc9410c72016-07-28 12:18:40 -0700574 ;
575
576enum_values
577 : /* empty */
578 {
Andreas Huber881227d2016-08-02 14:20:21 -0700579 $$ = new std::vector<EnumValue *>;
Andreas Huberc9410c72016-07-28 12:18:40 -0700580 }
581 | enum_value
582 {
Andreas Huber881227d2016-08-02 14:20:21 -0700583 $$ = new std::vector<EnumValue *>;
Andreas Huberc9410c72016-07-28 12:18:40 -0700584 $$->push_back($1);
585 }
586 | enum_values ',' enum_value
587 {
588 $$ = $1;
589 $$->push_back($3);
590 }
591 ;
592
593type
Andreas Huber84f89de2016-07-28 15:39:51 -0700594 : fqname { $$ = $1; }
Andreas Huberb95ea8a2016-08-15 15:35:42 -0700595 | fqname '[' INTEGER ']'
596 {
Andreas Huber295ad302016-08-16 11:35:00 -0700597 if ($1->isBinder()) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700598 std::cerr << "ERROR: Arrays of interface types are not supported."
599 << " at " << @1 << "\n";
Andreas Huber70a59e12016-08-16 12:57:01 -0700600
Andreas Huberb95ea8a2016-08-15 15:35:42 -0700601 YYERROR;
602 }
603
604 $$ = new ArrayType($1, $3);
605 }
606 | VEC '<' fqname '>'
607 {
Andreas Huber295ad302016-08-16 11:35:00 -0700608 if ($3->isBinder()) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700609 std::cerr << "ERROR: Vectors of interface types are not "
610 << "supported. at " << @3 << "\n";
Andreas Huber70a59e12016-08-16 12:57:01 -0700611
Andreas Huberb95ea8a2016-08-15 15:35:42 -0700612 YYERROR;
613 }
614
615 $$ = new VectorType($3);
616 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700617 | struct_or_union_declaration { $$ = $1; }
618 | enum_declaration { $$ = $1; }
Andreas Huber295ad302016-08-16 11:35:00 -0700619 | INTERFACE { $$ = new GenericBinder; }
Andreas Huberc9410c72016-07-28 12:18:40 -0700620 ;
621
622optIdentifier
623 : /* empty */ { $$ = NULL; }
624 | IDENTIFIER { $$ = $1; }
625 ;
626
627%%
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700628
629#include <android-base/logging.h>
630
631void yy::parser::error(
632 const yy::parser::location_type &where,
633 const std::string &errstr) {
634 std::cerr << "ERROR: " << errstr << " at " << where << "\n";
635}
636