blob: 55fee101254a83eaae31f8419df1acaf22e2663f [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 "TypeDef.h"
13#include "VectorType.h"
14
15#include "hidl-gen_y.h"
16
17#include <stdio.h>
Andreas Huber84f89de2016-07-28 15:39:51 -070018#include <utils/String8.h>
Andreas Huberc9410c72016-07-28 12:18:40 -070019
20using namespace android;
21
Andreas Huber0d0f9a22016-08-17 10:26:11 -070022extern int yylex(yy::parser::semantic_type *, yy::parser::location_type *, void *);
Andreas Huberc9410c72016-07-28 12:18:40 -070023
24#define scanner ast->scanner()
25
26%}
27
Andreas Huber0d0f9a22016-08-17 10:26:11 -070028%initial-action {
29 // Initialize the initial location.
30 @$.begin.filename = @$.end.filename =
31 const_cast<std::string *>(&ast->getFilename());
32}
33
Andreas Huberc9410c72016-07-28 12:18:40 -070034%parse-param { android::AST *ast }
35%lex-param { void *scanner }
36%pure-parser
Andreas Huber0d0f9a22016-08-17 10:26:11 -070037%skeleton "glr.cc"
Andreas Huberc9410c72016-07-28 12:18:40 -070038
Andreas Huberc9410c72016-07-28 12:18:40 -070039%token<str> ENUM
40%token<str> EXTENDS
Andreas Huber84f89de2016-07-28 15:39:51 -070041%token<str> FQNAME
Andreas Huberc9410c72016-07-28 12:18:40 -070042%token<str> GENERATES
43%token<str> IDENTIFIER
44%token<str> IMPORT
45%token<str> INTEGER
Yifan Hong52165692016-08-12 18:06:40 -070046%token<str> FLOAT
Andreas Huberc9410c72016-07-28 12:18:40 -070047%token<str> INTERFACE
48%token<str> PACKAGE
Andreas Huber84f89de2016-07-28 15:39:51 -070049%token<type> SCALAR
Andreas Huberc9410c72016-07-28 12:18:40 -070050%token<str> STRUCT
51%token<str> STRING_LITERAL
52%token<str> TYPEDEF
53%token<str> UNION
54%token<str> VEC
Iliyan Malchev639bff82016-08-13 14:24:11 -070055%token<void> ONEWAY
Andreas Huberc9410c72016-07-28 12:18:40 -070056
Yifan Hong52165692016-08-12 18:06:40 -070057/* Operator precedence and associativity, as per
58 * http://en.cppreference.com/w/cpp/language/operator_precedence */
59/* Precedence level 15 ternary operator */
60%right '?' ':'
61/* Precedence level 13 - 14, LTR, logical operators*/
62%left LOGICAL_OR
63%left LOGICAL_AND
64/* Precedence level 10 - 12, LTR, bitwise operators*/
65%left '|'
66%left '^'
67%left '&'
68/* Precedence level 9, LTR */
69%left EQUALITY NEQ
70/* Precedence level 8, LTR */
71%left '<' '>' LEQ GEQ
72/* Precedence level 7, LTR */
73%left LSHIFT RSHIFT
74/* Precedence level 6, LTR */
75%left '+' '-'
76/* Precedence level 5, LTR */
77%left '*' '/' '%'
78/* Precedence level 3, RTL; but we have to use %left here */
79%left UNARY_MINUS UNARY_PLUS '!' '~'
80
Andreas Huberc9410c72016-07-28 12:18:40 -070081%type<str> optIdentifier package
Andreas Huber84f89de2016-07-28 15:39:51 -070082%type<type> fqname
Andreas Huberc9410c72016-07-28 12:18:40 -070083
84%type<type> type opt_storage_type
85%type<type> enum_declaration
86%type<type> struct_or_union_declaration
87%type<type> opt_extends
88
89%type<field> field_declaration
90%type<fields> field_declarations struct_or_union_body
Yifan Hong52165692016-08-12 18:06:40 -070091%type<constantExpression> const_expr
Andreas Huberc9410c72016-07-28 12:18:40 -070092%type<enumValue> enum_value
93%type<enumValues> enum_values
94%type<typedVars> typed_vars
95%type<typedVar> typed_var
96%type<method> method_declaration
97%type<compoundStyle> struct_or_union_keyword
Andreas Huber3599d922016-08-09 10:42:57 -070098%type<stringVec> annotation_string_values annotation_value
99%type<annotationParam> annotation_param
100%type<annotationParams> opt_annotation_params annotation_params
101%type<annotation> annotation
102%type<annotations> opt_annotations
Andreas Huberc9410c72016-07-28 12:18:40 -0700103
104%start program
105
106%union {
107 const char *str;
108 android::Type *type;
109 android::CompoundType *compoundType;
110 android::CompoundField *field;
Andreas Huber881227d2016-08-02 14:20:21 -0700111 std::vector<android::CompoundField *> *fields;
Andreas Huberc9410c72016-07-28 12:18:40 -0700112 android::EnumValue *enumValue;
Yifan Hong52165692016-08-12 18:06:40 -0700113 android::ConstantExpression *constantExpression;
Andreas Huber881227d2016-08-02 14:20:21 -0700114 std::vector<android::EnumValue *> *enumValues;
Andreas Huberc9410c72016-07-28 12:18:40 -0700115 android::TypedVar *typedVar;
Andreas Huber881227d2016-08-02 14:20:21 -0700116 std::vector<android::TypedVar *> *typedVars;
Andreas Huberc9410c72016-07-28 12:18:40 -0700117 android::Method *method;
118 android::CompoundType::Style compoundStyle;
Andreas Huber3599d922016-08-09 10:42:57 -0700119 std::vector<std::string> *stringVec;
120 std::pair<std::string, std::vector<std::string> *> *annotationParam;
Zhuoyao Zhang5158db42016-08-10 10:25:20 -0700121 android::DefaultKeyedVector<std::string, std::vector<std::string> *> *annotationParams;
Andreas Huber3599d922016-08-09 10:42:57 -0700122 android::Annotation *annotation;
Zhuoyao Zhang5158db42016-08-10 10:25:20 -0700123 android::DefaultKeyedVector<std::string, android::Annotation *> *annotations;
Andreas Huberc9410c72016-07-28 12:18:40 -0700124}
125
126%%
127
Andreas Huber3599d922016-08-09 10:42:57 -0700128opt_annotations
129 : /* empty */
130 {
Zhuoyao Zhang5158db42016-08-10 10:25:20 -0700131 $$ = new DefaultKeyedVector<std::string, Annotation *>;
Andreas Huber3599d922016-08-09 10:42:57 -0700132 }
133 | opt_annotations annotation
134 {
135 $$ = $1;
136 $$->add($2->name(), $2);
137 }
138 ;
139
140annotation
141 : '@' IDENTIFIER opt_annotation_params
142 {
143 $$ = new Annotation($2, $3);
144 }
145 ;
146
147opt_annotation_params
148 : /* empty */
149 {
Zhuoyao Zhang5158db42016-08-10 10:25:20 -0700150 $$ = new DefaultKeyedVector<std::string, std::vector<std::string> *>;
Andreas Huber3599d922016-08-09 10:42:57 -0700151 }
152 | '(' annotation_params ')'
153 {
154 $$ = $2;
155 }
156 ;
157
158annotation_params
159 : annotation_param
160 {
Zhuoyao Zhang5158db42016-08-10 10:25:20 -0700161 $$ = new DefaultKeyedVector<std::string, std::vector<std::string> *>;
Andreas Huber3599d922016-08-09 10:42:57 -0700162 $$->add($1->first, $1->second);
163 }
164 | annotation_params ',' annotation_param
165 {
166 $$ = $1;
167 $$->add($3->first, $3->second);
168 }
169 ;
170
171annotation_param
172 : IDENTIFIER '=' annotation_value
173 {
174 $$ = new std::pair<std::string, std::vector<std::string> *>($1, $3);
175 }
176 ;
177
178annotation_value
179 : STRING_LITERAL
180 {
181 $$ = new std::vector<std::string>;
182 $$->push_back($1);
183 }
184 | '{' annotation_string_values '}' { $$ = $2; }
185 ;
186
187annotation_string_values
188 : STRING_LITERAL
189 {
190 $$ = new std::vector<std::string>;
191 $$->push_back($1);
192 }
193 | annotation_string_values ',' STRING_LITERAL
194 {
195 $$ = $1;
196 $$->push_back($3);
197 }
198 ;
199
Andreas Huberc9410c72016-07-28 12:18:40 -0700200program
Andreas Huberda51b8e2016-07-28 16:00:57 -0700201 : package imports body
Andreas Huber84f89de2016-07-28 15:39:51 -0700202 ;
203
204fqname
205 : FQNAME
206 {
207 $$ = ast->lookupType($1);
208 if ($$ == NULL) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700209 std::cerr << "ERROR: Failed to lookup type '" << $1 << "' at "
210 << @1
211 << "\n";
212
Andreas Huber84f89de2016-07-28 15:39:51 -0700213 YYERROR;
214 }
215 }
216 | IDENTIFIER
217 {
218 $$ = ast->lookupType($1);
219 if ($$ == NULL) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700220 std::cerr << "Failed to lookup type '" << $1 << "' at " << @1
221 << "\n";
222
Andreas Huber84f89de2016-07-28 15:39:51 -0700223 YYERROR;
224 }
225 }
226 | SCALAR
227 ;
Andreas Huberc9410c72016-07-28 12:18:40 -0700228
229package
Andreas Huber84f89de2016-07-28 15:39:51 -0700230 : PACKAGE FQNAME ';'
Andreas Hubereb1081f2016-07-28 13:13:24 -0700231 {
Andreas Huber84f89de2016-07-28 15:39:51 -0700232 if (!ast->setPackage($2)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700233 std::cerr << "ERROR: Malformed package identifier '"
234 << $2
235 << "' at "
236 << @2
237 << "\n";
238
Andreas Huber84f89de2016-07-28 15:39:51 -0700239 YYERROR;
240 }
Andreas Hubereb1081f2016-07-28 13:13:24 -0700241 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700242
Andreas Huberc9410c72016-07-28 12:18:40 -0700243imports
244 : /* empty */
Andreas Huber84f89de2016-07-28 15:39:51 -0700245 | imports IMPORT FQNAME ';'
Andreas Hubereb1081f2016-07-28 13:13:24 -0700246 {
Andreas Huber68f24592016-07-29 14:53:48 -0700247 if (!ast->addImport($3)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700248 std::cerr << "ERROR: Unable to import '" << $3 << "' at " << @3
249 << "\n";
Andreas Huber68f24592016-07-29 14:53:48 -0700250
251 YYERROR;
252 }
Andreas Hubereb1081f2016-07-28 13:13:24 -0700253 }
Andreas Huber5345ec22016-07-29 13:33:27 -0700254 | imports IMPORT IDENTIFIER ';'
255 {
Andreas Huber68f24592016-07-29 14:53:48 -0700256 if (!ast->addImport($3)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700257 std::cerr << "ERROR: Unable to import '" << $3 << "' at " << @3
258 << "\n";
Andreas Huber68f24592016-07-29 14:53:48 -0700259
260 YYERROR;
261 }
Andreas Huber5345ec22016-07-29 13:33:27 -0700262 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700263 ;
264
265opt_extends
266 : /* empty */ { $$ = NULL; }
Andreas Huber84f89de2016-07-28 15:39:51 -0700267 | EXTENDS fqname { $$ = $2; }
Andreas Huberc9410c72016-07-28 12:18:40 -0700268
269body
Zhuoyao Zhangba7e6e92016-08-10 12:19:02 -0700270 : opt_annotations INTERFACE IDENTIFIER opt_extends
Andreas Huberc9410c72016-07-28 12:18:40 -0700271 {
Zhuoyao Zhangba7e6e92016-08-10 12:19:02 -0700272 if ($4 != NULL && !$4->isInterface()) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700273 std::cerr << "ERROR: You can only extend interfaces. at" << @4
274 << "\n";
275
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700276 YYERROR;
277 }
278
Andreas Huber991b8642016-08-15 16:40:44 -0700279 if ($3[0] != 'I') {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700280 std::cerr << "ERROR: All interface names must start with an 'I' "
281 << "prefix. at " << @3 << "\n";
Andreas Huber991b8642016-08-15 16:40:44 -0700282
283 YYERROR;
284 }
285
Zhuoyao Zhangba7e6e92016-08-10 12:19:02 -0700286 Interface *iface = new Interface(static_cast<Interface *>($4), $1);
Andreas Hubereb1081f2016-07-28 13:13:24 -0700287
288 // Register interface immediately so it can be referenced inside
289 // definition.
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700290 std::string errorMsg;
291 if (!ast->addScopedType($3, iface, &errorMsg)) {
292 std::cerr << "ERROR: " << errorMsg << " at " << @3 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700293 YYERROR;
294 }
Andreas Hubereb1081f2016-07-28 13:13:24 -0700295
Andreas Huberc9410c72016-07-28 12:18:40 -0700296 ast->enterScope(iface);
297 }
298 '{' interface_declarations '}' ';'
299 {
300 Interface *iface = static_cast<Interface *>(ast->scope());
301
302 ast->leaveScope();
Andreas Huberc9410c72016-07-28 12:18:40 -0700303 }
304 | type_declarations
305 ;
306
307interface_declarations
308 : /* empty */
309 | interface_declarations type_declaration
310 | interface_declarations method_declaration
311 {
312 Interface *iface = static_cast<Interface *>(ast->scope());
313 iface->addMethod($2);
314 }
315 ;
316
317type_declarations
Andreas Hubera2723d22016-07-29 15:36:07 -0700318 : /* empty */
Andreas Huberc9410c72016-07-28 12:18:40 -0700319 | type_declarations type_declaration
320 ;
321
322type_declaration
323 : named_struct_or_union_declaration ';'
324 | named_enum_declaration ';'
325 | typedef_declaration ';'
Andreas Huberc9410c72016-07-28 12:18:40 -0700326 ;
327
328typedef_declaration
329 : TYPEDEF type IDENTIFIER
330 {
Andreas Huber31629bc2016-08-03 09:06:40 -0700331 TypeDef *def = new TypeDef($2);
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700332
333 std::string errorMsg;
334 if (!ast->addScopedType($3, def, &errorMsg)) {
335 std::cerr << "ERROR: " << errorMsg << " at " << @3 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700336 YYERROR;
337 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700338 }
339 ;
340
Yifan Hong52165692016-08-12 18:06:40 -0700341const_expr
342 : INTEGER { $$ = new ConstantExpression($1); }
343 | IDENTIFIER { $$ = new ConstantExpression($1); }
344 | const_expr '?' const_expr ':' const_expr
345 {
346 $$ = new ConstantExpression($1, $3, $5);
347 }
348 | const_expr LOGICAL_OR const_expr { $$ = new ConstantExpression($1, "||", $3); }
349 | const_expr LOGICAL_AND const_expr { $$ = new ConstantExpression($1, "&&", $3); }
350 | const_expr '|' const_expr { $$ = new ConstantExpression($1, "|" , $3); }
351 | const_expr '^' const_expr { $$ = new ConstantExpression($1, "^" , $3); }
352 | const_expr '&' const_expr { $$ = new ConstantExpression($1, "&" , $3); }
353 | const_expr EQUALITY const_expr { $$ = new ConstantExpression($1, "==", $3); }
354 | const_expr NEQ const_expr { $$ = new ConstantExpression($1, "!=", $3); }
355 | const_expr '<' const_expr { $$ = new ConstantExpression($1, "<" , $3); }
356 | const_expr '>' const_expr { $$ = new ConstantExpression($1, ">" , $3); }
357 | const_expr LEQ const_expr { $$ = new ConstantExpression($1, "<=", $3); }
358 | const_expr GEQ const_expr { $$ = new ConstantExpression($1, ">=", $3); }
359 | const_expr LSHIFT const_expr { $$ = new ConstantExpression($1, "<<", $3); }
360 | const_expr RSHIFT 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 '*' 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 %prec UNARY_PLUS { $$ = new ConstantExpression("+", $2); }
367 | '-' const_expr %prec UNARY_MINUS { $$ = new ConstantExpression("-", $2); }
368 | '!' const_expr { $$ = new ConstantExpression("!", $2); }
369 | '~' const_expr { $$ = new ConstantExpression("~", $2); }
370 | '(' const_expr ')' { $$ = $2; }
371 ;
372
Andreas Huberc9410c72016-07-28 12:18:40 -0700373method_declaration
Andreas Huber3599d922016-08-09 10:42:57 -0700374 : opt_annotations IDENTIFIER '(' typed_vars ')' ';'
Andreas Huberc9410c72016-07-28 12:18:40 -0700375 {
Iliyan Malchev639bff82016-08-13 14:24:11 -0700376 $$ = new Method($2, $4, new std::vector<TypedVar *>, false, $1);
377 }
378 | opt_annotations ONEWAY IDENTIFIER '(' typed_vars ')' ';'
379 {
380 $$ = new Method($3, $5, new std::vector<TypedVar *>, true, $1);
Andreas Huberc9410c72016-07-28 12:18:40 -0700381 }
Andreas Huber3599d922016-08-09 10:42:57 -0700382 | opt_annotations IDENTIFIER '(' typed_vars ')' GENERATES '(' typed_vars ')' ';'
Andreas Huberc9410c72016-07-28 12:18:40 -0700383 {
Iliyan Malchev639bff82016-08-13 14:24:11 -0700384 $$ = new Method($2, $4, $8, false, $1);
Andreas Huberc9410c72016-07-28 12:18:40 -0700385 }
386 ;
387
388typed_vars
389 : /* empty */
390 {
Andreas Huber881227d2016-08-02 14:20:21 -0700391 $$ = new std::vector<TypedVar *>;
Andreas Huberc9410c72016-07-28 12:18:40 -0700392 }
393 | typed_var
394 {
Andreas Huber881227d2016-08-02 14:20:21 -0700395 $$ = new std::vector<TypedVar *>;
Andreas Huberc9410c72016-07-28 12:18:40 -0700396 $$->push_back($1);
397 }
398 | typed_vars ',' typed_var
399 {
400 $$ = $1;
401 $$->push_back($3);
402 }
403 ;
404
405typed_var : type IDENTIFIER { $$ = new TypedVar($2, $1); }
406 ;
407
408
409struct_or_union_keyword
410 : STRUCT { $$ = CompoundType::STYLE_STRUCT; }
411 | UNION { $$ = CompoundType::STYLE_UNION; }
412 ;
413
414named_struct_or_union_declaration
415 : struct_or_union_keyword IDENTIFIER
416 {
Andreas Huber31629bc2016-08-03 09:06:40 -0700417 CompoundType *container = new CompoundType($1);
Andreas Huberc9410c72016-07-28 12:18:40 -0700418 ast->enterScope(container);
419 }
420 struct_or_union_body
421 {
422 CompoundType *container = static_cast<CompoundType *>(ast->scope());
423
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700424 std::string errorMsg;
425 if (!container->setFields($4, &errorMsg)) {
426 std::cerr << "ERROR: " << errorMsg << " at " << @4 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700427 YYERROR;
428 }
429
Andreas Huberc9410c72016-07-28 12:18:40 -0700430 ast->leaveScope();
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700431
432 if (!ast->addScopedType($2, container, &errorMsg)) {
433 std::cerr << "ERROR: " << errorMsg << " at " << @2 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700434 YYERROR;
435 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700436 }
437 ;
438
439struct_or_union_declaration
440 : struct_or_union_keyword optIdentifier
441 {
Andreas Huber31629bc2016-08-03 09:06:40 -0700442 CompoundType *container = new CompoundType($1);
Andreas Huberc9410c72016-07-28 12:18:40 -0700443 ast->enterScope(container);
444 }
445 struct_or_union_body
446 {
447 CompoundType *container = static_cast<CompoundType *>(ast->scope());
448
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700449 std::string errorMsg;
450 if (!container->setFields($4, &errorMsg)) {
451 std::cerr << "ERROR: " << errorMsg << " at " << @4 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700452 YYERROR;
453 }
454
Andreas Huberc9410c72016-07-28 12:18:40 -0700455 ast->leaveScope();
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700456
457 if (!ast->addScopedType($2, container, &errorMsg)) {
458 std::cerr << "ERROR: " << errorMsg << " at " << @2 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700459 YYERROR;
460 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700461
Andreas Huberfd4afab2016-08-03 13:02:57 -0700462 $$ = container->ref();
Andreas Huberc9410c72016-07-28 12:18:40 -0700463 }
464 ;
465
466struct_or_union_body
467 : '{' field_declarations '}' { $$ = $2; }
468 ;
469
470field_declarations
Andreas Huber881227d2016-08-02 14:20:21 -0700471 : /* empty */ { $$ = new std::vector<CompoundField *>; }
Andreas Huberc9410c72016-07-28 12:18:40 -0700472 | field_declarations field_declaration
473 {
474 $$ = $1;
475
476 if ($2 != NULL) {
477 $$->push_back($2);
478 }
479 }
480 ;
481
482field_declaration
483 : type IDENTIFIER ';' { $$ = new CompoundField($2, $1); }
484 | struct_or_union_declaration ';' { $$ = NULL; }
485 | enum_declaration ';' { $$ = NULL; }
486 ;
487
488opt_storage_type
489 : /* empty */ { $$ = NULL; }
Andreas Huber8d3ac0c2016-08-04 14:49:23 -0700490 | ':' fqname
491 {
492 $$ = $2;
493
494 if ($$ != NULL && !$$->isValidEnumStorageType()) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700495 std::cerr << "ERROR: Invalid enum storage type specified. at "
496 << @2 << "\n";
497
Andreas Huber8d3ac0c2016-08-04 14:49:23 -0700498 YYABORT;
499 }
500 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700501 ;
502
503opt_comma
504 : /* empty */
505 | ','
506 ;
507
508named_enum_declaration
509 : ENUM IDENTIFIER opt_storage_type '{' enum_values opt_comma '}'
510 {
Andreas Huber31629bc2016-08-03 09:06:40 -0700511 EnumType *enumType = new EnumType($5, $3);
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700512
513 std::string errorMsg;
514 if (!ast->addScopedType($2, enumType, &errorMsg)) {
515 std::cerr << "ERROR: " << errorMsg << " at " << @2 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700516 YYERROR;
517 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700518 }
519 ;
520
521enum_declaration
522 : ENUM '{' enum_values opt_comma '}'
523 {
Andreas Huber31629bc2016-08-03 09:06:40 -0700524 EnumType *enumType = new EnumType($3);
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700525
526 std::string errorMsg;
527 if (!ast->addScopedType(NULL /* localName */, enumType, &errorMsg)) {
528 // This should never fail.
529 std::cerr << "ERROR: " << errorMsg << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700530 YYERROR;
531 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700532
Andreas Huberfd4afab2016-08-03 13:02:57 -0700533 $$ = enumType->ref();
Andreas Huberc9410c72016-07-28 12:18:40 -0700534 }
535 | ENUM IDENTIFIER opt_storage_type '{' enum_values opt_comma '}'
536 {
Andreas Huber31629bc2016-08-03 09:06:40 -0700537 EnumType *enumType = new EnumType($5, $3);
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700538
539 std::string errorMsg;
540 if (!ast->addScopedType($2, enumType, &errorMsg)) {
541 std::cerr << "ERROR: " << errorMsg << " at " << @2 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700542 YYERROR;
543 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700544
Andreas Huberfd4afab2016-08-03 13:02:57 -0700545 $$ = enumType->ref();
Andreas Huberc9410c72016-07-28 12:18:40 -0700546 }
547 ;
548
549enum_value
550 : IDENTIFIER { $$ = new EnumValue($1); }
Yifan Hong52165692016-08-12 18:06:40 -0700551 | IDENTIFIER '=' const_expr { $$ = new EnumValue($1, $3->value()); }
Andreas Huberc9410c72016-07-28 12:18:40 -0700552 ;
553
554enum_values
555 : /* empty */
556 {
Andreas Huber881227d2016-08-02 14:20:21 -0700557 $$ = new std::vector<EnumValue *>;
Andreas Huberc9410c72016-07-28 12:18:40 -0700558 }
559 | enum_value
560 {
Andreas Huber881227d2016-08-02 14:20:21 -0700561 $$ = new std::vector<EnumValue *>;
Andreas Huberc9410c72016-07-28 12:18:40 -0700562 $$->push_back($1);
563 }
564 | enum_values ',' enum_value
565 {
566 $$ = $1;
567 $$->push_back($3);
568 }
569 ;
570
571type
Andreas Huber84f89de2016-07-28 15:39:51 -0700572 : fqname { $$ = $1; }
Andreas Huberb95ea8a2016-08-15 15:35:42 -0700573 | fqname '[' INTEGER ']'
574 {
Andreas Huber295ad302016-08-16 11:35:00 -0700575 if ($1->isBinder()) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700576 std::cerr << "ERROR: Arrays of interface types are not supported."
577 << " at " << @1 << "\n";
Andreas Huber70a59e12016-08-16 12:57:01 -0700578
Andreas Huberb95ea8a2016-08-15 15:35:42 -0700579 YYERROR;
580 }
581
582 $$ = new ArrayType($1, $3);
583 }
584 | VEC '<' fqname '>'
585 {
Andreas Huber295ad302016-08-16 11:35:00 -0700586 if ($3->isBinder()) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700587 std::cerr << "ERROR: Vectors of interface types are not "
588 << "supported. at " << @3 << "\n";
Andreas Huber70a59e12016-08-16 12:57:01 -0700589
Andreas Huberb95ea8a2016-08-15 15:35:42 -0700590 YYERROR;
591 }
592
593 $$ = new VectorType($3);
594 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700595 | struct_or_union_declaration { $$ = $1; }
596 | enum_declaration { $$ = $1; }
Andreas Huber295ad302016-08-16 11:35:00 -0700597 | INTERFACE { $$ = new GenericBinder; }
Andreas Huberc9410c72016-07-28 12:18:40 -0700598 ;
599
600optIdentifier
601 : /* empty */ { $$ = NULL; }
602 | IDENTIFIER { $$ = $1; }
603 ;
604
605%%
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700606
607#include <android-base/logging.h>
608
609void yy::parser::error(
610 const yy::parser::location_type &where,
611 const std::string &errstr) {
612 std::cerr << "ERROR: " << errstr << " at " << where << "\n";
613}
614