blob: 30c5aafcc25956228fad126a2e2077935ad96a06 [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
Steven Moreland4ab9b792016-09-26 14:14:07 -070053%glr-parser
Andreas Huber0d0f9a22016-08-17 10:26:11 -070054%skeleton "glr.cc"
Andreas Huberc9410c72016-07-28 12:18:40 -070055
Steven Moreland4ab9b792016-09-26 14:14:07 -070056%expect-rr 0
57
Andreas Huberc9410c72016-07-28 12:18:40 -070058%token<str> ENUM
59%token<str> EXTENDS
Andreas Huber84f89de2016-07-28 15:39:51 -070060%token<str> FQNAME
Andreas Huberc9410c72016-07-28 12:18:40 -070061%token<str> GENERATES
62%token<str> IDENTIFIER
63%token<str> IMPORT
64%token<str> INTEGER
Yifan Hong52165692016-08-12 18:06:40 -070065%token<str> FLOAT
Andreas Huberc9410c72016-07-28 12:18:40 -070066%token<str> INTERFACE
67%token<str> PACKAGE
Andreas Huber84f89de2016-07-28 15:39:51 -070068%token<type> SCALAR
Andreas Huberc9410c72016-07-28 12:18:40 -070069%token<str> STRUCT
70%token<str> STRING_LITERAL
71%token<str> TYPEDEF
72%token<str> UNION
73%token<str> VEC
Iliyan Malchev639bff82016-08-13 14:24:11 -070074%token<void> ONEWAY
Andreas Huberc9410c72016-07-28 12:18:40 -070075
Yifan Hong52165692016-08-12 18:06:40 -070076/* Operator precedence and associativity, as per
77 * http://en.cppreference.com/w/cpp/language/operator_precedence */
78/* Precedence level 15 ternary operator */
79%right '?' ':'
80/* Precedence level 13 - 14, LTR, logical operators*/
81%left LOGICAL_OR
82%left LOGICAL_AND
83/* Precedence level 10 - 12, LTR, bitwise operators*/
84%left '|'
85%left '^'
86%left '&'
87/* Precedence level 9, LTR */
88%left EQUALITY NEQ
89/* Precedence level 8, LTR */
90%left '<' '>' LEQ GEQ
91/* Precedence level 7, LTR */
92%left LSHIFT RSHIFT
93/* Precedence level 6, LTR */
94%left '+' '-'
95/* Precedence level 5, LTR */
96%left '*' '/' '%'
97/* Precedence level 3, RTL; but we have to use %left here */
98%left UNARY_MINUS UNARY_PLUS '!' '~'
99
Andreas Huberc9410c72016-07-28 12:18:40 -0700100%type<str> optIdentifier package
Yifan Hongae16eed2016-09-23 13:25:25 -0700101%type<fqName> fqname
102%type<type> fqtype
Andreas Huberc9410c72016-07-28 12:18:40 -0700103
104%type<type> type opt_storage_type
105%type<type> enum_declaration
106%type<type> struct_or_union_declaration
107%type<type> opt_extends
108
109%type<field> field_declaration
110%type<fields> field_declarations struct_or_union_body
Yifan Hong52165692016-08-12 18:06:40 -0700111%type<constantExpression> const_expr
Andreas Huberc9410c72016-07-28 12:18:40 -0700112%type<enumValue> enum_value
Yifan Hongf24fa852016-09-23 11:03:15 -0700113%type<enumValues> enum_values enum_declaration_body
Andreas Huberc9410c72016-07-28 12:18:40 -0700114%type<typedVars> typed_vars
115%type<typedVar> typed_var
116%type<method> method_declaration
117%type<compoundStyle> struct_or_union_keyword
Yifan Hongf24fa852016-09-23 11:03:15 -0700118%type<stringVec> annotation_string_values annotation_string_value
119%type<constExprVec> annotation_const_expr_values annotation_const_expr_value
Andreas Huber3599d922016-08-09 10:42:57 -0700120%type<annotationParam> annotation_param
121%type<annotationParams> opt_annotation_params annotation_params
122%type<annotation> annotation
123%type<annotations> opt_annotations
Andreas Huberc9410c72016-07-28 12:18:40 -0700124
125%start program
126
127%union {
128 const char *str;
129 android::Type *type;
Yifan Hongae16eed2016-09-23 13:25:25 -0700130 android::FQName *fqName;
Andreas Huberc9410c72016-07-28 12:18:40 -0700131 android::CompoundType *compoundType;
132 android::CompoundField *field;
Andreas Huber881227d2016-08-02 14:20:21 -0700133 std::vector<android::CompoundField *> *fields;
Andreas Huberc9410c72016-07-28 12:18:40 -0700134 android::EnumValue *enumValue;
Yifan Hong52165692016-08-12 18:06:40 -0700135 android::ConstantExpression *constantExpression;
Andreas Huber881227d2016-08-02 14:20:21 -0700136 std::vector<android::EnumValue *> *enumValues;
Andreas Huberc9410c72016-07-28 12:18:40 -0700137 android::TypedVar *typedVar;
Andreas Huber881227d2016-08-02 14:20:21 -0700138 std::vector<android::TypedVar *> *typedVars;
Andreas Huberc9410c72016-07-28 12:18:40 -0700139 android::Method *method;
140 android::CompoundType::Style compoundStyle;
Andreas Huber3599d922016-08-09 10:42:57 -0700141 std::vector<std::string> *stringVec;
Yifan Hongf24fa852016-09-23 11:03:15 -0700142 std::vector<android::ConstantExpression *> *constExprVec;
Steven Morelandd537ab02016-09-12 10:32:01 -0700143 android::AnnotationParam *annotationParam;
144 android::AnnotationParamVector *annotationParams;
Andreas Huber3599d922016-08-09 10:42:57 -0700145 android::Annotation *annotation;
Steven Morelandd537ab02016-09-12 10:32:01 -0700146 std::vector<android::Annotation *> *annotations;
Andreas Huberc9410c72016-07-28 12:18:40 -0700147}
148
149%%
150
Andreas Huber3599d922016-08-09 10:42:57 -0700151opt_annotations
152 : /* empty */
153 {
Steven Morelandd537ab02016-09-12 10:32:01 -0700154 $$ = new std::vector<Annotation *>;
Andreas Huber3599d922016-08-09 10:42:57 -0700155 }
156 | opt_annotations annotation
157 {
158 $$ = $1;
Steven Morelandd537ab02016-09-12 10:32:01 -0700159 $$->push_back($2);
Andreas Huber3599d922016-08-09 10:42:57 -0700160 }
161 ;
162
163annotation
164 : '@' IDENTIFIER opt_annotation_params
165 {
166 $$ = new Annotation($2, $3);
167 }
168 ;
169
170opt_annotation_params
171 : /* empty */
172 {
Steven Morelandd537ab02016-09-12 10:32:01 -0700173 $$ = new AnnotationParamVector;
Andreas Huber3599d922016-08-09 10:42:57 -0700174 }
175 | '(' annotation_params ')'
176 {
177 $$ = $2;
178 }
179 ;
180
181annotation_params
182 : annotation_param
183 {
Steven Morelandd537ab02016-09-12 10:32:01 -0700184 $$ = new AnnotationParamVector;
185 $$->push_back($1);
Andreas Huber3599d922016-08-09 10:42:57 -0700186 }
187 | annotation_params ',' annotation_param
188 {
189 $$ = $1;
Steven Morelandd537ab02016-09-12 10:32:01 -0700190 $$->push_back($3);
Andreas Huber3599d922016-08-09 10:42:57 -0700191 }
192 ;
193
194annotation_param
Yifan Hongf24fa852016-09-23 11:03:15 -0700195 : IDENTIFIER '=' annotation_string_value
196 {
197 $$ = new AnnotationParam($1, $3);
198 }
199 | IDENTIFIER '=' annotation_const_expr_value
Andreas Huber3599d922016-08-09 10:42:57 -0700200 {
Steven Morelandd537ab02016-09-12 10:32:01 -0700201 $$ = new AnnotationParam($1, $3);
Andreas Huber3599d922016-08-09 10:42:57 -0700202 }
203 ;
204
Yifan Hongf24fa852016-09-23 11:03:15 -0700205annotation_string_value
Andreas Huber3599d922016-08-09 10:42:57 -0700206 : STRING_LITERAL
207 {
208 $$ = new std::vector<std::string>;
209 $$->push_back($1);
210 }
211 | '{' annotation_string_values '}' { $$ = $2; }
212 ;
213
214annotation_string_values
215 : STRING_LITERAL
216 {
217 $$ = new std::vector<std::string>;
218 $$->push_back($1);
219 }
220 | annotation_string_values ',' STRING_LITERAL
221 {
222 $$ = $1;
223 $$->push_back($3);
224 }
225 ;
226
Yifan Hongf24fa852016-09-23 11:03:15 -0700227annotation_const_expr_value
228 : const_expr
229 {
230 $$ = new std::vector<ConstantExpression *>;
231 $$->push_back($1);
232 }
233 | '{' annotation_const_expr_values '}' { $$ = $2; }
234 ;
235
236annotation_const_expr_values
237 : const_expr
238 {
239 $$ = new std::vector<ConstantExpression *>;
240 $$->push_back($1);
241 }
242 | annotation_const_expr_values ',' const_expr
243 {
244 $$ = $1;
245 $$->push_back($3);
246 }
247 ;
248
Andreas Huberc9410c72016-07-28 12:18:40 -0700249program
Andreas Huberda51b8e2016-07-28 16:00:57 -0700250 : package imports body
Andreas Huber84f89de2016-07-28 15:39:51 -0700251 ;
252
253fqname
254 : FQNAME
255 {
Yifan Hongae16eed2016-09-23 13:25:25 -0700256 $$ = new FQName($1);
257 if(!$$->isValid()) {
258 std::cerr << "ERROR: FQName '" << $1 << "' is not valid at "
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700259 << @1
Yifan Hongae16eed2016-09-23 13:25:25 -0700260 << ".\n";
Andreas Huber84f89de2016-07-28 15:39:51 -0700261 YYERROR;
262 }
263 }
264 | IDENTIFIER
265 {
Yifan Hongae16eed2016-09-23 13:25:25 -0700266 $$ = new FQName($1);
267 if(!$$->isValid()) {
268 std::cerr << "ERROR: FQName '" << $1 << "' is not valid at "
269 << @1
270 << ".\n";
271 YYERROR;
272 }
273 }
274 ;
275
276fqtype
277 : fqname
278 {
279 $$ = ast->lookupType(*($1));
Andreas Huber84f89de2016-07-28 15:39:51 -0700280 if ($$ == NULL) {
Yifan Hongae16eed2016-09-23 13:25:25 -0700281 std::cerr << "ERROR: Failed to lookup type '" << $1->string() << "' at "
282 << @1
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700283 << "\n";
284
Andreas Huber84f89de2016-07-28 15:39:51 -0700285 YYERROR;
286 }
287 }
288 | SCALAR
289 ;
Andreas Huberc9410c72016-07-28 12:18:40 -0700290
291package
Andreas Huber84f89de2016-07-28 15:39:51 -0700292 : PACKAGE FQNAME ';'
Andreas Hubereb1081f2016-07-28 13:13:24 -0700293 {
Andreas Huber84f89de2016-07-28 15:39:51 -0700294 if (!ast->setPackage($2)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700295 std::cerr << "ERROR: Malformed package identifier '"
296 << $2
297 << "' at "
298 << @2
299 << "\n";
300
Andreas Huber84f89de2016-07-28 15:39:51 -0700301 YYERROR;
302 }
Andreas Hubereb1081f2016-07-28 13:13:24 -0700303 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700304
Andreas Huberc9410c72016-07-28 12:18:40 -0700305imports
306 : /* empty */
Andreas Huber84f89de2016-07-28 15:39:51 -0700307 | imports IMPORT FQNAME ';'
Andreas Hubereb1081f2016-07-28 13:13:24 -0700308 {
Andreas Huber68f24592016-07-29 14:53:48 -0700309 if (!ast->addImport($3)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700310 std::cerr << "ERROR: Unable to import '" << $3 << "' at " << @3
311 << "\n";
Andreas Huber68f24592016-07-29 14:53:48 -0700312
313 YYERROR;
314 }
Andreas Hubereb1081f2016-07-28 13:13:24 -0700315 }
Andreas Huber5345ec22016-07-29 13:33:27 -0700316 | imports IMPORT IDENTIFIER ';'
317 {
Andreas Huber68f24592016-07-29 14:53:48 -0700318 if (!ast->addImport($3)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700319 std::cerr << "ERROR: Unable to import '" << $3 << "' at " << @3
320 << "\n";
Andreas Huber68f24592016-07-29 14:53:48 -0700321
322 YYERROR;
323 }
Andreas Huber5345ec22016-07-29 13:33:27 -0700324 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700325 ;
326
327opt_extends
328 : /* empty */ { $$ = NULL; }
Yifan Hongae16eed2016-09-23 13:25:25 -0700329 | EXTENDS fqtype { $$ = $2; }
Andreas Huberc9410c72016-07-28 12:18:40 -0700330
331body
Zhuoyao Zhangba7e6e92016-08-10 12:19:02 -0700332 : opt_annotations INTERFACE IDENTIFIER opt_extends
Andreas Huberc9410c72016-07-28 12:18:40 -0700333 {
Zhuoyao Zhangba7e6e92016-08-10 12:19:02 -0700334 if ($4 != NULL && !$4->isInterface()) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700335 std::cerr << "ERROR: You can only extend interfaces. at" << @4
336 << "\n";
337
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700338 YYERROR;
339 }
340
Andreas Huber991b8642016-08-15 16:40:44 -0700341 if ($3[0] != 'I') {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700342 std::cerr << "ERROR: All interface names must start with an 'I' "
343 << "prefix. at " << @3 << "\n";
Andreas Huber991b8642016-08-15 16:40:44 -0700344
345 YYERROR;
346 }
347
Andreas Huber9ed827c2016-08-22 12:31:13 -0700348 Interface *iface = new Interface($3, static_cast<Interface *>($4), $1);
Andreas Hubereb1081f2016-07-28 13:13:24 -0700349
350 // Register interface immediately so it can be referenced inside
351 // definition.
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700352 std::string errorMsg;
Andreas Huber9ed827c2016-08-22 12:31:13 -0700353 if (!ast->addScopedType(iface, &errorMsg)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700354 std::cerr << "ERROR: " << errorMsg << " at " << @3 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700355 YYERROR;
356 }
Andreas Hubereb1081f2016-07-28 13:13:24 -0700357
Andreas Huberc9410c72016-07-28 12:18:40 -0700358 ast->enterScope(iface);
359 }
360 '{' interface_declarations '}' ';'
361 {
362 Interface *iface = static_cast<Interface *>(ast->scope());
363
364 ast->leaveScope();
Andreas Huberc9410c72016-07-28 12:18:40 -0700365 }
366 | type_declarations
367 ;
368
369interface_declarations
370 : /* empty */
371 | interface_declarations type_declaration
372 | interface_declarations method_declaration
373 {
374 Interface *iface = static_cast<Interface *>(ast->scope());
375 iface->addMethod($2);
376 }
377 ;
378
379type_declarations
Andreas Hubera2723d22016-07-29 15:36:07 -0700380 : /* empty */
Andreas Huberc9410c72016-07-28 12:18:40 -0700381 | type_declarations type_declaration
382 ;
383
384type_declaration
385 : named_struct_or_union_declaration ';'
386 | named_enum_declaration ';'
387 | typedef_declaration ';'
Andreas Huberc9410c72016-07-28 12:18:40 -0700388 ;
389
390typedef_declaration
391 : TYPEDEF type IDENTIFIER
392 {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700393 std::string errorMsg;
Andreas Huber39fa7182016-08-19 14:27:33 -0700394 if (!ast->addTypeDef($3, $2, &errorMsg)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700395 std::cerr << "ERROR: " << errorMsg << " at " << @3 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700396 YYERROR;
397 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700398 }
399 ;
400
Yifan Hong52165692016-08-12 18:06:40 -0700401const_expr
Yifan Hongf24fa852016-09-23 11:03:15 -0700402 : INTEGER { $$ = new ConstantExpression($1); }
Yifan Hongb44a6c82016-09-22 15:50:18 -0700403 | fqname
404 {
Yifan Hongf24fa852016-09-23 11:03:15 -0700405 if(!$1->isValidValueName()) {
406 std::cerr << "ERROR: '" << $1->string()
407 << "' does not refer to an enum value at "
408 << @1 << ".\n";
409 YYERROR;
410 }
411 if($1->isIdentifier()) {
412 std::string identifier = $1->name();
413 LocalIdentifier *iden = ast->scope()->lookupIdentifier(identifier);
414 if(!iden) {
415 std::cerr << "ERROR: at " << @1 << ", identifier " << $1
416 << " could not be found.\n";
417 YYERROR;
418 }
419 if(!iden->isEnumValue()) {
420 std::cerr << "ERROR: at " << @1 << ", identifier " << $1
421 << " is not an enum value.\n";
422 YYERROR;
423 }
424 $$ = new ConstantExpression(
425 *(static_cast<EnumValue *>(iden)->constExpr()), $1->string());
426 } else {
427 std::string errorMsg;
428 EnumValue *v = ast->lookupEnumValue(*($1), &errorMsg);
429 if(v == nullptr) {
430 std::cerr << "ERROR: " << errorMsg << " at " << @1 << ".\n";
431 YYERROR;
432 }
433 $$ = new ConstantExpression(*(v->constExpr()), $1->string());
434 }
Yifan Hongb44a6c82016-09-22 15:50:18 -0700435 }
Yifan Hong52165692016-08-12 18:06:40 -0700436 | const_expr '?' const_expr ':' const_expr
437 {
Yifan Hongb44a6c82016-09-22 15:50:18 -0700438 $$ = new ConstantExpression($1, $3, $5);
Yifan Hong52165692016-08-12 18:06:40 -0700439 }
440 | const_expr LOGICAL_OR const_expr { $$ = new ConstantExpression($1, "||", $3); }
441 | const_expr LOGICAL_AND const_expr { $$ = new ConstantExpression($1, "&&", $3); }
442 | const_expr '|' const_expr { $$ = new ConstantExpression($1, "|" , $3); }
443 | const_expr '^' const_expr { $$ = new ConstantExpression($1, "^" , $3); }
444 | const_expr '&' const_expr { $$ = new ConstantExpression($1, "&" , $3); }
445 | const_expr EQUALITY const_expr { $$ = new ConstantExpression($1, "==", $3); }
446 | const_expr NEQ const_expr { $$ = new ConstantExpression($1, "!=", $3); }
447 | const_expr '<' const_expr { $$ = new ConstantExpression($1, "<" , $3); }
448 | const_expr '>' const_expr { $$ = new ConstantExpression($1, ">" , $3); }
449 | const_expr LEQ const_expr { $$ = new ConstantExpression($1, "<=", $3); }
450 | const_expr GEQ const_expr { $$ = new ConstantExpression($1, ">=", $3); }
451 | const_expr LSHIFT const_expr { $$ = new ConstantExpression($1, "<<", $3); }
452 | const_expr RSHIFT 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 '*' const_expr { $$ = new ConstantExpression($1, "*" , $3); }
456 | const_expr '/' const_expr { $$ = new ConstantExpression($1, "/" , $3); }
457 | const_expr '%' const_expr { $$ = new ConstantExpression($1, "%" , $3); }
458 | '+' const_expr %prec UNARY_PLUS { $$ = new ConstantExpression("+", $2); }
459 | '-' const_expr %prec UNARY_MINUS { $$ = new ConstantExpression("-", $2); }
460 | '!' const_expr { $$ = new ConstantExpression("!", $2); }
461 | '~' const_expr { $$ = new ConstantExpression("~", $2); }
462 | '(' const_expr ')' { $$ = $2; }
463 ;
464
Andreas Huberc9410c72016-07-28 12:18:40 -0700465method_declaration
Andreas Huber3599d922016-08-09 10:42:57 -0700466 : opt_annotations IDENTIFIER '(' typed_vars ')' ';'
Andreas Huberc9410c72016-07-28 12:18:40 -0700467 {
Iliyan Malchev639bff82016-08-13 14:24:11 -0700468 $$ = new Method($2, $4, new std::vector<TypedVar *>, false, $1);
469 }
470 | opt_annotations ONEWAY IDENTIFIER '(' typed_vars ')' ';'
471 {
472 $$ = new Method($3, $5, new std::vector<TypedVar *>, true, $1);
Andreas Huberc9410c72016-07-28 12:18:40 -0700473 }
Andreas Huber3599d922016-08-09 10:42:57 -0700474 | opt_annotations IDENTIFIER '(' typed_vars ')' GENERATES '(' typed_vars ')' ';'
Andreas Huberc9410c72016-07-28 12:18:40 -0700475 {
Iliyan Malchev639bff82016-08-13 14:24:11 -0700476 $$ = new Method($2, $4, $8, false, $1);
Andreas Huberc9410c72016-07-28 12:18:40 -0700477 }
478 ;
479
480typed_vars
481 : /* empty */
482 {
Andreas Huber881227d2016-08-02 14:20:21 -0700483 $$ = new std::vector<TypedVar *>;
Andreas Huberc9410c72016-07-28 12:18:40 -0700484 }
485 | typed_var
486 {
Andreas Huber881227d2016-08-02 14:20:21 -0700487 $$ = new std::vector<TypedVar *>;
Andreas Huberc9410c72016-07-28 12:18:40 -0700488 $$->push_back($1);
489 }
490 | typed_vars ',' typed_var
491 {
492 $$ = $1;
493 $$->push_back($3);
494 }
495 ;
496
497typed_var : type IDENTIFIER { $$ = new TypedVar($2, $1); }
498 ;
499
500
501struct_or_union_keyword
502 : STRUCT { $$ = CompoundType::STYLE_STRUCT; }
503 | UNION { $$ = CompoundType::STYLE_UNION; }
504 ;
505
506named_struct_or_union_declaration
507 : struct_or_union_keyword IDENTIFIER
508 {
Andreas Huber9ed827c2016-08-22 12:31:13 -0700509 CompoundType *container = new CompoundType($1, $2);
Andreas Huberc9410c72016-07-28 12:18:40 -0700510 ast->enterScope(container);
511 }
512 struct_or_union_body
513 {
514 CompoundType *container = static_cast<CompoundType *>(ast->scope());
515
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700516 std::string errorMsg;
517 if (!container->setFields($4, &errorMsg)) {
518 std::cerr << "ERROR: " << errorMsg << " at " << @4 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700519 YYERROR;
520 }
521
Andreas Huberc9410c72016-07-28 12:18:40 -0700522 ast->leaveScope();
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700523
Andreas Huber9ed827c2016-08-22 12:31:13 -0700524 if (!ast->addScopedType(container, &errorMsg)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700525 std::cerr << "ERROR: " << errorMsg << " at " << @2 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700526 YYERROR;
527 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700528 }
529 ;
530
531struct_or_union_declaration
532 : struct_or_union_keyword optIdentifier
533 {
Andreas Huber9ed827c2016-08-22 12:31:13 -0700534 const char *localName = $2;
535 std::string anonName;
536 if (localName == nullptr) {
537 anonName = ast->scope()->pickUniqueAnonymousName();
538 localName = anonName.c_str();
539 }
540
541 CompoundType *container = new CompoundType($1, localName);
Andreas Huberc9410c72016-07-28 12:18:40 -0700542 ast->enterScope(container);
543 }
544 struct_or_union_body
545 {
546 CompoundType *container = static_cast<CompoundType *>(ast->scope());
547
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700548 std::string errorMsg;
549 if (!container->setFields($4, &errorMsg)) {
550 std::cerr << "ERROR: " << errorMsg << " at " << @4 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700551 YYERROR;
552 }
553
Andreas Huberc9410c72016-07-28 12:18:40 -0700554 ast->leaveScope();
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700555
Andreas Huber9ed827c2016-08-22 12:31:13 -0700556 if (!ast->addScopedType(container, &errorMsg)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700557 std::cerr << "ERROR: " << errorMsg << " at " << @2 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700558 YYERROR;
559 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700560
Andreas Huberfd4afab2016-08-03 13:02:57 -0700561 $$ = container->ref();
Andreas Huberc9410c72016-07-28 12:18:40 -0700562 }
563 ;
564
565struct_or_union_body
566 : '{' field_declarations '}' { $$ = $2; }
567 ;
568
569field_declarations
Andreas Huber881227d2016-08-02 14:20:21 -0700570 : /* empty */ { $$ = new std::vector<CompoundField *>; }
Andreas Huberc9410c72016-07-28 12:18:40 -0700571 | field_declarations field_declaration
572 {
573 $$ = $1;
574
575 if ($2 != NULL) {
576 $$->push_back($2);
577 }
578 }
579 ;
580
581field_declaration
582 : type IDENTIFIER ';' { $$ = new CompoundField($2, $1); }
583 | struct_or_union_declaration ';' { $$ = NULL; }
584 | enum_declaration ';' { $$ = NULL; }
585 ;
586
587opt_storage_type
588 : /* empty */ { $$ = NULL; }
Yifan Hongae16eed2016-09-23 13:25:25 -0700589 | ':' fqtype
Andreas Huber8d3ac0c2016-08-04 14:49:23 -0700590 {
591 $$ = $2;
592
593 if ($$ != NULL && !$$->isValidEnumStorageType()) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700594 std::cerr << "ERROR: Invalid enum storage type specified. at "
595 << @2 << "\n";
596
Andreas Huber8d3ac0c2016-08-04 14:49:23 -0700597 YYABORT;
598 }
599 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700600 ;
601
602opt_comma
603 : /* empty */
604 | ','
605 ;
606
607named_enum_declaration
Yifan Hongf24fa852016-09-23 11:03:15 -0700608 : ENUM IDENTIFIER opt_storage_type
Andreas Huberc9410c72016-07-28 12:18:40 -0700609 {
Yifan Hongf24fa852016-09-23 11:03:15 -0700610 ast->enterScope(new EnumType($2, $3));
611 }
612 enum_declaration_body
613 {
614 EnumType *enumType = static_cast<EnumType *>(ast->scope());
615 ast->leaveScope();
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700616
617 std::string errorMsg;
Andreas Huber9ed827c2016-08-22 12:31:13 -0700618 if (!ast->addScopedType(enumType, &errorMsg)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700619 std::cerr << "ERROR: " << errorMsg << " at " << @2 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700620 YYERROR;
621 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700622 }
623 ;
624
625enum_declaration
Yifan Hongf24fa852016-09-23 11:03:15 -0700626 : ENUM
Andreas Huberc9410c72016-07-28 12:18:40 -0700627 {
Andreas Huber9ed827c2016-08-22 12:31:13 -0700628 std::string anonName = ast->scope()->pickUniqueAnonymousName();
Yifan Hongf24fa852016-09-23 11:03:15 -0700629 ast->enterScope(new EnumType(anonName.c_str()));
630 }
631 enum_declaration_body
632 {
Andreas Huber9ed827c2016-08-22 12:31:13 -0700633
Yifan Hongf24fa852016-09-23 11:03:15 -0700634 EnumType *enumType = static_cast<EnumType *>(ast->scope());
635 ast->leaveScope();
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700636
637 std::string errorMsg;
Andreas Huber9ed827c2016-08-22 12:31:13 -0700638 if (!ast->addScopedType(enumType, &errorMsg)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700639 // This should never fail.
640 std::cerr << "ERROR: " << errorMsg << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700641 YYERROR;
642 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700643
Andreas Huberfd4afab2016-08-03 13:02:57 -0700644 $$ = enumType->ref();
Andreas Huberc9410c72016-07-28 12:18:40 -0700645 }
Yifan Hongf24fa852016-09-23 11:03:15 -0700646 | ENUM IDENTIFIER opt_storage_type
Andreas Huberc9410c72016-07-28 12:18:40 -0700647 {
Yifan Hongf24fa852016-09-23 11:03:15 -0700648 ast->enterScope(new EnumType($2, $3));
649 }
650 enum_declaration_body
651 {
652 EnumType *enumType = static_cast<EnumType *>(ast->scope());
653 ast->leaveScope();
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700654
655 std::string errorMsg;
Andreas Huber9ed827c2016-08-22 12:31:13 -0700656 if (!ast->addScopedType(enumType, &errorMsg)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700657 std::cerr << "ERROR: " << errorMsg << " at " << @2 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700658 YYERROR;
659 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700660
Andreas Huberfd4afab2016-08-03 13:02:57 -0700661 $$ = enumType->ref();
Andreas Huberc9410c72016-07-28 12:18:40 -0700662 }
663 ;
664
Yifan Hongf24fa852016-09-23 11:03:15 -0700665enum_declaration_body
666 : '{' enum_values opt_comma '}' { $$ = $2; }
667 ;
668
Andreas Huberc9410c72016-07-28 12:18:40 -0700669enum_value
670 : IDENTIFIER { $$ = new EnumValue($1); }
Yifan Hong57886972016-08-17 10:42:15 -0700671 | IDENTIFIER '=' const_expr { $$ = new EnumValue($1, $3); }
Andreas Huberc9410c72016-07-28 12:18:40 -0700672 ;
673
674enum_values
675 : /* empty */
Yifan Hongf24fa852016-09-23 11:03:15 -0700676 { /* do nothing */ }
Andreas Huberc9410c72016-07-28 12:18:40 -0700677 | enum_value
678 {
Yifan Hongf24fa852016-09-23 11:03:15 -0700679 static_cast<EnumType *>(ast->scope())->addValue($1);
Andreas Huberc9410c72016-07-28 12:18:40 -0700680 }
681 | enum_values ',' enum_value
682 {
Yifan Hongf24fa852016-09-23 11:03:15 -0700683 static_cast<EnumType *>(ast->scope())->addValue($3);
Andreas Huberc9410c72016-07-28 12:18:40 -0700684 }
685 ;
686
687type
Yifan Hongae16eed2016-09-23 13:25:25 -0700688 : fqtype { $$ = $1; }
Yifan Hongf24fa852016-09-23 11:03:15 -0700689 | fqtype '[' const_expr ']'
Andreas Huberb95ea8a2016-08-15 15:35:42 -0700690 {
Andreas Huber295ad302016-08-16 11:35:00 -0700691 if ($1->isBinder()) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700692 std::cerr << "ERROR: Arrays of interface types are not supported."
693 << " at " << @1 << "\n";
Andreas Huber70a59e12016-08-16 12:57:01 -0700694
Andreas Huberb95ea8a2016-08-15 15:35:42 -0700695 YYERROR;
696 }
697
Andreas Huber709b62d2016-09-19 11:21:18 -0700698 if ($1->isArray()) {
Yifan Hongf24fa852016-09-23 11:03:15 -0700699 $$ = new ArrayType(static_cast<ArrayType *>($1), $3);
Andreas Huber709b62d2016-09-19 11:21:18 -0700700 } else {
Yifan Hongf24fa852016-09-23 11:03:15 -0700701 $$ = new ArrayType($1, $3);
Andreas Huber709b62d2016-09-19 11:21:18 -0700702 }
Andreas Huberb95ea8a2016-08-15 15:35:42 -0700703 }
Yifan Hongae16eed2016-09-23 13:25:25 -0700704 | VEC '<' fqtype '>'
Andreas Huberb95ea8a2016-08-15 15:35:42 -0700705 {
Andreas Huber295ad302016-08-16 11:35:00 -0700706 if ($3->isBinder()) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700707 std::cerr << "ERROR: Vectors of interface types are not "
708 << "supported. at " << @3 << "\n";
Andreas Huber70a59e12016-08-16 12:57:01 -0700709
Andreas Huberb95ea8a2016-08-15 15:35:42 -0700710 YYERROR;
711 }
712
713 $$ = new VectorType($3);
714 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700715 | struct_or_union_declaration { $$ = $1; }
716 | enum_declaration { $$ = $1; }
Andreas Huber295ad302016-08-16 11:35:00 -0700717 | INTERFACE { $$ = new GenericBinder; }
Andreas Huberc9410c72016-07-28 12:18:40 -0700718 ;
719
720optIdentifier
721 : /* empty */ { $$ = NULL; }
722 | IDENTIFIER { $$ = $1; }
723 ;
724
725%%
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700726
727#include <android-base/logging.h>
728
729void yy::parser::error(
730 const yy::parser::location_type &where,
731 const std::string &errstr) {
732 std::cerr << "ERROR: " << errstr << " at " << where << "\n";
733}
734