blob: 6e1957faa13d3304287e012ef9f987e8dfec94e2 [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
Zhuoyao Zhangba7e6e92016-08-10 12:19:02 -0700248 Interface *iface = new Interface(static_cast<Interface *>($4), $1);
Andreas Hubereb1081f2016-07-28 13:13:24 -0700249
250 // Register interface immediately so it can be referenced inside
251 // definition.
Zhuoyao Zhangba7e6e92016-08-10 12:19:02 -0700252 if (!ast->addScopedType($3, iface)) {
Andreas Huber5a545442016-08-03 10:44:56 -0700253 YYERROR;
254 }
Andreas Hubereb1081f2016-07-28 13:13:24 -0700255
Andreas Huberc9410c72016-07-28 12:18:40 -0700256 ast->enterScope(iface);
257 }
258 '{' interface_declarations '}' ';'
259 {
260 Interface *iface = static_cast<Interface *>(ast->scope());
261
262 ast->leaveScope();
Andreas Huberc9410c72016-07-28 12:18:40 -0700263 }
264 | type_declarations
265 ;
266
267interface_declarations
268 : /* empty */
269 | interface_declarations type_declaration
270 | interface_declarations method_declaration
271 {
272 Interface *iface = static_cast<Interface *>(ast->scope());
273 iface->addMethod($2);
274 }
275 ;
276
277type_declarations
Andreas Hubera2723d22016-07-29 15:36:07 -0700278 : /* empty */
Andreas Huberc9410c72016-07-28 12:18:40 -0700279 | type_declarations type_declaration
280 ;
281
282type_declaration
283 : named_struct_or_union_declaration ';'
284 | named_enum_declaration ';'
285 | typedef_declaration ';'
286 | const_declaration ';'
287 ;
288
289typedef_declaration
290 : TYPEDEF type IDENTIFIER
291 {
Andreas Huber31629bc2016-08-03 09:06:40 -0700292 TypeDef *def = new TypeDef($2);
Andreas Huber5a545442016-08-03 10:44:56 -0700293 if (!ast->addScopedType($3, def)) {
294 YYERROR;
295 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700296 }
297 ;
298
299const_value
300 : INTEGER
301 | STRING_LITERAL ;
302
303const_declaration
Andreas Huber84f89de2016-07-28 15:39:51 -0700304 : CONST fqname IDENTIFIER '=' const_value
Andreas Huberc9410c72016-07-28 12:18:40 -0700305 {
306 Constant *constant = new Constant($3, $2, $5);
307 ast->scope()->addConstant(constant);
308 }
309 ;
310
311method_declaration
Andreas Huber3599d922016-08-09 10:42:57 -0700312 : opt_annotations IDENTIFIER '(' typed_vars ')' ';'
Andreas Huberc9410c72016-07-28 12:18:40 -0700313 {
Iliyan Malchev639bff82016-08-13 14:24:11 -0700314 $$ = new Method($2, $4, new std::vector<TypedVar *>, false, $1);
315 }
316 | opt_annotations ONEWAY IDENTIFIER '(' typed_vars ')' ';'
317 {
318 $$ = new Method($3, $5, new std::vector<TypedVar *>, true, $1);
Andreas Huberc9410c72016-07-28 12:18:40 -0700319 }
Andreas Huber3599d922016-08-09 10:42:57 -0700320 | opt_annotations IDENTIFIER '(' typed_vars ')' GENERATES '(' typed_vars ')' ';'
Andreas Huberc9410c72016-07-28 12:18:40 -0700321 {
Iliyan Malchev639bff82016-08-13 14:24:11 -0700322 $$ = new Method($2, $4, $8, false, $1);
Andreas Huberc9410c72016-07-28 12:18:40 -0700323 }
324 ;
325
326typed_vars
327 : /* empty */
328 {
Andreas Huber881227d2016-08-02 14:20:21 -0700329 $$ = new std::vector<TypedVar *>;
Andreas Huberc9410c72016-07-28 12:18:40 -0700330 }
331 | typed_var
332 {
Andreas Huber881227d2016-08-02 14:20:21 -0700333 $$ = new std::vector<TypedVar *>;
Andreas Huberc9410c72016-07-28 12:18:40 -0700334 $$->push_back($1);
335 }
336 | typed_vars ',' typed_var
337 {
338 $$ = $1;
339 $$->push_back($3);
340 }
341 ;
342
343typed_var : type IDENTIFIER { $$ = new TypedVar($2, $1); }
344 ;
345
346
347struct_or_union_keyword
348 : STRUCT { $$ = CompoundType::STYLE_STRUCT; }
349 | UNION { $$ = CompoundType::STYLE_UNION; }
350 ;
351
352named_struct_or_union_declaration
353 : struct_or_union_keyword IDENTIFIER
354 {
Andreas Huber31629bc2016-08-03 09:06:40 -0700355 CompoundType *container = new CompoundType($1);
Andreas Huberc9410c72016-07-28 12:18:40 -0700356 ast->enterScope(container);
357 }
358 struct_or_union_body
359 {
360 CompoundType *container = static_cast<CompoundType *>(ast->scope());
361
Andreas Huber5a545442016-08-03 10:44:56 -0700362 if (!container->setFields($4)) {
363 YYERROR;
364 }
365
Andreas Huberc9410c72016-07-28 12:18:40 -0700366 ast->leaveScope();
Andreas Huber5a545442016-08-03 10:44:56 -0700367 if (!ast->addScopedType($2, container)) {
368 YYERROR;
369 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700370 }
371 ;
372
373struct_or_union_declaration
374 : struct_or_union_keyword optIdentifier
375 {
Andreas Huber31629bc2016-08-03 09:06:40 -0700376 CompoundType *container = new CompoundType($1);
Andreas Huberc9410c72016-07-28 12:18:40 -0700377 ast->enterScope(container);
378 }
379 struct_or_union_body
380 {
381 CompoundType *container = static_cast<CompoundType *>(ast->scope());
382
Andreas Huber5a545442016-08-03 10:44:56 -0700383 if (!container->setFields($4)) {
384 YYERROR;
385 }
386
Andreas Huberc9410c72016-07-28 12:18:40 -0700387 ast->leaveScope();
Andreas Huber5a545442016-08-03 10:44:56 -0700388 if (!ast->addScopedType($2, container)) {
389 YYERROR;
390 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700391
Andreas Huberfd4afab2016-08-03 13:02:57 -0700392 $$ = container->ref();
Andreas Huberc9410c72016-07-28 12:18:40 -0700393 }
394 ;
395
396struct_or_union_body
397 : '{' field_declarations '}' { $$ = $2; }
398 ;
399
400field_declarations
Andreas Huber881227d2016-08-02 14:20:21 -0700401 : /* empty */ { $$ = new std::vector<CompoundField *>; }
Andreas Huberc9410c72016-07-28 12:18:40 -0700402 | field_declarations field_declaration
403 {
404 $$ = $1;
405
406 if ($2 != NULL) {
407 $$->push_back($2);
408 }
409 }
410 ;
411
412field_declaration
413 : type IDENTIFIER ';' { $$ = new CompoundField($2, $1); }
414 | struct_or_union_declaration ';' { $$ = NULL; }
415 | enum_declaration ';' { $$ = NULL; }
416 ;
417
418opt_storage_type
419 : /* empty */ { $$ = NULL; }
Andreas Huber8d3ac0c2016-08-04 14:49:23 -0700420 | ':' fqname
421 {
422 $$ = $2;
423
424 if ($$ != NULL && !$$->isValidEnumStorageType()) {
425 fprintf(stderr, "Invalid enum storage type specified.\n");
426 YYABORT;
427 }
428 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700429 ;
430
431opt_comma
432 : /* empty */
433 | ','
434 ;
435
436named_enum_declaration
437 : ENUM IDENTIFIER opt_storage_type '{' enum_values opt_comma '}'
438 {
Andreas Huber31629bc2016-08-03 09:06:40 -0700439 EnumType *enumType = new EnumType($5, $3);
Andreas Huber5a545442016-08-03 10:44:56 -0700440 if (!ast->addScopedType($2, enumType)) {
441 YYERROR;
442 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700443 }
444 ;
445
446enum_declaration
447 : ENUM '{' enum_values opt_comma '}'
448 {
Andreas Huber31629bc2016-08-03 09:06:40 -0700449 EnumType *enumType = new EnumType($3);
Andreas Huber5a545442016-08-03 10:44:56 -0700450 if (!ast->addScopedType(NULL /* localName */, enumType)) {
451 YYERROR;
452 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700453
Andreas Huberfd4afab2016-08-03 13:02:57 -0700454 $$ = enumType->ref();
Andreas Huberc9410c72016-07-28 12:18:40 -0700455 }
456 | ENUM IDENTIFIER opt_storage_type '{' enum_values opt_comma '}'
457 {
Andreas Huber31629bc2016-08-03 09:06:40 -0700458 EnumType *enumType = new EnumType($5, $3);
Andreas Huber5a545442016-08-03 10:44:56 -0700459 if (!ast->addScopedType($2, enumType)) {
460 YYERROR;
461 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700462
Andreas Huberfd4afab2016-08-03 13:02:57 -0700463 $$ = enumType->ref();
Andreas Huberc9410c72016-07-28 12:18:40 -0700464 }
465 ;
466
467enum_value
468 : IDENTIFIER { $$ = new EnumValue($1); }
469 | IDENTIFIER '=' INTEGER { $$ = new EnumValue($1, $3); }
470 | IDENTIFIER '=' IDENTIFIER { $$ = new EnumValue($1, $3); }
Andreas Huber006189f2016-07-29 15:51:17 -0700471 | IDENTIFIER '=' IDENTIFIER '+' INTEGER
472 {
473 $$ = new EnumValue(
474 $1, strdup(
475 android::String8::format("%s + %s", $3, $5).string()));
476 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700477 ;
478
479enum_values
480 : /* empty */
481 {
Andreas Huber881227d2016-08-02 14:20:21 -0700482 $$ = new std::vector<EnumValue *>;
Andreas Huberc9410c72016-07-28 12:18:40 -0700483 }
484 | enum_value
485 {
Andreas Huber881227d2016-08-02 14:20:21 -0700486 $$ = new std::vector<EnumValue *>;
Andreas Huberc9410c72016-07-28 12:18:40 -0700487 $$->push_back($1);
488 }
489 | enum_values ',' enum_value
490 {
491 $$ = $1;
492 $$->push_back($3);
493 }
494 ;
495
496type
Andreas Huber84f89de2016-07-28 15:39:51 -0700497 : fqname { $$ = $1; }
498 | fqname '[' INTEGER ']' { $$ = new ArrayType($1, $3); }
499 | VEC '<' fqname '>' { $$ = new VectorType($3); }
Andreas Huberc9410c72016-07-28 12:18:40 -0700500 | struct_or_union_declaration { $$ = $1; }
501 | enum_declaration { $$ = $1; }
502 ;
503
504optIdentifier
505 : /* empty */ { $$ = NULL; }
506 | IDENTIFIER { $$ = $1; }
507 ;
508
509%%