blob: 31568b8127c19e8839cfaedbbc9460fc17473211 [file] [log] [blame]
Andreas Huberc9410c72016-07-28 12:18:40 -07001%{
2
Andreas Huber3599d922016-08-09 10:42:57 -07003#include "Annotation.h"
Andreas Huberc9410c72016-07-28 12:18:40 -07004#include "AST.h"
5#include "ArrayType.h"
6#include "CompoundType.h"
Yifan Hong52165692016-08-12 18:06:40 -07007#include "ConstantExpression.h"
Andreas Huberc9410c72016-07-28 12:18:40 -07008#include "EnumType.h"
Andreas Huber295ad302016-08-16 11:35:00 -07009#include "GenericBinder.h"
Andreas Huberc9410c72016-07-28 12:18:40 -070010#include "Interface.h"
11#include "Method.h"
Andreas Huberc9410c72016-07-28 12:18:40 -070012#include "VectorType.h"
13
14#include "hidl-gen_y.h"
15
16#include <stdio.h>
Andreas Huber84f89de2016-07-28 15:39:51 -070017#include <utils/String8.h>
Andreas Huberc9410c72016-07-28 12:18:40 -070018
19using namespace android;
20
Andreas Huber0d0f9a22016-08-17 10:26:11 -070021extern int yylex(yy::parser::semantic_type *, yy::parser::location_type *, void *);
Andreas Huberc9410c72016-07-28 12:18:40 -070022
23#define scanner ast->scanner()
24
25%}
26
Andreas Huber0d0f9a22016-08-17 10:26:11 -070027%initial-action {
28 // Initialize the initial location.
29 @$.begin.filename = @$.end.filename =
30 const_cast<std::string *>(&ast->getFilename());
31}
32
Andreas Huberc9410c72016-07-28 12:18:40 -070033%parse-param { android::AST *ast }
34%lex-param { void *scanner }
35%pure-parser
Andreas Huber0d0f9a22016-08-17 10:26:11 -070036%skeleton "glr.cc"
Andreas Huberc9410c72016-07-28 12:18:40 -070037
Andreas Huberc9410c72016-07-28 12:18:40 -070038%token<str> ENUM
39%token<str> EXTENDS
Andreas Huber84f89de2016-07-28 15:39:51 -070040%token<str> FQNAME
Andreas Huberc9410c72016-07-28 12:18:40 -070041%token<str> GENERATES
42%token<str> IDENTIFIER
43%token<str> IMPORT
44%token<str> INTEGER
Yifan Hong52165692016-08-12 18:06:40 -070045%token<str> FLOAT
Andreas Huberc9410c72016-07-28 12:18:40 -070046%token<str> INTERFACE
47%token<str> PACKAGE
Andreas Huber84f89de2016-07-28 15:39:51 -070048%token<type> SCALAR
Andreas Huberc9410c72016-07-28 12:18:40 -070049%token<str> STRUCT
50%token<str> STRING_LITERAL
51%token<str> TYPEDEF
52%token<str> UNION
53%token<str> VEC
Iliyan Malchev639bff82016-08-13 14:24:11 -070054%token<void> ONEWAY
Andreas Huberc9410c72016-07-28 12:18:40 -070055
Yifan Hong52165692016-08-12 18:06:40 -070056/* Operator precedence and associativity, as per
57 * http://en.cppreference.com/w/cpp/language/operator_precedence */
58/* Precedence level 15 ternary operator */
59%right '?' ':'
60/* Precedence level 13 - 14, LTR, logical operators*/
61%left LOGICAL_OR
62%left LOGICAL_AND
63/* Precedence level 10 - 12, LTR, bitwise operators*/
64%left '|'
65%left '^'
66%left '&'
67/* Precedence level 9, LTR */
68%left EQUALITY NEQ
69/* Precedence level 8, LTR */
70%left '<' '>' LEQ GEQ
71/* Precedence level 7, LTR */
72%left LSHIFT RSHIFT
73/* Precedence level 6, LTR */
74%left '+' '-'
75/* Precedence level 5, LTR */
76%left '*' '/' '%'
77/* Precedence level 3, RTL; but we have to use %left here */
78%left UNARY_MINUS UNARY_PLUS '!' '~'
79
Andreas Huberc9410c72016-07-28 12:18:40 -070080%type<str> optIdentifier package
Andreas Huber84f89de2016-07-28 15:39:51 -070081%type<type> fqname
Andreas Huberc9410c72016-07-28 12:18:40 -070082
83%type<type> type opt_storage_type
84%type<type> enum_declaration
85%type<type> struct_or_union_declaration
86%type<type> opt_extends
87
88%type<field> field_declaration
89%type<fields> field_declarations struct_or_union_body
Yifan Hong52165692016-08-12 18:06:40 -070090%type<constantExpression> const_expr
Andreas Huberc9410c72016-07-28 12:18:40 -070091%type<enumValue> enum_value
92%type<enumValues> enum_values
93%type<typedVars> typed_vars
94%type<typedVar> typed_var
95%type<method> method_declaration
96%type<compoundStyle> struct_or_union_keyword
Andreas Huber3599d922016-08-09 10:42:57 -070097%type<stringVec> annotation_string_values annotation_value
98%type<annotationParam> annotation_param
99%type<annotationParams> opt_annotation_params annotation_params
100%type<annotation> annotation
101%type<annotations> opt_annotations
Andreas Huberc9410c72016-07-28 12:18:40 -0700102
103%start program
104
105%union {
106 const char *str;
107 android::Type *type;
108 android::CompoundType *compoundType;
109 android::CompoundField *field;
Andreas Huber881227d2016-08-02 14:20:21 -0700110 std::vector<android::CompoundField *> *fields;
Andreas Huberc9410c72016-07-28 12:18:40 -0700111 android::EnumValue *enumValue;
Yifan Hong52165692016-08-12 18:06:40 -0700112 android::ConstantExpression *constantExpression;
Andreas Huber881227d2016-08-02 14:20:21 -0700113 std::vector<android::EnumValue *> *enumValues;
Andreas Huberc9410c72016-07-28 12:18:40 -0700114 android::TypedVar *typedVar;
Andreas Huber881227d2016-08-02 14:20:21 -0700115 std::vector<android::TypedVar *> *typedVars;
Andreas Huberc9410c72016-07-28 12:18:40 -0700116 android::Method *method;
117 android::CompoundType::Style compoundStyle;
Andreas Huber3599d922016-08-09 10:42:57 -0700118 std::vector<std::string> *stringVec;
119 std::pair<std::string, std::vector<std::string> *> *annotationParam;
Zhuoyao Zhang5158db42016-08-10 10:25:20 -0700120 android::DefaultKeyedVector<std::string, std::vector<std::string> *> *annotationParams;
Andreas Huber3599d922016-08-09 10:42:57 -0700121 android::Annotation *annotation;
Zhuoyao Zhang5158db42016-08-10 10:25:20 -0700122 android::DefaultKeyedVector<std::string, android::Annotation *> *annotations;
Andreas Huberc9410c72016-07-28 12:18:40 -0700123}
124
125%%
126
Andreas Huber3599d922016-08-09 10:42:57 -0700127opt_annotations
128 : /* empty */
129 {
Zhuoyao Zhang5158db42016-08-10 10:25:20 -0700130 $$ = new DefaultKeyedVector<std::string, Annotation *>;
Andreas Huber3599d922016-08-09 10:42:57 -0700131 }
132 | opt_annotations annotation
133 {
134 $$ = $1;
135 $$->add($2->name(), $2);
136 }
137 ;
138
139annotation
140 : '@' IDENTIFIER opt_annotation_params
141 {
142 $$ = new Annotation($2, $3);
143 }
144 ;
145
146opt_annotation_params
147 : /* empty */
148 {
Zhuoyao Zhang5158db42016-08-10 10:25:20 -0700149 $$ = new DefaultKeyedVector<std::string, std::vector<std::string> *>;
Andreas Huber3599d922016-08-09 10:42:57 -0700150 }
151 | '(' annotation_params ')'
152 {
153 $$ = $2;
154 }
155 ;
156
157annotation_params
158 : annotation_param
159 {
Zhuoyao Zhang5158db42016-08-10 10:25:20 -0700160 $$ = new DefaultKeyedVector<std::string, std::vector<std::string> *>;
Andreas Huber3599d922016-08-09 10:42:57 -0700161 $$->add($1->first, $1->second);
162 }
163 | annotation_params ',' annotation_param
164 {
165 $$ = $1;
166 $$->add($3->first, $3->second);
167 }
168 ;
169
170annotation_param
171 : IDENTIFIER '=' annotation_value
172 {
173 $$ = new std::pair<std::string, std::vector<std::string> *>($1, $3);
174 }
175 ;
176
177annotation_value
178 : STRING_LITERAL
179 {
180 $$ = new std::vector<std::string>;
181 $$->push_back($1);
182 }
183 | '{' annotation_string_values '}' { $$ = $2; }
184 ;
185
186annotation_string_values
187 : STRING_LITERAL
188 {
189 $$ = new std::vector<std::string>;
190 $$->push_back($1);
191 }
192 | annotation_string_values ',' STRING_LITERAL
193 {
194 $$ = $1;
195 $$->push_back($3);
196 }
197 ;
198
Andreas Huberc9410c72016-07-28 12:18:40 -0700199program
Andreas Huberda51b8e2016-07-28 16:00:57 -0700200 : package imports body
Andreas Huber84f89de2016-07-28 15:39:51 -0700201 ;
202
203fqname
204 : FQNAME
205 {
206 $$ = ast->lookupType($1);
207 if ($$ == NULL) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700208 std::cerr << "ERROR: Failed to lookup type '" << $1 << "' at "
209 << @1
210 << "\n";
211
Andreas Huber84f89de2016-07-28 15:39:51 -0700212 YYERROR;
213 }
214 }
215 | IDENTIFIER
216 {
217 $$ = ast->lookupType($1);
218 if ($$ == NULL) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700219 std::cerr << "Failed to lookup type '" << $1 << "' at " << @1
220 << "\n";
221
Andreas Huber84f89de2016-07-28 15:39:51 -0700222 YYERROR;
223 }
224 }
225 | SCALAR
226 ;
Andreas Huberc9410c72016-07-28 12:18:40 -0700227
228package
Andreas Huber84f89de2016-07-28 15:39:51 -0700229 : PACKAGE FQNAME ';'
Andreas Hubereb1081f2016-07-28 13:13:24 -0700230 {
Andreas Huber84f89de2016-07-28 15:39:51 -0700231 if (!ast->setPackage($2)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700232 std::cerr << "ERROR: Malformed package identifier '"
233 << $2
234 << "' at "
235 << @2
236 << "\n";
237
Andreas Huber84f89de2016-07-28 15:39:51 -0700238 YYERROR;
239 }
Andreas Hubereb1081f2016-07-28 13:13:24 -0700240 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700241
Andreas Huberc9410c72016-07-28 12:18:40 -0700242imports
243 : /* empty */
Andreas Huber84f89de2016-07-28 15:39:51 -0700244 | imports IMPORT FQNAME ';'
Andreas Hubereb1081f2016-07-28 13:13:24 -0700245 {
Andreas Huber68f24592016-07-29 14:53:48 -0700246 if (!ast->addImport($3)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700247 std::cerr << "ERROR: Unable to import '" << $3 << "' at " << @3
248 << "\n";
Andreas Huber68f24592016-07-29 14:53:48 -0700249
250 YYERROR;
251 }
Andreas Hubereb1081f2016-07-28 13:13:24 -0700252 }
Andreas Huber5345ec22016-07-29 13:33:27 -0700253 | imports IMPORT IDENTIFIER ';'
254 {
Andreas Huber68f24592016-07-29 14:53:48 -0700255 if (!ast->addImport($3)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700256 std::cerr << "ERROR: Unable to import '" << $3 << "' at " << @3
257 << "\n";
Andreas Huber68f24592016-07-29 14:53:48 -0700258
259 YYERROR;
260 }
Andreas Huber5345ec22016-07-29 13:33:27 -0700261 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700262 ;
263
264opt_extends
265 : /* empty */ { $$ = NULL; }
Andreas Huber84f89de2016-07-28 15:39:51 -0700266 | EXTENDS fqname { $$ = $2; }
Andreas Huberc9410c72016-07-28 12:18:40 -0700267
268body
Zhuoyao Zhangba7e6e92016-08-10 12:19:02 -0700269 : opt_annotations INTERFACE IDENTIFIER opt_extends
Andreas Huberc9410c72016-07-28 12:18:40 -0700270 {
Zhuoyao Zhangba7e6e92016-08-10 12:19:02 -0700271 if ($4 != NULL && !$4->isInterface()) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700272 std::cerr << "ERROR: You can only extend interfaces. at" << @4
273 << "\n";
274
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700275 YYERROR;
276 }
277
Andreas Huber991b8642016-08-15 16:40:44 -0700278 if ($3[0] != 'I') {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700279 std::cerr << "ERROR: All interface names must start with an 'I' "
280 << "prefix. at " << @3 << "\n";
Andreas Huber991b8642016-08-15 16:40:44 -0700281
282 YYERROR;
283 }
284
Andreas Huber9ed827c2016-08-22 12:31:13 -0700285 Interface *iface = new Interface($3, static_cast<Interface *>($4), $1);
Andreas Hubereb1081f2016-07-28 13:13:24 -0700286
287 // Register interface immediately so it can be referenced inside
288 // definition.
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700289 std::string errorMsg;
Andreas Huber9ed827c2016-08-22 12:31:13 -0700290 if (!ast->addScopedType(iface, &errorMsg)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700291 std::cerr << "ERROR: " << errorMsg << " at " << @3 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700292 YYERROR;
293 }
Andreas Hubereb1081f2016-07-28 13:13:24 -0700294
Andreas Huberc9410c72016-07-28 12:18:40 -0700295 ast->enterScope(iface);
296 }
297 '{' interface_declarations '}' ';'
298 {
299 Interface *iface = static_cast<Interface *>(ast->scope());
300
301 ast->leaveScope();
Andreas Huberc9410c72016-07-28 12:18:40 -0700302 }
303 | type_declarations
304 ;
305
306interface_declarations
307 : /* empty */
308 | interface_declarations type_declaration
309 | interface_declarations method_declaration
310 {
311 Interface *iface = static_cast<Interface *>(ast->scope());
312 iface->addMethod($2);
313 }
314 ;
315
316type_declarations
Andreas Hubera2723d22016-07-29 15:36:07 -0700317 : /* empty */
Andreas Huberc9410c72016-07-28 12:18:40 -0700318 | type_declarations type_declaration
319 ;
320
321type_declaration
322 : named_struct_or_union_declaration ';'
323 | named_enum_declaration ';'
324 | typedef_declaration ';'
Andreas Huberc9410c72016-07-28 12:18:40 -0700325 ;
326
327typedef_declaration
328 : TYPEDEF type IDENTIFIER
329 {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700330 std::string errorMsg;
Andreas Huber39fa7182016-08-19 14:27:33 -0700331 if (!ast->addTypeDef($3, $2, &errorMsg)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700332 std::cerr << "ERROR: " << errorMsg << " at " << @3 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700333 YYERROR;
334 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700335 }
336 ;
337
Yifan Hong52165692016-08-12 18:06:40 -0700338const_expr
339 : INTEGER { $$ = new ConstantExpression($1); }
340 | IDENTIFIER { $$ = new ConstantExpression($1); }
341 | const_expr '?' const_expr ':' const_expr
342 {
343 $$ = new ConstantExpression($1, $3, $5);
344 }
345 | const_expr LOGICAL_OR const_expr { $$ = new ConstantExpression($1, "||", $3); }
346 | const_expr LOGICAL_AND const_expr { $$ = new ConstantExpression($1, "&&", $3); }
347 | const_expr '|' const_expr { $$ = new ConstantExpression($1, "|" , $3); }
348 | const_expr '^' const_expr { $$ = new ConstantExpression($1, "^" , $3); }
349 | const_expr '&' const_expr { $$ = new ConstantExpression($1, "&" , $3); }
350 | const_expr EQUALITY const_expr { $$ = new ConstantExpression($1, "==", $3); }
351 | const_expr NEQ const_expr { $$ = new ConstantExpression($1, "!=", $3); }
352 | const_expr '<' const_expr { $$ = new ConstantExpression($1, "<" , $3); }
353 | const_expr '>' const_expr { $$ = new ConstantExpression($1, ">" , $3); }
354 | const_expr LEQ const_expr { $$ = new ConstantExpression($1, "<=", $3); }
355 | const_expr GEQ const_expr { $$ = new ConstantExpression($1, ">=", $3); }
356 | const_expr LSHIFT const_expr { $$ = new ConstantExpression($1, "<<", $3); }
357 | const_expr RSHIFT const_expr { $$ = new ConstantExpression($1, ">>", $3); }
358 | const_expr '+' const_expr { $$ = new ConstantExpression($1, "+" , $3); }
359 | const_expr '-' const_expr { $$ = new ConstantExpression($1, "-" , $3); }
360 | const_expr '*' const_expr { $$ = new ConstantExpression($1, "*" , $3); }
361 | const_expr '/' const_expr { $$ = new ConstantExpression($1, "/" , $3); }
362 | const_expr '%' const_expr { $$ = new ConstantExpression($1, "%" , $3); }
363 | '+' const_expr %prec UNARY_PLUS { $$ = new ConstantExpression("+", $2); }
364 | '-' const_expr %prec UNARY_MINUS { $$ = new ConstantExpression("-", $2); }
365 | '!' const_expr { $$ = new ConstantExpression("!", $2); }
366 | '~' const_expr { $$ = new ConstantExpression("~", $2); }
367 | '(' const_expr ')' { $$ = $2; }
368 ;
369
Andreas Huberc9410c72016-07-28 12:18:40 -0700370method_declaration
Andreas Huber3599d922016-08-09 10:42:57 -0700371 : opt_annotations IDENTIFIER '(' typed_vars ')' ';'
Andreas Huberc9410c72016-07-28 12:18:40 -0700372 {
Iliyan Malchev639bff82016-08-13 14:24:11 -0700373 $$ = new Method($2, $4, new std::vector<TypedVar *>, false, $1);
374 }
375 | opt_annotations ONEWAY IDENTIFIER '(' typed_vars ')' ';'
376 {
377 $$ = new Method($3, $5, new std::vector<TypedVar *>, true, $1);
Andreas Huberc9410c72016-07-28 12:18:40 -0700378 }
Andreas Huber3599d922016-08-09 10:42:57 -0700379 | opt_annotations IDENTIFIER '(' typed_vars ')' GENERATES '(' typed_vars ')' ';'
Andreas Huberc9410c72016-07-28 12:18:40 -0700380 {
Iliyan Malchev639bff82016-08-13 14:24:11 -0700381 $$ = new Method($2, $4, $8, false, $1);
Andreas Huberc9410c72016-07-28 12:18:40 -0700382 }
383 ;
384
385typed_vars
386 : /* empty */
387 {
Andreas Huber881227d2016-08-02 14:20:21 -0700388 $$ = new std::vector<TypedVar *>;
Andreas Huberc9410c72016-07-28 12:18:40 -0700389 }
390 | typed_var
391 {
Andreas Huber881227d2016-08-02 14:20:21 -0700392 $$ = new std::vector<TypedVar *>;
Andreas Huberc9410c72016-07-28 12:18:40 -0700393 $$->push_back($1);
394 }
395 | typed_vars ',' typed_var
396 {
397 $$ = $1;
398 $$->push_back($3);
399 }
400 ;
401
402typed_var : type IDENTIFIER { $$ = new TypedVar($2, $1); }
403 ;
404
405
406struct_or_union_keyword
407 : STRUCT { $$ = CompoundType::STYLE_STRUCT; }
408 | UNION { $$ = CompoundType::STYLE_UNION; }
409 ;
410
411named_struct_or_union_declaration
412 : struct_or_union_keyword IDENTIFIER
413 {
Andreas Huber9ed827c2016-08-22 12:31:13 -0700414 CompoundType *container = new CompoundType($1, $2);
Andreas Huberc9410c72016-07-28 12:18:40 -0700415 ast->enterScope(container);
416 }
417 struct_or_union_body
418 {
419 CompoundType *container = static_cast<CompoundType *>(ast->scope());
420
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700421 std::string errorMsg;
422 if (!container->setFields($4, &errorMsg)) {
423 std::cerr << "ERROR: " << errorMsg << " at " << @4 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700424 YYERROR;
425 }
426
Andreas Huberc9410c72016-07-28 12:18:40 -0700427 ast->leaveScope();
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700428
Andreas Huber9ed827c2016-08-22 12:31:13 -0700429 if (!ast->addScopedType(container, &errorMsg)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700430 std::cerr << "ERROR: " << errorMsg << " at " << @2 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700431 YYERROR;
432 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700433 }
434 ;
435
436struct_or_union_declaration
437 : struct_or_union_keyword optIdentifier
438 {
Andreas Huber9ed827c2016-08-22 12:31:13 -0700439 const char *localName = $2;
440 std::string anonName;
441 if (localName == nullptr) {
442 anonName = ast->scope()->pickUniqueAnonymousName();
443 localName = anonName.c_str();
444 }
445
446 CompoundType *container = new CompoundType($1, localName);
Andreas Huberc9410c72016-07-28 12:18:40 -0700447 ast->enterScope(container);
448 }
449 struct_or_union_body
450 {
451 CompoundType *container = static_cast<CompoundType *>(ast->scope());
452
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700453 std::string errorMsg;
454 if (!container->setFields($4, &errorMsg)) {
455 std::cerr << "ERROR: " << errorMsg << " at " << @4 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700456 YYERROR;
457 }
458
Andreas Huberc9410c72016-07-28 12:18:40 -0700459 ast->leaveScope();
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700460
Andreas Huber9ed827c2016-08-22 12:31:13 -0700461 if (!ast->addScopedType(container, &errorMsg)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700462 std::cerr << "ERROR: " << errorMsg << " at " << @2 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700463 YYERROR;
464 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700465
Andreas Huberfd4afab2016-08-03 13:02:57 -0700466 $$ = container->ref();
Andreas Huberc9410c72016-07-28 12:18:40 -0700467 }
468 ;
469
470struct_or_union_body
471 : '{' field_declarations '}' { $$ = $2; }
472 ;
473
474field_declarations
Andreas Huber881227d2016-08-02 14:20:21 -0700475 : /* empty */ { $$ = new std::vector<CompoundField *>; }
Andreas Huberc9410c72016-07-28 12:18:40 -0700476 | field_declarations field_declaration
477 {
478 $$ = $1;
479
480 if ($2 != NULL) {
481 $$->push_back($2);
482 }
483 }
484 ;
485
486field_declaration
487 : type IDENTIFIER ';' { $$ = new CompoundField($2, $1); }
488 | struct_or_union_declaration ';' { $$ = NULL; }
489 | enum_declaration ';' { $$ = NULL; }
490 ;
491
492opt_storage_type
493 : /* empty */ { $$ = NULL; }
Andreas Huber8d3ac0c2016-08-04 14:49:23 -0700494 | ':' fqname
495 {
496 $$ = $2;
497
498 if ($$ != NULL && !$$->isValidEnumStorageType()) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700499 std::cerr << "ERROR: Invalid enum storage type specified. at "
500 << @2 << "\n";
501
Andreas Huber8d3ac0c2016-08-04 14:49:23 -0700502 YYABORT;
503 }
504 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700505 ;
506
507opt_comma
508 : /* empty */
509 | ','
510 ;
511
512named_enum_declaration
513 : ENUM IDENTIFIER opt_storage_type '{' enum_values opt_comma '}'
514 {
Andreas Huber9ed827c2016-08-22 12:31:13 -0700515 EnumType *enumType = new EnumType($2, $5, $3);
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700516
517 std::string errorMsg;
Andreas Huber9ed827c2016-08-22 12:31:13 -0700518 if (!ast->addScopedType(enumType, &errorMsg)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700519 std::cerr << "ERROR: " << errorMsg << " at " << @2 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700520 YYERROR;
521 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700522 }
523 ;
524
525enum_declaration
526 : ENUM '{' enum_values opt_comma '}'
527 {
Andreas Huber9ed827c2016-08-22 12:31:13 -0700528 std::string anonName = ast->scope()->pickUniqueAnonymousName();
529
530 EnumType *enumType = new EnumType(anonName.c_str(), $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 // This should never fail.
535 std::cerr << "ERROR: " << errorMsg << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700536 YYERROR;
537 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700538
Andreas Huberfd4afab2016-08-03 13:02:57 -0700539 $$ = enumType->ref();
Andreas Huberc9410c72016-07-28 12:18:40 -0700540 }
541 | ENUM IDENTIFIER opt_storage_type '{' enum_values opt_comma '}'
542 {
Andreas Huber9ed827c2016-08-22 12:31:13 -0700543 EnumType *enumType = new EnumType($2, $5, $3);
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700544
545 std::string errorMsg;
Andreas Huber9ed827c2016-08-22 12:31:13 -0700546 if (!ast->addScopedType(enumType, &errorMsg)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700547 std::cerr << "ERROR: " << errorMsg << " at " << @2 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700548 YYERROR;
549 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700550
Andreas Huberfd4afab2016-08-03 13:02:57 -0700551 $$ = enumType->ref();
Andreas Huberc9410c72016-07-28 12:18:40 -0700552 }
553 ;
554
555enum_value
556 : IDENTIFIER { $$ = new EnumValue($1); }
Yifan Hong52165692016-08-12 18:06:40 -0700557 | IDENTIFIER '=' const_expr { $$ = new EnumValue($1, $3->value()); }
Andreas Huberc9410c72016-07-28 12:18:40 -0700558 ;
559
560enum_values
561 : /* empty */
562 {
Andreas Huber881227d2016-08-02 14:20:21 -0700563 $$ = new std::vector<EnumValue *>;
Andreas Huberc9410c72016-07-28 12:18:40 -0700564 }
565 | enum_value
566 {
Andreas Huber881227d2016-08-02 14:20:21 -0700567 $$ = new std::vector<EnumValue *>;
Andreas Huberc9410c72016-07-28 12:18:40 -0700568 $$->push_back($1);
569 }
570 | enum_values ',' enum_value
571 {
572 $$ = $1;
573 $$->push_back($3);
574 }
575 ;
576
577type
Andreas Huber84f89de2016-07-28 15:39:51 -0700578 : fqname { $$ = $1; }
Andreas Huberb95ea8a2016-08-15 15:35:42 -0700579 | fqname '[' INTEGER ']'
580 {
Andreas Huber295ad302016-08-16 11:35:00 -0700581 if ($1->isBinder()) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700582 std::cerr << "ERROR: Arrays of interface types are not supported."
583 << " at " << @1 << "\n";
Andreas Huber70a59e12016-08-16 12:57:01 -0700584
Andreas Huberb95ea8a2016-08-15 15:35:42 -0700585 YYERROR;
586 }
587
588 $$ = new ArrayType($1, $3);
589 }
590 | VEC '<' fqname '>'
591 {
Andreas Huber295ad302016-08-16 11:35:00 -0700592 if ($3->isBinder()) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700593 std::cerr << "ERROR: Vectors of interface types are not "
594 << "supported. at " << @3 << "\n";
Andreas Huber70a59e12016-08-16 12:57:01 -0700595
Andreas Huberb95ea8a2016-08-15 15:35:42 -0700596 YYERROR;
597 }
598
599 $$ = new VectorType($3);
600 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700601 | struct_or_union_declaration { $$ = $1; }
602 | enum_declaration { $$ = $1; }
Andreas Huber295ad302016-08-16 11:35:00 -0700603 | INTERFACE { $$ = new GenericBinder; }
Andreas Huberc9410c72016-07-28 12:18:40 -0700604 ;
605
606optIdentifier
607 : /* empty */ { $$ = NULL; }
608 | IDENTIFIER { $$ = $1; }
609 ;
610
611%%
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700612
613#include <android-base/logging.h>
614
615void yy::parser::error(
616 const yy::parser::location_type &where,
617 const std::string &errstr) {
618 std::cerr << "ERROR: " << errstr << " at " << where << "\n";
619}
620