blob: 4f640ce4ae57b4cc9710b8398c44578384ac8d4e [file] [log] [blame]
Andreas Huberc9410c72016-07-28 12:18:40 -07001%{
2
3#include "AST.h"
4#include "ArrayType.h"
5#include "CompoundType.h"
6#include "Constant.h"
7#include "EnumType.h"
8#include "Interface.h"
9#include "Method.h"
Andreas Huberc9410c72016-07-28 12:18:40 -070010#include "TypeDef.h"
11#include "VectorType.h"
12
13#include "hidl-gen_y.h"
14
15#include <stdio.h>
Andreas Huber84f89de2016-07-28 15:39:51 -070016#include <utils/String8.h>
Andreas Huberc9410c72016-07-28 12:18:40 -070017
18using namespace android;
19
20extern int yylex(YYSTYPE *yylval_param, void *yyscanner);
21extern int column;
22
Andreas Hubereb1081f2016-07-28 13:13:24 -070023int yyerror(AST *, const char *s) {
Andreas Huberc9410c72016-07-28 12:18:40 -070024 fflush(stdout);
25 printf("\n%*s\n%*s\n", column, "^", column, s);
26
27 return 0;
28}
29
30#define scanner ast->scanner()
31
32%}
33
34%parse-param { android::AST *ast }
35%lex-param { void *scanner }
36%pure-parser
37
38%token<str> CONST
39%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
46%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
Andreas Huberc9410c72016-07-28 12:18:40 -070054
Andreas Huberc9410c72016-07-28 12:18:40 -070055%type<str> optIdentifier package
56%type<str> const_value
Andreas Huber84f89de2016-07-28 15:39:51 -070057%type<type> fqname
Andreas Huberc9410c72016-07-28 12:18:40 -070058
59%type<type> type opt_storage_type
60%type<type> enum_declaration
61%type<type> struct_or_union_declaration
62%type<type> opt_extends
63
64%type<field> field_declaration
65%type<fields> field_declarations struct_or_union_body
66%type<enumValue> enum_value
67%type<enumValues> enum_values
68%type<typedVars> typed_vars
69%type<typedVar> typed_var
70%type<method> method_declaration
71%type<compoundStyle> struct_or_union_keyword
72
73%start program
74
75%union {
76 const char *str;
77 android::Type *type;
78 android::CompoundType *compoundType;
79 android::CompoundField *field;
Andreas Huber881227d2016-08-02 14:20:21 -070080 std::vector<android::CompoundField *> *fields;
Andreas Huberc9410c72016-07-28 12:18:40 -070081 android::EnumValue *enumValue;
Andreas Huber881227d2016-08-02 14:20:21 -070082 std::vector<android::EnumValue *> *enumValues;
Andreas Huberc9410c72016-07-28 12:18:40 -070083 android::TypedVar *typedVar;
Andreas Huber881227d2016-08-02 14:20:21 -070084 std::vector<android::TypedVar *> *typedVars;
Andreas Huberc9410c72016-07-28 12:18:40 -070085 android::Method *method;
86 android::CompoundType::Style compoundStyle;
Andreas Hubereb1081f2016-07-28 13:13:24 -070087 android::Vector<std::string> *stringVec;
Andreas Huberc9410c72016-07-28 12:18:40 -070088}
89
90%%
91
92program
Andreas Huberda51b8e2016-07-28 16:00:57 -070093 : package imports body
Andreas Huber84f89de2016-07-28 15:39:51 -070094 ;
95
96fqname
97 : FQNAME
98 {
99 $$ = ast->lookupType($1);
100 if ($$ == NULL) {
101 yyerror(ast,
102 android::String8::format(
103 "Failed to lookup type '%s'.", $1).string());
104 YYERROR;
105 }
106 }
107 | IDENTIFIER
108 {
109 $$ = ast->lookupType($1);
110 if ($$ == NULL) {
111 yyerror(ast,
112 android::String8::format(
113 "Failed to lookup type '%s'.", $1).string());
114 YYERROR;
115 }
116 }
117 | SCALAR
118 ;
Andreas Huberc9410c72016-07-28 12:18:40 -0700119
120package
Andreas Huber84f89de2016-07-28 15:39:51 -0700121 : PACKAGE FQNAME ';'
Andreas Hubereb1081f2016-07-28 13:13:24 -0700122 {
Andreas Huber84f89de2016-07-28 15:39:51 -0700123 if (!ast->setPackage($2)) {
124 yyerror(ast, "Malformed package identifier.");
125 YYERROR;
126 }
Andreas Hubereb1081f2016-07-28 13:13:24 -0700127 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700128
Andreas Huberc9410c72016-07-28 12:18:40 -0700129imports
130 : /* empty */
Andreas Huber84f89de2016-07-28 15:39:51 -0700131 | imports IMPORT FQNAME ';'
Andreas Hubereb1081f2016-07-28 13:13:24 -0700132 {
Andreas Huber68f24592016-07-29 14:53:48 -0700133 if (!ast->addImport($3)) {
134 yyerror(ast,
135 android::String8::format(
136 "Unable to import '%s'.", $3));
137
138 YYERROR;
139 }
Andreas Hubereb1081f2016-07-28 13:13:24 -0700140 }
Andreas Huber5345ec22016-07-29 13:33:27 -0700141 | imports IMPORT IDENTIFIER ';'
142 {
Andreas Huber68f24592016-07-29 14:53:48 -0700143 if (!ast->addImport($3)) {
144 yyerror(ast,
145 android::String8::format(
146 "Unable to import '%s'.", $3));
147
148 YYERROR;
149 }
Andreas Huber5345ec22016-07-29 13:33:27 -0700150 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700151 ;
152
153opt_extends
154 : /* empty */ { $$ = NULL; }
Andreas Huber84f89de2016-07-28 15:39:51 -0700155 | EXTENDS fqname { $$ = $2; }
Andreas Huberc9410c72016-07-28 12:18:40 -0700156
157body
158 : INTERFACE IDENTIFIER opt_extends
159 {
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700160 if ($3 != NULL && !$3->isInterface()) {
161 fprintf(stderr, "You can only extend interfaces.\n");
162 YYERROR;
163 }
164
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700165 Interface *iface = new Interface(static_cast<Interface *>($3));
Andreas Hubereb1081f2016-07-28 13:13:24 -0700166
167 // Register interface immediately so it can be referenced inside
168 // definition.
Andreas Huber5a545442016-08-03 10:44:56 -0700169 if (!ast->addScopedType($2, iface)) {
170 YYERROR;
171 }
Andreas Hubereb1081f2016-07-28 13:13:24 -0700172
Andreas Huberc9410c72016-07-28 12:18:40 -0700173 ast->enterScope(iface);
174 }
175 '{' interface_declarations '}' ';'
176 {
177 Interface *iface = static_cast<Interface *>(ast->scope());
178
179 ast->leaveScope();
Andreas Huberc9410c72016-07-28 12:18:40 -0700180 }
181 | type_declarations
182 ;
183
184interface_declarations
185 : /* empty */
186 | interface_declarations type_declaration
187 | interface_declarations method_declaration
188 {
189 Interface *iface = static_cast<Interface *>(ast->scope());
190 iface->addMethod($2);
191 }
192 ;
193
194type_declarations
Andreas Hubera2723d22016-07-29 15:36:07 -0700195 : /* empty */
Andreas Huberc9410c72016-07-28 12:18:40 -0700196 | type_declarations type_declaration
197 ;
198
199type_declaration
200 : named_struct_or_union_declaration ';'
201 | named_enum_declaration ';'
202 | typedef_declaration ';'
203 | const_declaration ';'
204 ;
205
206typedef_declaration
207 : TYPEDEF type IDENTIFIER
208 {
Andreas Huber31629bc2016-08-03 09:06:40 -0700209 TypeDef *def = new TypeDef($2);
Andreas Huber5a545442016-08-03 10:44:56 -0700210 if (!ast->addScopedType($3, def)) {
211 YYERROR;
212 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700213 }
214 ;
215
216const_value
217 : INTEGER
218 | STRING_LITERAL ;
219
220const_declaration
Andreas Huber84f89de2016-07-28 15:39:51 -0700221 : CONST fqname IDENTIFIER '=' const_value
Andreas Huberc9410c72016-07-28 12:18:40 -0700222 {
223 Constant *constant = new Constant($3, $2, $5);
224 ast->scope()->addConstant(constant);
225 }
226 ;
227
228method_declaration
229 : IDENTIFIER '(' typed_vars ')' ';'
230 {
Andreas Huber881227d2016-08-02 14:20:21 -0700231 $$ = new Method($1, $3, new std::vector<TypedVar *>);
Andreas Huberc9410c72016-07-28 12:18:40 -0700232 }
233 | IDENTIFIER '(' typed_vars ')' GENERATES '(' typed_vars ')' ';'
234 {
235 $$ = new Method($1, $3, $7);
236 }
237 ;
238
239typed_vars
240 : /* empty */
241 {
Andreas Huber881227d2016-08-02 14:20:21 -0700242 $$ = new std::vector<TypedVar *>;
Andreas Huberc9410c72016-07-28 12:18:40 -0700243 }
244 | typed_var
245 {
Andreas Huber881227d2016-08-02 14:20:21 -0700246 $$ = new std::vector<TypedVar *>;
Andreas Huberc9410c72016-07-28 12:18:40 -0700247 $$->push_back($1);
248 }
249 | typed_vars ',' typed_var
250 {
251 $$ = $1;
252 $$->push_back($3);
253 }
254 ;
255
256typed_var : type IDENTIFIER { $$ = new TypedVar($2, $1); }
257 ;
258
259
260struct_or_union_keyword
261 : STRUCT { $$ = CompoundType::STYLE_STRUCT; }
262 | UNION { $$ = CompoundType::STYLE_UNION; }
263 ;
264
265named_struct_or_union_declaration
266 : struct_or_union_keyword IDENTIFIER
267 {
Andreas Huber31629bc2016-08-03 09:06:40 -0700268 CompoundType *container = new CompoundType($1);
Andreas Huberc9410c72016-07-28 12:18:40 -0700269 ast->enterScope(container);
270 }
271 struct_or_union_body
272 {
273 CompoundType *container = static_cast<CompoundType *>(ast->scope());
274
Andreas Huber5a545442016-08-03 10:44:56 -0700275 if (!container->setFields($4)) {
276 YYERROR;
277 }
278
Andreas Huberc9410c72016-07-28 12:18:40 -0700279 ast->leaveScope();
Andreas Huber5a545442016-08-03 10:44:56 -0700280 if (!ast->addScopedType($2, container)) {
281 YYERROR;
282 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700283 }
284 ;
285
286struct_or_union_declaration
287 : struct_or_union_keyword optIdentifier
288 {
Andreas Huber31629bc2016-08-03 09:06:40 -0700289 CompoundType *container = new CompoundType($1);
Andreas Huberc9410c72016-07-28 12:18:40 -0700290 ast->enterScope(container);
291 }
292 struct_or_union_body
293 {
294 CompoundType *container = static_cast<CompoundType *>(ast->scope());
295
Andreas Huber5a545442016-08-03 10:44:56 -0700296 if (!container->setFields($4)) {
297 YYERROR;
298 }
299
Andreas Huberc9410c72016-07-28 12:18:40 -0700300 ast->leaveScope();
Andreas Huber5a545442016-08-03 10:44:56 -0700301 if (!ast->addScopedType($2, container)) {
302 YYERROR;
303 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700304
Andreas Huberfd4afab2016-08-03 13:02:57 -0700305 $$ = container->ref();
Andreas Huberc9410c72016-07-28 12:18:40 -0700306 }
307 ;
308
309struct_or_union_body
310 : '{' field_declarations '}' { $$ = $2; }
311 ;
312
313field_declarations
Andreas Huber881227d2016-08-02 14:20:21 -0700314 : /* empty */ { $$ = new std::vector<CompoundField *>; }
Andreas Huberc9410c72016-07-28 12:18:40 -0700315 | field_declarations field_declaration
316 {
317 $$ = $1;
318
319 if ($2 != NULL) {
320 $$->push_back($2);
321 }
322 }
323 ;
324
325field_declaration
326 : type IDENTIFIER ';' { $$ = new CompoundField($2, $1); }
327 | struct_or_union_declaration ';' { $$ = NULL; }
328 | enum_declaration ';' { $$ = NULL; }
329 ;
330
331opt_storage_type
332 : /* empty */ { $$ = NULL; }
Andreas Huber8d3ac0c2016-08-04 14:49:23 -0700333 | ':' fqname
334 {
335 $$ = $2;
336
337 if ($$ != NULL && !$$->isValidEnumStorageType()) {
338 fprintf(stderr, "Invalid enum storage type specified.\n");
339 YYABORT;
340 }
341 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700342 ;
343
344opt_comma
345 : /* empty */
346 | ','
347 ;
348
349named_enum_declaration
350 : ENUM IDENTIFIER opt_storage_type '{' enum_values opt_comma '}'
351 {
Andreas Huber31629bc2016-08-03 09:06:40 -0700352 EnumType *enumType = new EnumType($5, $3);
Andreas Huber5a545442016-08-03 10:44:56 -0700353 if (!ast->addScopedType($2, enumType)) {
354 YYERROR;
355 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700356 }
357 ;
358
359enum_declaration
360 : ENUM '{' enum_values opt_comma '}'
361 {
Andreas Huber31629bc2016-08-03 09:06:40 -0700362 EnumType *enumType = new EnumType($3);
Andreas Huber5a545442016-08-03 10:44:56 -0700363 if (!ast->addScopedType(NULL /* localName */, enumType)) {
364 YYERROR;
365 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700366
Andreas Huberfd4afab2016-08-03 13:02:57 -0700367 $$ = enumType->ref();
Andreas Huberc9410c72016-07-28 12:18:40 -0700368 }
369 | ENUM IDENTIFIER opt_storage_type '{' enum_values opt_comma '}'
370 {
Andreas Huber31629bc2016-08-03 09:06:40 -0700371 EnumType *enumType = new EnumType($5, $3);
Andreas Huber5a545442016-08-03 10:44:56 -0700372 if (!ast->addScopedType($2, enumType)) {
373 YYERROR;
374 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700375
Andreas Huberfd4afab2016-08-03 13:02:57 -0700376 $$ = enumType->ref();
Andreas Huberc9410c72016-07-28 12:18:40 -0700377 }
378 ;
379
380enum_value
381 : IDENTIFIER { $$ = new EnumValue($1); }
382 | IDENTIFIER '=' INTEGER { $$ = new EnumValue($1, $3); }
383 | IDENTIFIER '=' IDENTIFIER { $$ = new EnumValue($1, $3); }
Andreas Huber006189f2016-07-29 15:51:17 -0700384 | IDENTIFIER '=' IDENTIFIER '+' INTEGER
385 {
386 $$ = new EnumValue(
387 $1, strdup(
388 android::String8::format("%s + %s", $3, $5).string()));
389 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700390 ;
391
392enum_values
393 : /* empty */
394 {
Andreas Huber881227d2016-08-02 14:20:21 -0700395 $$ = new std::vector<EnumValue *>;
Andreas Huberc9410c72016-07-28 12:18:40 -0700396 }
397 | enum_value
398 {
Andreas Huber881227d2016-08-02 14:20:21 -0700399 $$ = new std::vector<EnumValue *>;
Andreas Huberc9410c72016-07-28 12:18:40 -0700400 $$->push_back($1);
401 }
402 | enum_values ',' enum_value
403 {
404 $$ = $1;
405 $$->push_back($3);
406 }
407 ;
408
409type
Andreas Huber84f89de2016-07-28 15:39:51 -0700410 : fqname { $$ = $1; }
411 | fqname '[' INTEGER ']' { $$ = new ArrayType($1, $3); }
412 | VEC '<' fqname '>' { $$ = new VectorType($3); }
Andreas Huberc9410c72016-07-28 12:18:40 -0700413 | struct_or_union_declaration { $$ = $1; }
414 | enum_declaration { $$ = $1; }
415 ;
416
417optIdentifier
418 : /* empty */ { $$ = NULL; }
419 | IDENTIFIER { $$ = $1; }
420 ;
421
422%%