blob: 5efe93cec697f1907ae751b3fbedfeb5bf8049cb [file] [log] [blame]
Andreas Huber1aec3972016-08-26 09:26:32 -07001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Andreas Huberc9410c72016-07-28 12:18:40 -070017%{
18
Andreas Huber3599d922016-08-09 10:42:57 -070019#include "Annotation.h"
Andreas Huberc9410c72016-07-28 12:18:40 -070020#include "AST.h"
21#include "ArrayType.h"
22#include "CompoundType.h"
Yifan Hong52165692016-08-12 18:06:40 -070023#include "ConstantExpression.h"
Andreas Huberc9410c72016-07-28 12:18:40 -070024#include "EnumType.h"
Yifan Hongf24fa852016-09-23 11:03:15 -070025#include "FQName.h"
Andreas Huber295ad302016-08-16 11:35:00 -070026#include "GenericBinder.h"
Andreas Huberc9410c72016-07-28 12:18:40 -070027#include "Interface.h"
28#include "Method.h"
Andreas Huberc9410c72016-07-28 12:18:40 -070029#include "VectorType.h"
30
31#include "hidl-gen_y.h"
32
Andreas Huber709b62d2016-09-19 11:21:18 -070033#include <android-base/logging.h>
Andreas Huberc9410c72016-07-28 12:18:40 -070034#include <stdio.h>
35
36using namespace android;
37
Andreas Huber0d0f9a22016-08-17 10:26:11 -070038extern int yylex(yy::parser::semantic_type *, yy::parser::location_type *, void *);
Andreas Huberc9410c72016-07-28 12:18:40 -070039
40#define scanner ast->scanner()
41
42%}
43
Andreas Huber0d0f9a22016-08-17 10:26:11 -070044%initial-action {
45 // Initialize the initial location.
46 @$.begin.filename = @$.end.filename =
47 const_cast<std::string *>(&ast->getFilename());
48}
49
Andreas Huberc9410c72016-07-28 12:18:40 -070050%parse-param { android::AST *ast }
51%lex-param { void *scanner }
52%pure-parser
Andreas Huber0d0f9a22016-08-17 10:26:11 -070053%skeleton "glr.cc"
Andreas Huberc9410c72016-07-28 12:18:40 -070054
Andreas Huberc9410c72016-07-28 12:18:40 -070055%token<str> ENUM
56%token<str> EXTENDS
Andreas Huber84f89de2016-07-28 15:39:51 -070057%token<str> FQNAME
Andreas Huberc9410c72016-07-28 12:18:40 -070058%token<str> GENERATES
59%token<str> IDENTIFIER
60%token<str> IMPORT
61%token<str> INTEGER
Yifan Hong52165692016-08-12 18:06:40 -070062%token<str> FLOAT
Andreas Huberc9410c72016-07-28 12:18:40 -070063%token<str> INTERFACE
64%token<str> PACKAGE
Andreas Huber84f89de2016-07-28 15:39:51 -070065%token<type> SCALAR
Andreas Huberc9410c72016-07-28 12:18:40 -070066%token<str> STRUCT
67%token<str> STRING_LITERAL
68%token<str> TYPEDEF
69%token<str> UNION
70%token<str> VEC
Iliyan Malchev639bff82016-08-13 14:24:11 -070071%token<void> ONEWAY
Andreas Huberc9410c72016-07-28 12:18:40 -070072
Yifan Hong52165692016-08-12 18:06:40 -070073/* Operator precedence and associativity, as per
74 * http://en.cppreference.com/w/cpp/language/operator_precedence */
75/* Precedence level 15 ternary operator */
76%right '?' ':'
77/* Precedence level 13 - 14, LTR, logical operators*/
78%left LOGICAL_OR
79%left LOGICAL_AND
80/* Precedence level 10 - 12, LTR, bitwise operators*/
81%left '|'
82%left '^'
83%left '&'
84/* Precedence level 9, LTR */
85%left EQUALITY NEQ
86/* Precedence level 8, LTR */
87%left '<' '>' LEQ GEQ
88/* Precedence level 7, LTR */
89%left LSHIFT RSHIFT
90/* Precedence level 6, LTR */
91%left '+' '-'
92/* Precedence level 5, LTR */
93%left '*' '/' '%'
94/* Precedence level 3, RTL; but we have to use %left here */
95%left UNARY_MINUS UNARY_PLUS '!' '~'
96
Andreas Huberc9410c72016-07-28 12:18:40 -070097%type<str> optIdentifier package
Yifan Hongae16eed2016-09-23 13:25:25 -070098%type<fqName> fqname
99%type<type> fqtype
Andreas Huberc9410c72016-07-28 12:18:40 -0700100
101%type<type> type opt_storage_type
102%type<type> enum_declaration
103%type<type> struct_or_union_declaration
104%type<type> opt_extends
105
106%type<field> field_declaration
107%type<fields> field_declarations struct_or_union_body
Yifan Hong52165692016-08-12 18:06:40 -0700108%type<constantExpression> const_expr
Andreas Huberc9410c72016-07-28 12:18:40 -0700109%type<enumValue> enum_value
Yifan Hongf24fa852016-09-23 11:03:15 -0700110%type<enumValues> enum_values enum_declaration_body
Andreas Huberc9410c72016-07-28 12:18:40 -0700111%type<typedVars> typed_vars
112%type<typedVar> typed_var
113%type<method> method_declaration
114%type<compoundStyle> struct_or_union_keyword
Yifan Hongf24fa852016-09-23 11:03:15 -0700115%type<stringVec> annotation_string_values annotation_string_value
116%type<constExprVec> annotation_const_expr_values annotation_const_expr_value
Andreas Huber3599d922016-08-09 10:42:57 -0700117%type<annotationParam> annotation_param
118%type<annotationParams> opt_annotation_params annotation_params
119%type<annotation> annotation
120%type<annotations> opt_annotations
Andreas Huberc9410c72016-07-28 12:18:40 -0700121
122%start program
123
124%union {
125 const char *str;
126 android::Type *type;
Yifan Hongae16eed2016-09-23 13:25:25 -0700127 android::FQName *fqName;
Andreas Huberc9410c72016-07-28 12:18:40 -0700128 android::CompoundType *compoundType;
129 android::CompoundField *field;
Andreas Huber881227d2016-08-02 14:20:21 -0700130 std::vector<android::CompoundField *> *fields;
Andreas Huberc9410c72016-07-28 12:18:40 -0700131 android::EnumValue *enumValue;
Yifan Hong52165692016-08-12 18:06:40 -0700132 android::ConstantExpression *constantExpression;
Andreas Huber881227d2016-08-02 14:20:21 -0700133 std::vector<android::EnumValue *> *enumValues;
Andreas Huberc9410c72016-07-28 12:18:40 -0700134 android::TypedVar *typedVar;
Andreas Huber881227d2016-08-02 14:20:21 -0700135 std::vector<android::TypedVar *> *typedVars;
Andreas Huberc9410c72016-07-28 12:18:40 -0700136 android::Method *method;
137 android::CompoundType::Style compoundStyle;
Andreas Huber3599d922016-08-09 10:42:57 -0700138 std::vector<std::string> *stringVec;
Yifan Hongf24fa852016-09-23 11:03:15 -0700139 std::vector<android::ConstantExpression *> *constExprVec;
Steven Morelandd537ab02016-09-12 10:32:01 -0700140 android::AnnotationParam *annotationParam;
141 android::AnnotationParamVector *annotationParams;
Andreas Huber3599d922016-08-09 10:42:57 -0700142 android::Annotation *annotation;
Steven Morelandd537ab02016-09-12 10:32:01 -0700143 std::vector<android::Annotation *> *annotations;
Andreas Huberc9410c72016-07-28 12:18:40 -0700144}
145
146%%
147
Andreas Huber3599d922016-08-09 10:42:57 -0700148opt_annotations
149 : /* empty */
150 {
Steven Morelandd537ab02016-09-12 10:32:01 -0700151 $$ = new std::vector<Annotation *>;
Andreas Huber3599d922016-08-09 10:42:57 -0700152 }
153 | opt_annotations annotation
154 {
155 $$ = $1;
Steven Morelandd537ab02016-09-12 10:32:01 -0700156 $$->push_back($2);
Andreas Huber3599d922016-08-09 10:42:57 -0700157 }
158 ;
159
160annotation
161 : '@' IDENTIFIER opt_annotation_params
162 {
163 $$ = new Annotation($2, $3);
164 }
165 ;
166
167opt_annotation_params
168 : /* empty */
169 {
Steven Morelandd537ab02016-09-12 10:32:01 -0700170 $$ = new AnnotationParamVector;
Andreas Huber3599d922016-08-09 10:42:57 -0700171 }
172 | '(' annotation_params ')'
173 {
174 $$ = $2;
175 }
176 ;
177
178annotation_params
179 : annotation_param
180 {
Steven Morelandd537ab02016-09-12 10:32:01 -0700181 $$ = new AnnotationParamVector;
182 $$->push_back($1);
Andreas Huber3599d922016-08-09 10:42:57 -0700183 }
184 | annotation_params ',' annotation_param
185 {
186 $$ = $1;
Steven Morelandd537ab02016-09-12 10:32:01 -0700187 $$->push_back($3);
Andreas Huber3599d922016-08-09 10:42:57 -0700188 }
189 ;
190
191annotation_param
Yifan Hongf24fa852016-09-23 11:03:15 -0700192 : IDENTIFIER '=' annotation_string_value
193 {
194 $$ = new AnnotationParam($1, $3);
195 }
196 | IDENTIFIER '=' annotation_const_expr_value
Andreas Huber3599d922016-08-09 10:42:57 -0700197 {
Steven Morelandd537ab02016-09-12 10:32:01 -0700198 $$ = new AnnotationParam($1, $3);
Andreas Huber3599d922016-08-09 10:42:57 -0700199 }
200 ;
201
Yifan Hongf24fa852016-09-23 11:03:15 -0700202annotation_string_value
Andreas Huber3599d922016-08-09 10:42:57 -0700203 : STRING_LITERAL
204 {
205 $$ = new std::vector<std::string>;
206 $$->push_back($1);
207 }
208 | '{' annotation_string_values '}' { $$ = $2; }
209 ;
210
211annotation_string_values
212 : STRING_LITERAL
213 {
214 $$ = new std::vector<std::string>;
215 $$->push_back($1);
216 }
217 | annotation_string_values ',' STRING_LITERAL
218 {
219 $$ = $1;
220 $$->push_back($3);
221 }
222 ;
223
Yifan Hongf24fa852016-09-23 11:03:15 -0700224annotation_const_expr_value
225 : const_expr
226 {
227 $$ = new std::vector<ConstantExpression *>;
228 $$->push_back($1);
229 }
230 | '{' annotation_const_expr_values '}' { $$ = $2; }
231 ;
232
233annotation_const_expr_values
234 : const_expr
235 {
236 $$ = new std::vector<ConstantExpression *>;
237 $$->push_back($1);
238 }
239 | annotation_const_expr_values ',' const_expr
240 {
241 $$ = $1;
242 $$->push_back($3);
243 }
244 ;
245
Andreas Huberc9410c72016-07-28 12:18:40 -0700246program
Andreas Huberda51b8e2016-07-28 16:00:57 -0700247 : package imports body
Andreas Huber84f89de2016-07-28 15:39:51 -0700248 ;
249
250fqname
251 : FQNAME
252 {
Yifan Hongae16eed2016-09-23 13:25:25 -0700253 $$ = new FQName($1);
254 if(!$$->isValid()) {
255 std::cerr << "ERROR: FQName '" << $1 << "' is not valid at "
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700256 << @1
Yifan Hongae16eed2016-09-23 13:25:25 -0700257 << ".\n";
Andreas Huber84f89de2016-07-28 15:39:51 -0700258 YYERROR;
259 }
260 }
261 | IDENTIFIER
262 {
Yifan Hongae16eed2016-09-23 13:25:25 -0700263 $$ = new FQName($1);
264 if(!$$->isValid()) {
265 std::cerr << "ERROR: FQName '" << $1 << "' is not valid at "
266 << @1
267 << ".\n";
268 YYERROR;
269 }
270 }
271 ;
272
273fqtype
274 : fqname
275 {
276 $$ = ast->lookupType(*($1));
Andreas Huber84f89de2016-07-28 15:39:51 -0700277 if ($$ == NULL) {
Yifan Hongae16eed2016-09-23 13:25:25 -0700278 std::cerr << "ERROR: Failed to lookup type '" << $1->string() << "' at "
279 << @1
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700280 << "\n";
281
Andreas Huber84f89de2016-07-28 15:39:51 -0700282 YYERROR;
283 }
284 }
285 | SCALAR
286 ;
Andreas Huberc9410c72016-07-28 12:18:40 -0700287
288package
Andreas Huber84f89de2016-07-28 15:39:51 -0700289 : PACKAGE FQNAME ';'
Andreas Hubereb1081f2016-07-28 13:13:24 -0700290 {
Andreas Huber84f89de2016-07-28 15:39:51 -0700291 if (!ast->setPackage($2)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700292 std::cerr << "ERROR: Malformed package identifier '"
293 << $2
294 << "' at "
295 << @2
296 << "\n";
297
Andreas Huber84f89de2016-07-28 15:39:51 -0700298 YYERROR;
299 }
Andreas Hubereb1081f2016-07-28 13:13:24 -0700300 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700301
Andreas Huberc9410c72016-07-28 12:18:40 -0700302imports
303 : /* empty */
Andreas Huber84f89de2016-07-28 15:39:51 -0700304 | imports IMPORT FQNAME ';'
Andreas Hubereb1081f2016-07-28 13:13:24 -0700305 {
Andreas Huber68f24592016-07-29 14:53:48 -0700306 if (!ast->addImport($3)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700307 std::cerr << "ERROR: Unable to import '" << $3 << "' at " << @3
308 << "\n";
Andreas Huber68f24592016-07-29 14:53:48 -0700309
310 YYERROR;
311 }
Andreas Hubereb1081f2016-07-28 13:13:24 -0700312 }
Andreas Huber5345ec22016-07-29 13:33:27 -0700313 | imports IMPORT IDENTIFIER ';'
314 {
Andreas Huber68f24592016-07-29 14:53:48 -0700315 if (!ast->addImport($3)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700316 std::cerr << "ERROR: Unable to import '" << $3 << "' at " << @3
317 << "\n";
Andreas Huber68f24592016-07-29 14:53:48 -0700318
319 YYERROR;
320 }
Andreas Huber5345ec22016-07-29 13:33:27 -0700321 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700322 ;
323
324opt_extends
325 : /* empty */ { $$ = NULL; }
Yifan Hongae16eed2016-09-23 13:25:25 -0700326 | EXTENDS fqtype { $$ = $2; }
Andreas Huberc9410c72016-07-28 12:18:40 -0700327
328body
Zhuoyao Zhangba7e6e92016-08-10 12:19:02 -0700329 : opt_annotations INTERFACE IDENTIFIER opt_extends
Andreas Huberc9410c72016-07-28 12:18:40 -0700330 {
Zhuoyao Zhangba7e6e92016-08-10 12:19:02 -0700331 if ($4 != NULL && !$4->isInterface()) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700332 std::cerr << "ERROR: You can only extend interfaces. at" << @4
333 << "\n";
334
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700335 YYERROR;
336 }
337
Andreas Huber991b8642016-08-15 16:40:44 -0700338 if ($3[0] != 'I') {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700339 std::cerr << "ERROR: All interface names must start with an 'I' "
340 << "prefix. at " << @3 << "\n";
Andreas Huber991b8642016-08-15 16:40:44 -0700341
342 YYERROR;
343 }
344
Andreas Huber9ed827c2016-08-22 12:31:13 -0700345 Interface *iface = new Interface($3, static_cast<Interface *>($4), $1);
Andreas Hubereb1081f2016-07-28 13:13:24 -0700346
347 // Register interface immediately so it can be referenced inside
348 // definition.
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700349 std::string errorMsg;
Andreas Huber9ed827c2016-08-22 12:31:13 -0700350 if (!ast->addScopedType(iface, &errorMsg)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700351 std::cerr << "ERROR: " << errorMsg << " at " << @3 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700352 YYERROR;
353 }
Andreas Hubereb1081f2016-07-28 13:13:24 -0700354
Andreas Huberc9410c72016-07-28 12:18:40 -0700355 ast->enterScope(iface);
356 }
357 '{' interface_declarations '}' ';'
358 {
359 Interface *iface = static_cast<Interface *>(ast->scope());
360
361 ast->leaveScope();
Andreas Huberc9410c72016-07-28 12:18:40 -0700362 }
363 | type_declarations
364 ;
365
366interface_declarations
367 : /* empty */
368 | interface_declarations type_declaration
369 | interface_declarations method_declaration
370 {
371 Interface *iface = static_cast<Interface *>(ast->scope());
372 iface->addMethod($2);
373 }
374 ;
375
376type_declarations
Andreas Hubera2723d22016-07-29 15:36:07 -0700377 : /* empty */
Andreas Huberc9410c72016-07-28 12:18:40 -0700378 | type_declarations type_declaration
379 ;
380
381type_declaration
382 : named_struct_or_union_declaration ';'
383 | named_enum_declaration ';'
384 | typedef_declaration ';'
Andreas Huberc9410c72016-07-28 12:18:40 -0700385 ;
386
387typedef_declaration
388 : TYPEDEF type IDENTIFIER
389 {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700390 std::string errorMsg;
Andreas Huber39fa7182016-08-19 14:27:33 -0700391 if (!ast->addTypeDef($3, $2, &errorMsg)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700392 std::cerr << "ERROR: " << errorMsg << " at " << @3 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700393 YYERROR;
394 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700395 }
396 ;
397
Yifan Hong52165692016-08-12 18:06:40 -0700398const_expr
Yifan Hongf24fa852016-09-23 11:03:15 -0700399 : INTEGER { $$ = new ConstantExpression($1); }
Yifan Hongb44a6c82016-09-22 15:50:18 -0700400 | fqname
401 {
Yifan Hongf24fa852016-09-23 11:03:15 -0700402 if(!$1->isValidValueName()) {
403 std::cerr << "ERROR: '" << $1->string()
404 << "' does not refer to an enum value at "
405 << @1 << ".\n";
406 YYERROR;
407 }
408 if($1->isIdentifier()) {
409 std::string identifier = $1->name();
410 LocalIdentifier *iden = ast->scope()->lookupIdentifier(identifier);
411 if(!iden) {
412 std::cerr << "ERROR: at " << @1 << ", identifier " << $1
413 << " could not be found.\n";
414 YYERROR;
415 }
416 if(!iden->isEnumValue()) {
417 std::cerr << "ERROR: at " << @1 << ", identifier " << $1
418 << " is not an enum value.\n";
419 YYERROR;
420 }
421 $$ = new ConstantExpression(
422 *(static_cast<EnumValue *>(iden)->constExpr()), $1->string());
423 } else {
424 std::string errorMsg;
425 EnumValue *v = ast->lookupEnumValue(*($1), &errorMsg);
426 if(v == nullptr) {
427 std::cerr << "ERROR: " << errorMsg << " at " << @1 << ".\n";
428 YYERROR;
429 }
430 $$ = new ConstantExpression(*(v->constExpr()), $1->string());
431 }
Yifan Hongb44a6c82016-09-22 15:50:18 -0700432 }
Yifan Hong52165692016-08-12 18:06:40 -0700433 | const_expr '?' const_expr ':' const_expr
434 {
Yifan Hongb44a6c82016-09-22 15:50:18 -0700435 $$ = new ConstantExpression($1, $3, $5);
Yifan Hong52165692016-08-12 18:06:40 -0700436 }
437 | const_expr LOGICAL_OR const_expr { $$ = new ConstantExpression($1, "||", $3); }
438 | const_expr LOGICAL_AND const_expr { $$ = new ConstantExpression($1, "&&", $3); }
439 | const_expr '|' const_expr { $$ = new ConstantExpression($1, "|" , $3); }
440 | const_expr '^' const_expr { $$ = new ConstantExpression($1, "^" , $3); }
441 | const_expr '&' const_expr { $$ = new ConstantExpression($1, "&" , $3); }
442 | const_expr EQUALITY const_expr { $$ = new ConstantExpression($1, "==", $3); }
443 | const_expr NEQ const_expr { $$ = new ConstantExpression($1, "!=", $3); }
444 | const_expr '<' const_expr { $$ = new ConstantExpression($1, "<" , $3); }
445 | const_expr '>' const_expr { $$ = new ConstantExpression($1, ">" , $3); }
446 | const_expr LEQ const_expr { $$ = new ConstantExpression($1, "<=", $3); }
447 | const_expr GEQ const_expr { $$ = new ConstantExpression($1, ">=", $3); }
448 | const_expr LSHIFT const_expr { $$ = new ConstantExpression($1, "<<", $3); }
449 | const_expr RSHIFT const_expr { $$ = new ConstantExpression($1, ">>", $3); }
450 | const_expr '+' const_expr { $$ = new ConstantExpression($1, "+" , $3); }
451 | const_expr '-' const_expr { $$ = new ConstantExpression($1, "-" , $3); }
452 | const_expr '*' const_expr { $$ = new ConstantExpression($1, "*" , $3); }
453 | const_expr '/' const_expr { $$ = new ConstantExpression($1, "/" , $3); }
454 | const_expr '%' const_expr { $$ = new ConstantExpression($1, "%" , $3); }
455 | '+' const_expr %prec UNARY_PLUS { $$ = new ConstantExpression("+", $2); }
456 | '-' const_expr %prec UNARY_MINUS { $$ = new ConstantExpression("-", $2); }
457 | '!' const_expr { $$ = new ConstantExpression("!", $2); }
458 | '~' const_expr { $$ = new ConstantExpression("~", $2); }
459 | '(' const_expr ')' { $$ = $2; }
460 ;
461
Andreas Huberc9410c72016-07-28 12:18:40 -0700462method_declaration
Andreas Huber3599d922016-08-09 10:42:57 -0700463 : opt_annotations IDENTIFIER '(' typed_vars ')' ';'
Andreas Huberc9410c72016-07-28 12:18:40 -0700464 {
Iliyan Malchev639bff82016-08-13 14:24:11 -0700465 $$ = new Method($2, $4, new std::vector<TypedVar *>, false, $1);
466 }
467 | opt_annotations ONEWAY IDENTIFIER '(' typed_vars ')' ';'
468 {
469 $$ = new Method($3, $5, new std::vector<TypedVar *>, true, $1);
Andreas Huberc9410c72016-07-28 12:18:40 -0700470 }
Andreas Huber3599d922016-08-09 10:42:57 -0700471 | opt_annotations IDENTIFIER '(' typed_vars ')' GENERATES '(' typed_vars ')' ';'
Andreas Huberc9410c72016-07-28 12:18:40 -0700472 {
Iliyan Malchev639bff82016-08-13 14:24:11 -0700473 $$ = new Method($2, $4, $8, false, $1);
Andreas Huberc9410c72016-07-28 12:18:40 -0700474 }
475 ;
476
477typed_vars
478 : /* empty */
479 {
Andreas Huber881227d2016-08-02 14:20:21 -0700480 $$ = new std::vector<TypedVar *>;
Andreas Huberc9410c72016-07-28 12:18:40 -0700481 }
482 | typed_var
483 {
Andreas Huber881227d2016-08-02 14:20:21 -0700484 $$ = new std::vector<TypedVar *>;
Andreas Huberc9410c72016-07-28 12:18:40 -0700485 $$->push_back($1);
486 }
487 | typed_vars ',' typed_var
488 {
489 $$ = $1;
490 $$->push_back($3);
491 }
492 ;
493
494typed_var : type IDENTIFIER { $$ = new TypedVar($2, $1); }
495 ;
496
497
498struct_or_union_keyword
499 : STRUCT { $$ = CompoundType::STYLE_STRUCT; }
500 | UNION { $$ = CompoundType::STYLE_UNION; }
501 ;
502
503named_struct_or_union_declaration
504 : struct_or_union_keyword IDENTIFIER
505 {
Andreas Huber9ed827c2016-08-22 12:31:13 -0700506 CompoundType *container = new CompoundType($1, $2);
Andreas Huberc9410c72016-07-28 12:18:40 -0700507 ast->enterScope(container);
508 }
509 struct_or_union_body
510 {
511 CompoundType *container = static_cast<CompoundType *>(ast->scope());
512
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700513 std::string errorMsg;
514 if (!container->setFields($4, &errorMsg)) {
515 std::cerr << "ERROR: " << errorMsg << " at " << @4 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700516 YYERROR;
517 }
518
Andreas Huberc9410c72016-07-28 12:18:40 -0700519 ast->leaveScope();
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700520
Andreas Huber9ed827c2016-08-22 12:31:13 -0700521 if (!ast->addScopedType(container, &errorMsg)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700522 std::cerr << "ERROR: " << errorMsg << " at " << @2 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700523 YYERROR;
524 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700525 }
526 ;
527
528struct_or_union_declaration
529 : struct_or_union_keyword optIdentifier
530 {
Andreas Huber9ed827c2016-08-22 12:31:13 -0700531 const char *localName = $2;
532 std::string anonName;
533 if (localName == nullptr) {
534 anonName = ast->scope()->pickUniqueAnonymousName();
535 localName = anonName.c_str();
536 }
537
538 CompoundType *container = new CompoundType($1, localName);
Andreas Huberc9410c72016-07-28 12:18:40 -0700539 ast->enterScope(container);
540 }
541 struct_or_union_body
542 {
543 CompoundType *container = static_cast<CompoundType *>(ast->scope());
544
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700545 std::string errorMsg;
546 if (!container->setFields($4, &errorMsg)) {
547 std::cerr << "ERROR: " << errorMsg << " at " << @4 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700548 YYERROR;
549 }
550
Andreas Huberc9410c72016-07-28 12:18:40 -0700551 ast->leaveScope();
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700552
Andreas Huber9ed827c2016-08-22 12:31:13 -0700553 if (!ast->addScopedType(container, &errorMsg)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700554 std::cerr << "ERROR: " << errorMsg << " at " << @2 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700555 YYERROR;
556 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700557
Andreas Huberfd4afab2016-08-03 13:02:57 -0700558 $$ = container->ref();
Andreas Huberc9410c72016-07-28 12:18:40 -0700559 }
560 ;
561
562struct_or_union_body
563 : '{' field_declarations '}' { $$ = $2; }
564 ;
565
566field_declarations
Andreas Huber881227d2016-08-02 14:20:21 -0700567 : /* empty */ { $$ = new std::vector<CompoundField *>; }
Andreas Huberc9410c72016-07-28 12:18:40 -0700568 | field_declarations field_declaration
569 {
570 $$ = $1;
571
572 if ($2 != NULL) {
573 $$->push_back($2);
574 }
575 }
576 ;
577
578field_declaration
579 : type IDENTIFIER ';' { $$ = new CompoundField($2, $1); }
580 | struct_or_union_declaration ';' { $$ = NULL; }
581 | enum_declaration ';' { $$ = NULL; }
582 ;
583
584opt_storage_type
585 : /* empty */ { $$ = NULL; }
Yifan Hongae16eed2016-09-23 13:25:25 -0700586 | ':' fqtype
Andreas Huber8d3ac0c2016-08-04 14:49:23 -0700587 {
588 $$ = $2;
589
590 if ($$ != NULL && !$$->isValidEnumStorageType()) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700591 std::cerr << "ERROR: Invalid enum storage type specified. at "
592 << @2 << "\n";
593
Andreas Huber8d3ac0c2016-08-04 14:49:23 -0700594 YYABORT;
595 }
596 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700597 ;
598
599opt_comma
600 : /* empty */
601 | ','
602 ;
603
604named_enum_declaration
Yifan Hongf24fa852016-09-23 11:03:15 -0700605 : ENUM IDENTIFIER opt_storage_type
Andreas Huberc9410c72016-07-28 12:18:40 -0700606 {
Yifan Hongf24fa852016-09-23 11:03:15 -0700607 ast->enterScope(new EnumType($2, $3));
608 }
609 enum_declaration_body
610 {
611 EnumType *enumType = static_cast<EnumType *>(ast->scope());
612 ast->leaveScope();
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700613
614 std::string errorMsg;
Andreas Huber9ed827c2016-08-22 12:31:13 -0700615 if (!ast->addScopedType(enumType, &errorMsg)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700616 std::cerr << "ERROR: " << errorMsg << " at " << @2 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700617 YYERROR;
618 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700619 }
620 ;
621
622enum_declaration
Yifan Hongf24fa852016-09-23 11:03:15 -0700623 : ENUM
Andreas Huberc9410c72016-07-28 12:18:40 -0700624 {
Andreas Huber9ed827c2016-08-22 12:31:13 -0700625 std::string anonName = ast->scope()->pickUniqueAnonymousName();
Yifan Hongf24fa852016-09-23 11:03:15 -0700626 ast->enterScope(new EnumType(anonName.c_str()));
627 }
628 enum_declaration_body
629 {
Andreas Huber9ed827c2016-08-22 12:31:13 -0700630
Yifan Hongf24fa852016-09-23 11:03:15 -0700631 EnumType *enumType = static_cast<EnumType *>(ast->scope());
632 ast->leaveScope();
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700633
634 std::string errorMsg;
Andreas Huber9ed827c2016-08-22 12:31:13 -0700635 if (!ast->addScopedType(enumType, &errorMsg)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700636 // This should never fail.
637 std::cerr << "ERROR: " << errorMsg << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700638 YYERROR;
639 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700640
Andreas Huberfd4afab2016-08-03 13:02:57 -0700641 $$ = enumType->ref();
Andreas Huberc9410c72016-07-28 12:18:40 -0700642 }
Yifan Hongf24fa852016-09-23 11:03:15 -0700643 | ENUM IDENTIFIER opt_storage_type
Andreas Huberc9410c72016-07-28 12:18:40 -0700644 {
Yifan Hongf24fa852016-09-23 11:03:15 -0700645 ast->enterScope(new EnumType($2, $3));
646 }
647 enum_declaration_body
648 {
649 EnumType *enumType = static_cast<EnumType *>(ast->scope());
650 ast->leaveScope();
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700651
652 std::string errorMsg;
Andreas Huber9ed827c2016-08-22 12:31:13 -0700653 if (!ast->addScopedType(enumType, &errorMsg)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700654 std::cerr << "ERROR: " << errorMsg << " at " << @2 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700655 YYERROR;
656 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700657
Andreas Huberfd4afab2016-08-03 13:02:57 -0700658 $$ = enumType->ref();
Andreas Huberc9410c72016-07-28 12:18:40 -0700659 }
660 ;
661
Yifan Hongf24fa852016-09-23 11:03:15 -0700662enum_declaration_body
663 : '{' enum_values opt_comma '}' { $$ = $2; }
664 ;
665
Andreas Huberc9410c72016-07-28 12:18:40 -0700666enum_value
667 : IDENTIFIER { $$ = new EnumValue($1); }
Yifan Hong57886972016-08-17 10:42:15 -0700668 | IDENTIFIER '=' const_expr { $$ = new EnumValue($1, $3); }
Andreas Huberc9410c72016-07-28 12:18:40 -0700669 ;
670
671enum_values
672 : /* empty */
Yifan Hongf24fa852016-09-23 11:03:15 -0700673 { /* do nothing */ }
Andreas Huberc9410c72016-07-28 12:18:40 -0700674 | enum_value
675 {
Yifan Hongf24fa852016-09-23 11:03:15 -0700676 static_cast<EnumType *>(ast->scope())->addValue($1);
Andreas Huberc9410c72016-07-28 12:18:40 -0700677 }
678 | enum_values ',' enum_value
679 {
Yifan Hongf24fa852016-09-23 11:03:15 -0700680 static_cast<EnumType *>(ast->scope())->addValue($3);
Andreas Huberc9410c72016-07-28 12:18:40 -0700681 }
682 ;
683
684type
Yifan Hongae16eed2016-09-23 13:25:25 -0700685 : fqtype { $$ = $1; }
Yifan Hongf24fa852016-09-23 11:03:15 -0700686 | fqtype '[' const_expr ']'
Andreas Huberb95ea8a2016-08-15 15:35:42 -0700687 {
Andreas Huber295ad302016-08-16 11:35:00 -0700688 if ($1->isBinder()) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700689 std::cerr << "ERROR: Arrays of interface types are not supported."
690 << " at " << @1 << "\n";
Andreas Huber70a59e12016-08-16 12:57:01 -0700691
Andreas Huberb95ea8a2016-08-15 15:35:42 -0700692 YYERROR;
693 }
694
Andreas Huber709b62d2016-09-19 11:21:18 -0700695 if ($1->isArray()) {
Yifan Hongf24fa852016-09-23 11:03:15 -0700696 $$ = new ArrayType(static_cast<ArrayType *>($1), $3);
Andreas Huber709b62d2016-09-19 11:21:18 -0700697 } else {
Yifan Hongf24fa852016-09-23 11:03:15 -0700698 $$ = new ArrayType($1, $3);
Andreas Huber709b62d2016-09-19 11:21:18 -0700699 }
Andreas Huberb95ea8a2016-08-15 15:35:42 -0700700 }
Yifan Hongae16eed2016-09-23 13:25:25 -0700701 | VEC '<' fqtype '>'
Andreas Huberb95ea8a2016-08-15 15:35:42 -0700702 {
Andreas Huber295ad302016-08-16 11:35:00 -0700703 if ($3->isBinder()) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700704 std::cerr << "ERROR: Vectors of interface types are not "
705 << "supported. at " << @3 << "\n";
Andreas Huber70a59e12016-08-16 12:57:01 -0700706
Andreas Huberb95ea8a2016-08-15 15:35:42 -0700707 YYERROR;
708 }
709
710 $$ = new VectorType($3);
711 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700712 | struct_or_union_declaration { $$ = $1; }
713 | enum_declaration { $$ = $1; }
Andreas Huber295ad302016-08-16 11:35:00 -0700714 | INTERFACE { $$ = new GenericBinder; }
Andreas Huberc9410c72016-07-28 12:18:40 -0700715 ;
716
717optIdentifier
718 : /* empty */ { $$ = NULL; }
719 | IDENTIFIER { $$ = $1; }
720 ;
721
722%%
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700723
724#include <android-base/logging.h>
725
726void yy::parser::error(
727 const yy::parser::location_type &where,
728 const std::string &errstr) {
729 std::cerr << "ERROR: " << errstr << " at " << where << "\n";
730}
731