blob: 92767de241e3a614b33d6a9c21c8033703c02c0e [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
Andreas Huberc9410c72016-07-28 12:18:40 -070055
Andreas Huberc9410c72016-07-28 12:18:40 -070056%type<str> optIdentifier package
57%type<str> const_value
Andreas Huber84f89de2016-07-28 15:39:51 -070058%type<type> fqname
Andreas Huberc9410c72016-07-28 12:18:40 -070059
60%type<type> type opt_storage_type
61%type<type> enum_declaration
62%type<type> struct_or_union_declaration
63%type<type> opt_extends
64
65%type<field> field_declaration
66%type<fields> field_declarations struct_or_union_body
67%type<enumValue> enum_value
68%type<enumValues> enum_values
69%type<typedVars> typed_vars
70%type<typedVar> typed_var
71%type<method> method_declaration
72%type<compoundStyle> struct_or_union_keyword
Andreas Huber3599d922016-08-09 10:42:57 -070073%type<stringVec> annotation_string_values annotation_value
74%type<annotationParam> annotation_param
75%type<annotationParams> opt_annotation_params annotation_params
76%type<annotation> annotation
77%type<annotations> opt_annotations
Andreas Huberc9410c72016-07-28 12:18:40 -070078
79%start program
80
81%union {
82 const char *str;
83 android::Type *type;
84 android::CompoundType *compoundType;
85 android::CompoundField *field;
Andreas Huber881227d2016-08-02 14:20:21 -070086 std::vector<android::CompoundField *> *fields;
Andreas Huberc9410c72016-07-28 12:18:40 -070087 android::EnumValue *enumValue;
Andreas Huber881227d2016-08-02 14:20:21 -070088 std::vector<android::EnumValue *> *enumValues;
Andreas Huberc9410c72016-07-28 12:18:40 -070089 android::TypedVar *typedVar;
Andreas Huber881227d2016-08-02 14:20:21 -070090 std::vector<android::TypedVar *> *typedVars;
Andreas Huberc9410c72016-07-28 12:18:40 -070091 android::Method *method;
92 android::CompoundType::Style compoundStyle;
Andreas Huber3599d922016-08-09 10:42:57 -070093 std::vector<std::string> *stringVec;
94 std::pair<std::string, std::vector<std::string> *> *annotationParam;
95 android::KeyedVector<std::string, std::vector<std::string> *> *annotationParams;
96 android::Annotation *annotation;
97 android::KeyedVector<std::string, android::Annotation *> *annotations;
Andreas Huberc9410c72016-07-28 12:18:40 -070098}
99
100%%
101
Andreas Huber3599d922016-08-09 10:42:57 -0700102opt_annotations
103 : /* empty */
104 {
105 $$ = new KeyedVector<std::string, Annotation *>;
106 }
107 | opt_annotations annotation
108 {
109 $$ = $1;
110 $$->add($2->name(), $2);
111 }
112 ;
113
114annotation
115 : '@' IDENTIFIER opt_annotation_params
116 {
117 $$ = new Annotation($2, $3);
118 }
119 ;
120
121opt_annotation_params
122 : /* empty */
123 {
124 $$ = new KeyedVector<std::string, std::vector<std::string> *>;
125 }
126 | '(' annotation_params ')'
127 {
128 $$ = $2;
129 }
130 ;
131
132annotation_params
133 : annotation_param
134 {
135 $$ = new KeyedVector<std::string, std::vector<std::string> *>;
136 $$->add($1->first, $1->second);
137 }
138 | annotation_params ',' annotation_param
139 {
140 $$ = $1;
141 $$->add($3->first, $3->second);
142 }
143 ;
144
145annotation_param
146 : IDENTIFIER '=' annotation_value
147 {
148 $$ = new std::pair<std::string, std::vector<std::string> *>($1, $3);
149 }
150 ;
151
152annotation_value
153 : STRING_LITERAL
154 {
155 $$ = new std::vector<std::string>;
156 $$->push_back($1);
157 }
158 | '{' annotation_string_values '}' { $$ = $2; }
159 ;
160
161annotation_string_values
162 : STRING_LITERAL
163 {
164 $$ = new std::vector<std::string>;
165 $$->push_back($1);
166 }
167 | annotation_string_values ',' STRING_LITERAL
168 {
169 $$ = $1;
170 $$->push_back($3);
171 }
172 ;
173
Andreas Huberc9410c72016-07-28 12:18:40 -0700174program
Andreas Huberda51b8e2016-07-28 16:00:57 -0700175 : package imports body
Andreas Huber84f89de2016-07-28 15:39:51 -0700176 ;
177
178fqname
179 : FQNAME
180 {
181 $$ = ast->lookupType($1);
182 if ($$ == NULL) {
183 yyerror(ast,
184 android::String8::format(
185 "Failed to lookup type '%s'.", $1).string());
186 YYERROR;
187 }
188 }
189 | IDENTIFIER
190 {
191 $$ = ast->lookupType($1);
192 if ($$ == NULL) {
193 yyerror(ast,
194 android::String8::format(
195 "Failed to lookup type '%s'.", $1).string());
196 YYERROR;
197 }
198 }
199 | SCALAR
200 ;
Andreas Huberc9410c72016-07-28 12:18:40 -0700201
202package
Andreas Huber84f89de2016-07-28 15:39:51 -0700203 : PACKAGE FQNAME ';'
Andreas Hubereb1081f2016-07-28 13:13:24 -0700204 {
Andreas Huber84f89de2016-07-28 15:39:51 -0700205 if (!ast->setPackage($2)) {
206 yyerror(ast, "Malformed package identifier.");
207 YYERROR;
208 }
Andreas Hubereb1081f2016-07-28 13:13:24 -0700209 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700210
Andreas Huberc9410c72016-07-28 12:18:40 -0700211imports
212 : /* empty */
Andreas Huber84f89de2016-07-28 15:39:51 -0700213 | imports IMPORT FQNAME ';'
Andreas Hubereb1081f2016-07-28 13:13:24 -0700214 {
Andreas Huber68f24592016-07-29 14:53:48 -0700215 if (!ast->addImport($3)) {
216 yyerror(ast,
217 android::String8::format(
218 "Unable to import '%s'.", $3));
219
220 YYERROR;
221 }
Andreas Hubereb1081f2016-07-28 13:13:24 -0700222 }
Andreas Huber5345ec22016-07-29 13:33:27 -0700223 | imports IMPORT IDENTIFIER ';'
224 {
Andreas Huber68f24592016-07-29 14:53:48 -0700225 if (!ast->addImport($3)) {
226 yyerror(ast,
227 android::String8::format(
228 "Unable to import '%s'.", $3));
229
230 YYERROR;
231 }
Andreas Huber5345ec22016-07-29 13:33:27 -0700232 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700233 ;
234
235opt_extends
236 : /* empty */ { $$ = NULL; }
Andreas Huber84f89de2016-07-28 15:39:51 -0700237 | EXTENDS fqname { $$ = $2; }
Andreas Huberc9410c72016-07-28 12:18:40 -0700238
239body
Zhuoyao Zhangba7e6e92016-08-10 12:19:02 -0700240 : opt_annotations INTERFACE IDENTIFIER opt_extends
Andreas Huberc9410c72016-07-28 12:18:40 -0700241 {
Zhuoyao Zhangba7e6e92016-08-10 12:19:02 -0700242 if ($4 != NULL && !$4->isInterface()) {
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700243 fprintf(stderr, "You can only extend interfaces.\n");
244 YYERROR;
245 }
246
Zhuoyao Zhangba7e6e92016-08-10 12:19:02 -0700247 Interface *iface = new Interface(static_cast<Interface *>($4), $1);
Andreas Hubereb1081f2016-07-28 13:13:24 -0700248
249 // Register interface immediately so it can be referenced inside
250 // definition.
Zhuoyao Zhangba7e6e92016-08-10 12:19:02 -0700251 if (!ast->addScopedType($3, iface)) {
Andreas Huber5a545442016-08-03 10:44:56 -0700252 YYERROR;
253 }
Andreas Hubereb1081f2016-07-28 13:13:24 -0700254
Andreas Huberc9410c72016-07-28 12:18:40 -0700255 ast->enterScope(iface);
256 }
257 '{' interface_declarations '}' ';'
258 {
259 Interface *iface = static_cast<Interface *>(ast->scope());
260
261 ast->leaveScope();
Andreas Huberc9410c72016-07-28 12:18:40 -0700262 }
263 | type_declarations
264 ;
265
266interface_declarations
267 : /* empty */
268 | interface_declarations type_declaration
269 | interface_declarations method_declaration
270 {
271 Interface *iface = static_cast<Interface *>(ast->scope());
272 iface->addMethod($2);
273 }
274 ;
275
276type_declarations
Andreas Hubera2723d22016-07-29 15:36:07 -0700277 : /* empty */
Andreas Huberc9410c72016-07-28 12:18:40 -0700278 | type_declarations type_declaration
279 ;
280
281type_declaration
282 : named_struct_or_union_declaration ';'
283 | named_enum_declaration ';'
284 | typedef_declaration ';'
285 | const_declaration ';'
286 ;
287
288typedef_declaration
289 : TYPEDEF type IDENTIFIER
290 {
Andreas Huber31629bc2016-08-03 09:06:40 -0700291 TypeDef *def = new TypeDef($2);
Andreas Huber5a545442016-08-03 10:44:56 -0700292 if (!ast->addScopedType($3, def)) {
293 YYERROR;
294 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700295 }
296 ;
297
298const_value
299 : INTEGER
300 | STRING_LITERAL ;
301
302const_declaration
Andreas Huber84f89de2016-07-28 15:39:51 -0700303 : CONST fqname IDENTIFIER '=' const_value
Andreas Huberc9410c72016-07-28 12:18:40 -0700304 {
305 Constant *constant = new Constant($3, $2, $5);
306 ast->scope()->addConstant(constant);
307 }
308 ;
309
310method_declaration
Andreas Huber3599d922016-08-09 10:42:57 -0700311 : opt_annotations IDENTIFIER '(' typed_vars ')' ';'
Andreas Huberc9410c72016-07-28 12:18:40 -0700312 {
Andreas Huber3599d922016-08-09 10:42:57 -0700313 $$ = new Method($2, $4, new std::vector<TypedVar *>, $1);
Andreas Huberc9410c72016-07-28 12:18:40 -0700314 }
Andreas Huber3599d922016-08-09 10:42:57 -0700315 | opt_annotations IDENTIFIER '(' typed_vars ')' GENERATES '(' typed_vars ')' ';'
Andreas Huberc9410c72016-07-28 12:18:40 -0700316 {
Andreas Huber3599d922016-08-09 10:42:57 -0700317 $$ = new Method($2, $4, $8, $1);
Andreas Huberc9410c72016-07-28 12:18:40 -0700318 }
319 ;
320
321typed_vars
322 : /* empty */
323 {
Andreas Huber881227d2016-08-02 14:20:21 -0700324 $$ = new std::vector<TypedVar *>;
Andreas Huberc9410c72016-07-28 12:18:40 -0700325 }
326 | typed_var
327 {
Andreas Huber881227d2016-08-02 14:20:21 -0700328 $$ = new std::vector<TypedVar *>;
Andreas Huberc9410c72016-07-28 12:18:40 -0700329 $$->push_back($1);
330 }
331 | typed_vars ',' typed_var
332 {
333 $$ = $1;
334 $$->push_back($3);
335 }
336 ;
337
338typed_var : type IDENTIFIER { $$ = new TypedVar($2, $1); }
339 ;
340
341
342struct_or_union_keyword
343 : STRUCT { $$ = CompoundType::STYLE_STRUCT; }
344 | UNION { $$ = CompoundType::STYLE_UNION; }
345 ;
346
347named_struct_or_union_declaration
348 : struct_or_union_keyword IDENTIFIER
349 {
Andreas Huber31629bc2016-08-03 09:06:40 -0700350 CompoundType *container = new CompoundType($1);
Andreas Huberc9410c72016-07-28 12:18:40 -0700351 ast->enterScope(container);
352 }
353 struct_or_union_body
354 {
355 CompoundType *container = static_cast<CompoundType *>(ast->scope());
356
Andreas Huber5a545442016-08-03 10:44:56 -0700357 if (!container->setFields($4)) {
358 YYERROR;
359 }
360
Andreas Huberc9410c72016-07-28 12:18:40 -0700361 ast->leaveScope();
Andreas Huber5a545442016-08-03 10:44:56 -0700362 if (!ast->addScopedType($2, container)) {
363 YYERROR;
364 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700365 }
366 ;
367
368struct_or_union_declaration
369 : struct_or_union_keyword optIdentifier
370 {
Andreas Huber31629bc2016-08-03 09:06:40 -0700371 CompoundType *container = new CompoundType($1);
Andreas Huberc9410c72016-07-28 12:18:40 -0700372 ast->enterScope(container);
373 }
374 struct_or_union_body
375 {
376 CompoundType *container = static_cast<CompoundType *>(ast->scope());
377
Andreas Huber5a545442016-08-03 10:44:56 -0700378 if (!container->setFields($4)) {
379 YYERROR;
380 }
381
Andreas Huberc9410c72016-07-28 12:18:40 -0700382 ast->leaveScope();
Andreas Huber5a545442016-08-03 10:44:56 -0700383 if (!ast->addScopedType($2, container)) {
384 YYERROR;
385 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700386
Andreas Huberfd4afab2016-08-03 13:02:57 -0700387 $$ = container->ref();
Andreas Huberc9410c72016-07-28 12:18:40 -0700388 }
389 ;
390
391struct_or_union_body
392 : '{' field_declarations '}' { $$ = $2; }
393 ;
394
395field_declarations
Andreas Huber881227d2016-08-02 14:20:21 -0700396 : /* empty */ { $$ = new std::vector<CompoundField *>; }
Andreas Huberc9410c72016-07-28 12:18:40 -0700397 | field_declarations field_declaration
398 {
399 $$ = $1;
400
401 if ($2 != NULL) {
402 $$->push_back($2);
403 }
404 }
405 ;
406
407field_declaration
408 : type IDENTIFIER ';' { $$ = new CompoundField($2, $1); }
409 | struct_or_union_declaration ';' { $$ = NULL; }
410 | enum_declaration ';' { $$ = NULL; }
411 ;
412
413opt_storage_type
414 : /* empty */ { $$ = NULL; }
Andreas Huber8d3ac0c2016-08-04 14:49:23 -0700415 | ':' fqname
416 {
417 $$ = $2;
418
419 if ($$ != NULL && !$$->isValidEnumStorageType()) {
420 fprintf(stderr, "Invalid enum storage type specified.\n");
421 YYABORT;
422 }
423 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700424 ;
425
426opt_comma
427 : /* empty */
428 | ','
429 ;
430
431named_enum_declaration
432 : ENUM IDENTIFIER opt_storage_type '{' enum_values opt_comma '}'
433 {
Andreas Huber31629bc2016-08-03 09:06:40 -0700434 EnumType *enumType = new EnumType($5, $3);
Andreas Huber5a545442016-08-03 10:44:56 -0700435 if (!ast->addScopedType($2, enumType)) {
436 YYERROR;
437 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700438 }
439 ;
440
441enum_declaration
442 : ENUM '{' enum_values opt_comma '}'
443 {
Andreas Huber31629bc2016-08-03 09:06:40 -0700444 EnumType *enumType = new EnumType($3);
Andreas Huber5a545442016-08-03 10:44:56 -0700445 if (!ast->addScopedType(NULL /* localName */, enumType)) {
446 YYERROR;
447 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700448
Andreas Huberfd4afab2016-08-03 13:02:57 -0700449 $$ = enumType->ref();
Andreas Huberc9410c72016-07-28 12:18:40 -0700450 }
451 | ENUM IDENTIFIER opt_storage_type '{' enum_values opt_comma '}'
452 {
Andreas Huber31629bc2016-08-03 09:06:40 -0700453 EnumType *enumType = new EnumType($5, $3);
Andreas Huber5a545442016-08-03 10:44:56 -0700454 if (!ast->addScopedType($2, enumType)) {
455 YYERROR;
456 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700457
Andreas Huberfd4afab2016-08-03 13:02:57 -0700458 $$ = enumType->ref();
Andreas Huberc9410c72016-07-28 12:18:40 -0700459 }
460 ;
461
462enum_value
463 : IDENTIFIER { $$ = new EnumValue($1); }
464 | IDENTIFIER '=' INTEGER { $$ = new EnumValue($1, $3); }
465 | IDENTIFIER '=' IDENTIFIER { $$ = new EnumValue($1, $3); }
Andreas Huber006189f2016-07-29 15:51:17 -0700466 | IDENTIFIER '=' IDENTIFIER '+' INTEGER
467 {
468 $$ = new EnumValue(
469 $1, strdup(
470 android::String8::format("%s + %s", $3, $5).string()));
471 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700472 ;
473
474enum_values
475 : /* empty */
476 {
Andreas Huber881227d2016-08-02 14:20:21 -0700477 $$ = new std::vector<EnumValue *>;
Andreas Huberc9410c72016-07-28 12:18:40 -0700478 }
479 | enum_value
480 {
Andreas Huber881227d2016-08-02 14:20:21 -0700481 $$ = new std::vector<EnumValue *>;
Andreas Huberc9410c72016-07-28 12:18:40 -0700482 $$->push_back($1);
483 }
484 | enum_values ',' enum_value
485 {
486 $$ = $1;
487 $$->push_back($3);
488 }
489 ;
490
491type
Andreas Huber84f89de2016-07-28 15:39:51 -0700492 : fqname { $$ = $1; }
Andreas Huberb95ea8a2016-08-15 15:35:42 -0700493 | fqname '[' INTEGER ']'
494 {
495 if ($1->isInterface()) {
496 fprintf(stderr, "Arrays of interface types are not supported.");
497 YYERROR;
498 }
499
500 $$ = new ArrayType($1, $3);
501 }
502 | VEC '<' fqname '>'
503 {
504 if ($3->isInterface()) {
505 fprintf(stderr, "Vectors of interface types are not supported.");
506 YYERROR;
507 }
508
509 $$ = new VectorType($3);
510 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700511 | struct_or_union_declaration { $$ = $1; }
512 | enum_declaration { $$ = $1; }
513 ;
514
515optIdentifier
516 : /* empty */ { $$ = NULL; }
517 | IDENTIFIER { $$ = $1; }
518 ;
519
520%%