blob: d6f03d0c3741afce530af4aa6687252b2b19375c [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"
7#include "Constant.h"
8#include "EnumType.h"
9#include "Interface.h"
10#include "Method.h"
Andreas Huberc9410c72016-07-28 12:18:40 -070011#include "TypeDef.h"
12#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
21extern int yylex(YYSTYPE *yylval_param, void *yyscanner);
22extern int column;
23
Andreas Hubereb1081f2016-07-28 13:13:24 -070024int yyerror(AST *, const char *s) {
Andreas Huberc9410c72016-07-28 12:18:40 -070025 fflush(stdout);
26 printf("\n%*s\n%*s\n", column, "^", column, s);
27
28 return 0;
29}
30
31#define scanner ast->scanner()
32
33%}
34
35%parse-param { android::AST *ast }
36%lex-param { void *scanner }
37%pure-parser
38
39%token<str> CONST
40%token<str> ENUM
41%token<str> EXTENDS
Andreas Huber84f89de2016-07-28 15:39:51 -070042%token<str> FQNAME
Andreas Huberc9410c72016-07-28 12:18:40 -070043%token<str> GENERATES
44%token<str> IDENTIFIER
45%token<str> IMPORT
46%token<str> INTEGER
47%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
Andreas Huberc9410c72016-07-28 12:18:40 -070057%type<str> optIdentifier package
58%type<str> const_value
Andreas Huber84f89de2016-07-28 15:39:51 -070059%type<type> fqname
Andreas Huberc9410c72016-07-28 12:18:40 -070060
61%type<type> type opt_storage_type
62%type<type> enum_declaration
63%type<type> struct_or_union_declaration
64%type<type> opt_extends
65
66%type<field> field_declaration
67%type<fields> field_declarations struct_or_union_body
68%type<enumValue> enum_value
69%type<enumValues> enum_values
70%type<typedVars> typed_vars
71%type<typedVar> typed_var
72%type<method> method_declaration
73%type<compoundStyle> struct_or_union_keyword
Andreas Huber3599d922016-08-09 10:42:57 -070074%type<stringVec> annotation_string_values annotation_value
75%type<annotationParam> annotation_param
76%type<annotationParams> opt_annotation_params annotation_params
77%type<annotation> annotation
78%type<annotations> opt_annotations
Andreas Huberc9410c72016-07-28 12:18:40 -070079
80%start program
81
82%union {
83 const char *str;
84 android::Type *type;
85 android::CompoundType *compoundType;
86 android::CompoundField *field;
Andreas Huber881227d2016-08-02 14:20:21 -070087 std::vector<android::CompoundField *> *fields;
Andreas Huberc9410c72016-07-28 12:18:40 -070088 android::EnumValue *enumValue;
Andreas Huber881227d2016-08-02 14:20:21 -070089 std::vector<android::EnumValue *> *enumValues;
Andreas Huberc9410c72016-07-28 12:18:40 -070090 android::TypedVar *typedVar;
Andreas Huber881227d2016-08-02 14:20:21 -070091 std::vector<android::TypedVar *> *typedVars;
Andreas Huberc9410c72016-07-28 12:18:40 -070092 android::Method *method;
93 android::CompoundType::Style compoundStyle;
Andreas Huber3599d922016-08-09 10:42:57 -070094 std::vector<std::string> *stringVec;
95 std::pair<std::string, std::vector<std::string> *> *annotationParam;
Zhuoyao Zhang5158db42016-08-10 10:25:20 -070096 android::DefaultKeyedVector<std::string, std::vector<std::string> *> *annotationParams;
Andreas Huber3599d922016-08-09 10:42:57 -070097 android::Annotation *annotation;
Zhuoyao Zhang5158db42016-08-10 10:25:20 -070098 android::DefaultKeyedVector<std::string, android::Annotation *> *annotations;
Andreas Huberc9410c72016-07-28 12:18:40 -070099}
100
101%%
102
Andreas Huber3599d922016-08-09 10:42:57 -0700103opt_annotations
104 : /* empty */
105 {
Zhuoyao Zhang5158db42016-08-10 10:25:20 -0700106 $$ = new DefaultKeyedVector<std::string, Annotation *>;
Andreas Huber3599d922016-08-09 10:42:57 -0700107 }
108 | opt_annotations annotation
109 {
110 $$ = $1;
111 $$->add($2->name(), $2);
112 }
113 ;
114
115annotation
116 : '@' IDENTIFIER opt_annotation_params
117 {
118 $$ = new Annotation($2, $3);
119 }
120 ;
121
122opt_annotation_params
123 : /* empty */
124 {
Zhuoyao Zhang5158db42016-08-10 10:25:20 -0700125 $$ = new DefaultKeyedVector<std::string, std::vector<std::string> *>;
Andreas Huber3599d922016-08-09 10:42:57 -0700126 }
127 | '(' annotation_params ')'
128 {
129 $$ = $2;
130 }
131 ;
132
133annotation_params
134 : annotation_param
135 {
Zhuoyao Zhang5158db42016-08-10 10:25:20 -0700136 $$ = new DefaultKeyedVector<std::string, std::vector<std::string> *>;
Andreas Huber3599d922016-08-09 10:42:57 -0700137 $$->add($1->first, $1->second);
138 }
139 | annotation_params ',' annotation_param
140 {
141 $$ = $1;
142 $$->add($3->first, $3->second);
143 }
144 ;
145
146annotation_param
147 : IDENTIFIER '=' annotation_value
148 {
149 $$ = new std::pair<std::string, std::vector<std::string> *>($1, $3);
150 }
151 ;
152
153annotation_value
154 : STRING_LITERAL
155 {
156 $$ = new std::vector<std::string>;
157 $$->push_back($1);
158 }
159 | '{' annotation_string_values '}' { $$ = $2; }
160 ;
161
162annotation_string_values
163 : STRING_LITERAL
164 {
165 $$ = new std::vector<std::string>;
166 $$->push_back($1);
167 }
168 | annotation_string_values ',' STRING_LITERAL
169 {
170 $$ = $1;
171 $$->push_back($3);
172 }
173 ;
174
Andreas Huberc9410c72016-07-28 12:18:40 -0700175program
Andreas Huberda51b8e2016-07-28 16:00:57 -0700176 : package imports body
Andreas Huber84f89de2016-07-28 15:39:51 -0700177 ;
178
179fqname
180 : FQNAME
181 {
182 $$ = ast->lookupType($1);
183 if ($$ == NULL) {
184 yyerror(ast,
185 android::String8::format(
186 "Failed to lookup type '%s'.", $1).string());
187 YYERROR;
188 }
189 }
190 | IDENTIFIER
191 {
192 $$ = ast->lookupType($1);
193 if ($$ == NULL) {
194 yyerror(ast,
195 android::String8::format(
196 "Failed to lookup type '%s'.", $1).string());
197 YYERROR;
198 }
199 }
200 | SCALAR
201 ;
Andreas Huberc9410c72016-07-28 12:18:40 -0700202
203package
Andreas Huber84f89de2016-07-28 15:39:51 -0700204 : PACKAGE FQNAME ';'
Andreas Hubereb1081f2016-07-28 13:13:24 -0700205 {
Andreas Huber84f89de2016-07-28 15:39:51 -0700206 if (!ast->setPackage($2)) {
207 yyerror(ast, "Malformed package identifier.");
208 YYERROR;
209 }
Andreas Hubereb1081f2016-07-28 13:13:24 -0700210 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700211
Andreas Huberc9410c72016-07-28 12:18:40 -0700212imports
213 : /* empty */
Andreas Huber84f89de2016-07-28 15:39:51 -0700214 | imports IMPORT FQNAME ';'
Andreas Hubereb1081f2016-07-28 13:13:24 -0700215 {
Andreas Huber68f24592016-07-29 14:53:48 -0700216 if (!ast->addImport($3)) {
217 yyerror(ast,
218 android::String8::format(
219 "Unable to import '%s'.", $3));
220
221 YYERROR;
222 }
Andreas Hubereb1081f2016-07-28 13:13:24 -0700223 }
Andreas Huber5345ec22016-07-29 13:33:27 -0700224 | imports IMPORT IDENTIFIER ';'
225 {
Andreas Huber68f24592016-07-29 14:53:48 -0700226 if (!ast->addImport($3)) {
227 yyerror(ast,
228 android::String8::format(
229 "Unable to import '%s'.", $3));
230
231 YYERROR;
232 }
Andreas Huber5345ec22016-07-29 13:33:27 -0700233 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700234 ;
235
236opt_extends
237 : /* empty */ { $$ = NULL; }
Andreas Huber84f89de2016-07-28 15:39:51 -0700238 | EXTENDS fqname { $$ = $2; }
Andreas Huberc9410c72016-07-28 12:18:40 -0700239
240body
Zhuoyao Zhangba7e6e92016-08-10 12:19:02 -0700241 : opt_annotations INTERFACE IDENTIFIER opt_extends
Andreas Huberc9410c72016-07-28 12:18:40 -0700242 {
Zhuoyao Zhangba7e6e92016-08-10 12:19:02 -0700243 if ($4 != NULL && !$4->isInterface()) {
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700244 fprintf(stderr, "You can only extend interfaces.\n");
245 YYERROR;
246 }
247
Andreas Huber991b8642016-08-15 16:40:44 -0700248 if ($3[0] != 'I') {
249 fprintf(stderr,
250 "All interface names must start with an 'I' prefix.\n");
251
252 YYERROR;
253 }
254
Zhuoyao Zhangba7e6e92016-08-10 12:19:02 -0700255 Interface *iface = new Interface(static_cast<Interface *>($4), $1);
Andreas Hubereb1081f2016-07-28 13:13:24 -0700256
257 // Register interface immediately so it can be referenced inside
258 // definition.
Zhuoyao Zhangba7e6e92016-08-10 12:19:02 -0700259 if (!ast->addScopedType($3, iface)) {
Andreas Huber5a545442016-08-03 10:44:56 -0700260 YYERROR;
261 }
Andreas Hubereb1081f2016-07-28 13:13:24 -0700262
Andreas Huberc9410c72016-07-28 12:18:40 -0700263 ast->enterScope(iface);
264 }
265 '{' interface_declarations '}' ';'
266 {
267 Interface *iface = static_cast<Interface *>(ast->scope());
268
269 ast->leaveScope();
Andreas Huberc9410c72016-07-28 12:18:40 -0700270 }
271 | type_declarations
272 ;
273
274interface_declarations
275 : /* empty */
276 | interface_declarations type_declaration
277 | interface_declarations method_declaration
278 {
279 Interface *iface = static_cast<Interface *>(ast->scope());
280 iface->addMethod($2);
281 }
282 ;
283
284type_declarations
Andreas Hubera2723d22016-07-29 15:36:07 -0700285 : /* empty */
Andreas Huberc9410c72016-07-28 12:18:40 -0700286 | type_declarations type_declaration
287 ;
288
289type_declaration
290 : named_struct_or_union_declaration ';'
291 | named_enum_declaration ';'
292 | typedef_declaration ';'
293 | const_declaration ';'
294 ;
295
296typedef_declaration
297 : TYPEDEF type IDENTIFIER
298 {
Andreas Huber31629bc2016-08-03 09:06:40 -0700299 TypeDef *def = new TypeDef($2);
Andreas Huber5a545442016-08-03 10:44:56 -0700300 if (!ast->addScopedType($3, def)) {
301 YYERROR;
302 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700303 }
304 ;
305
306const_value
307 : INTEGER
308 | STRING_LITERAL ;
309
310const_declaration
Andreas Huber84f89de2016-07-28 15:39:51 -0700311 : CONST fqname IDENTIFIER '=' const_value
Andreas Huberc9410c72016-07-28 12:18:40 -0700312 {
313 Constant *constant = new Constant($3, $2, $5);
314 ast->scope()->addConstant(constant);
315 }
316 ;
317
318method_declaration
Andreas Huber3599d922016-08-09 10:42:57 -0700319 : opt_annotations IDENTIFIER '(' typed_vars ')' ';'
Andreas Huberc9410c72016-07-28 12:18:40 -0700320 {
Iliyan Malchev639bff82016-08-13 14:24:11 -0700321 $$ = new Method($2, $4, new std::vector<TypedVar *>, false, $1);
322 }
323 | opt_annotations ONEWAY IDENTIFIER '(' typed_vars ')' ';'
324 {
325 $$ = new Method($3, $5, new std::vector<TypedVar *>, true, $1);
Andreas Huberc9410c72016-07-28 12:18:40 -0700326 }
Andreas Huber3599d922016-08-09 10:42:57 -0700327 | opt_annotations IDENTIFIER '(' typed_vars ')' GENERATES '(' typed_vars ')' ';'
Andreas Huberc9410c72016-07-28 12:18:40 -0700328 {
Iliyan Malchev639bff82016-08-13 14:24:11 -0700329 $$ = new Method($2, $4, $8, false, $1);
Andreas Huberc9410c72016-07-28 12:18:40 -0700330 }
331 ;
332
333typed_vars
334 : /* empty */
335 {
Andreas Huber881227d2016-08-02 14:20:21 -0700336 $$ = new std::vector<TypedVar *>;
Andreas Huberc9410c72016-07-28 12:18:40 -0700337 }
338 | typed_var
339 {
Andreas Huber881227d2016-08-02 14:20:21 -0700340 $$ = new std::vector<TypedVar *>;
Andreas Huberc9410c72016-07-28 12:18:40 -0700341 $$->push_back($1);
342 }
343 | typed_vars ',' typed_var
344 {
345 $$ = $1;
346 $$->push_back($3);
347 }
348 ;
349
350typed_var : type IDENTIFIER { $$ = new TypedVar($2, $1); }
351 ;
352
353
354struct_or_union_keyword
355 : STRUCT { $$ = CompoundType::STYLE_STRUCT; }
356 | UNION { $$ = CompoundType::STYLE_UNION; }
357 ;
358
359named_struct_or_union_declaration
360 : struct_or_union_keyword IDENTIFIER
361 {
Andreas Huber31629bc2016-08-03 09:06:40 -0700362 CompoundType *container = new CompoundType($1);
Andreas Huberc9410c72016-07-28 12:18:40 -0700363 ast->enterScope(container);
364 }
365 struct_or_union_body
366 {
367 CompoundType *container = static_cast<CompoundType *>(ast->scope());
368
Andreas Huber5a545442016-08-03 10:44:56 -0700369 if (!container->setFields($4)) {
370 YYERROR;
371 }
372
Andreas Huberc9410c72016-07-28 12:18:40 -0700373 ast->leaveScope();
Andreas Huber5a545442016-08-03 10:44:56 -0700374 if (!ast->addScopedType($2, container)) {
375 YYERROR;
376 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700377 }
378 ;
379
380struct_or_union_declaration
381 : struct_or_union_keyword optIdentifier
382 {
Andreas Huber31629bc2016-08-03 09:06:40 -0700383 CompoundType *container = new CompoundType($1);
Andreas Huberc9410c72016-07-28 12:18:40 -0700384 ast->enterScope(container);
385 }
386 struct_or_union_body
387 {
388 CompoundType *container = static_cast<CompoundType *>(ast->scope());
389
Andreas Huber5a545442016-08-03 10:44:56 -0700390 if (!container->setFields($4)) {
391 YYERROR;
392 }
393
Andreas Huberc9410c72016-07-28 12:18:40 -0700394 ast->leaveScope();
Andreas Huber5a545442016-08-03 10:44:56 -0700395 if (!ast->addScopedType($2, container)) {
396 YYERROR;
397 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700398
Andreas Huberfd4afab2016-08-03 13:02:57 -0700399 $$ = container->ref();
Andreas Huberc9410c72016-07-28 12:18:40 -0700400 }
401 ;
402
403struct_or_union_body
404 : '{' field_declarations '}' { $$ = $2; }
405 ;
406
407field_declarations
Andreas Huber881227d2016-08-02 14:20:21 -0700408 : /* empty */ { $$ = new std::vector<CompoundField *>; }
Andreas Huberc9410c72016-07-28 12:18:40 -0700409 | field_declarations field_declaration
410 {
411 $$ = $1;
412
413 if ($2 != NULL) {
414 $$->push_back($2);
415 }
416 }
417 ;
418
419field_declaration
420 : type IDENTIFIER ';' { $$ = new CompoundField($2, $1); }
421 | struct_or_union_declaration ';' { $$ = NULL; }
422 | enum_declaration ';' { $$ = NULL; }
423 ;
424
425opt_storage_type
426 : /* empty */ { $$ = NULL; }
Andreas Huber8d3ac0c2016-08-04 14:49:23 -0700427 | ':' fqname
428 {
429 $$ = $2;
430
431 if ($$ != NULL && !$$->isValidEnumStorageType()) {
432 fprintf(stderr, "Invalid enum storage type specified.\n");
433 YYABORT;
434 }
435 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700436 ;
437
438opt_comma
439 : /* empty */
440 | ','
441 ;
442
443named_enum_declaration
444 : ENUM IDENTIFIER opt_storage_type '{' enum_values opt_comma '}'
445 {
Andreas Huber31629bc2016-08-03 09:06:40 -0700446 EnumType *enumType = new EnumType($5, $3);
Andreas Huber5a545442016-08-03 10:44:56 -0700447 if (!ast->addScopedType($2, enumType)) {
448 YYERROR;
449 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700450 }
451 ;
452
453enum_declaration
454 : ENUM '{' enum_values opt_comma '}'
455 {
Andreas Huber31629bc2016-08-03 09:06:40 -0700456 EnumType *enumType = new EnumType($3);
Andreas Huber5a545442016-08-03 10:44:56 -0700457 if (!ast->addScopedType(NULL /* localName */, enumType)) {
458 YYERROR;
459 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700460
Andreas Huberfd4afab2016-08-03 13:02:57 -0700461 $$ = enumType->ref();
Andreas Huberc9410c72016-07-28 12:18:40 -0700462 }
463 | ENUM IDENTIFIER opt_storage_type '{' enum_values opt_comma '}'
464 {
Andreas Huber31629bc2016-08-03 09:06:40 -0700465 EnumType *enumType = new EnumType($5, $3);
Andreas Huber5a545442016-08-03 10:44:56 -0700466 if (!ast->addScopedType($2, enumType)) {
467 YYERROR;
468 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700469
Andreas Huberfd4afab2016-08-03 13:02:57 -0700470 $$ = enumType->ref();
Andreas Huberc9410c72016-07-28 12:18:40 -0700471 }
472 ;
473
474enum_value
475 : IDENTIFIER { $$ = new EnumValue($1); }
476 | IDENTIFIER '=' INTEGER { $$ = new EnumValue($1, $3); }
477 | IDENTIFIER '=' IDENTIFIER { $$ = new EnumValue($1, $3); }
Andreas Huber006189f2016-07-29 15:51:17 -0700478 | IDENTIFIER '=' IDENTIFIER '+' INTEGER
479 {
480 $$ = new EnumValue(
481 $1, strdup(
482 android::String8::format("%s + %s", $3, $5).string()));
483 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700484 ;
485
486enum_values
487 : /* empty */
488 {
Andreas Huber881227d2016-08-02 14:20:21 -0700489 $$ = new std::vector<EnumValue *>;
Andreas Huberc9410c72016-07-28 12:18:40 -0700490 }
491 | enum_value
492 {
Andreas Huber881227d2016-08-02 14:20:21 -0700493 $$ = new std::vector<EnumValue *>;
Andreas Huberc9410c72016-07-28 12:18:40 -0700494 $$->push_back($1);
495 }
496 | enum_values ',' enum_value
497 {
498 $$ = $1;
499 $$->push_back($3);
500 }
501 ;
502
503type
Andreas Huber84f89de2016-07-28 15:39:51 -0700504 : fqname { $$ = $1; }
Andreas Huberb95ea8a2016-08-15 15:35:42 -0700505 | fqname '[' INTEGER ']'
506 {
507 if ($1->isInterface()) {
508 fprintf(stderr, "Arrays of interface types are not supported.");
509 YYERROR;
510 }
511
512 $$ = new ArrayType($1, $3);
513 }
514 | VEC '<' fqname '>'
515 {
516 if ($3->isInterface()) {
517 fprintf(stderr, "Vectors of interface types are not supported.");
518 YYERROR;
519 }
520
521 $$ = new VectorType($3);
522 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700523 | struct_or_union_declaration { $$ = $1; }
524 | enum_declaration { $$ = $1; }
525 ;
526
527optIdentifier
528 : /* empty */ { $$ = NULL; }
529 | IDENTIFIER { $$ = $1; }
530 ;
531
532%%