blob: 93988fef996534cda58f30ee8c578b8e794ead6a [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"
10#include "RefType.h"
11#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
73
74%start program
75
76%union {
77 const char *str;
78 android::Type *type;
79 android::CompoundType *compoundType;
80 android::CompoundField *field;
Andreas Huber881227d2016-08-02 14:20:21 -070081 std::vector<android::CompoundField *> *fields;
Andreas Huberc9410c72016-07-28 12:18:40 -070082 android::EnumValue *enumValue;
Andreas Huber881227d2016-08-02 14:20:21 -070083 std::vector<android::EnumValue *> *enumValues;
Andreas Huberc9410c72016-07-28 12:18:40 -070084 android::TypedVar *typedVar;
Andreas Huber881227d2016-08-02 14:20:21 -070085 std::vector<android::TypedVar *> *typedVars;
Andreas Huberc9410c72016-07-28 12:18:40 -070086 android::Method *method;
87 android::CompoundType::Style compoundStyle;
Andreas Hubereb1081f2016-07-28 13:13:24 -070088 android::Vector<std::string> *stringVec;
Andreas Huberc9410c72016-07-28 12:18:40 -070089}
90
91%%
92
93program
Andreas Huberda51b8e2016-07-28 16:00:57 -070094 : package imports body
Andreas Huber84f89de2016-07-28 15:39:51 -070095 ;
96
97fqname
98 : FQNAME
99 {
100 $$ = ast->lookupType($1);
101 if ($$ == NULL) {
102 yyerror(ast,
103 android::String8::format(
104 "Failed to lookup type '%s'.", $1).string());
105 YYERROR;
106 }
107 }
108 | IDENTIFIER
109 {
110 $$ = ast->lookupType($1);
111 if ($$ == NULL) {
112 yyerror(ast,
113 android::String8::format(
114 "Failed to lookup type '%s'.", $1).string());
115 YYERROR;
116 }
117 }
118 | SCALAR
119 ;
Andreas Huberc9410c72016-07-28 12:18:40 -0700120
121package
Andreas Huber84f89de2016-07-28 15:39:51 -0700122 : PACKAGE FQNAME ';'
Andreas Hubereb1081f2016-07-28 13:13:24 -0700123 {
Andreas Huber84f89de2016-07-28 15:39:51 -0700124 if (!ast->setPackage($2)) {
125 yyerror(ast, "Malformed package identifier.");
126 YYERROR;
127 }
Andreas Hubereb1081f2016-07-28 13:13:24 -0700128 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700129
Andreas Huberc9410c72016-07-28 12:18:40 -0700130imports
131 : /* empty */
Andreas Huber84f89de2016-07-28 15:39:51 -0700132 | imports IMPORT FQNAME ';'
Andreas Hubereb1081f2016-07-28 13:13:24 -0700133 {
Andreas Huber68f24592016-07-29 14:53:48 -0700134 if (!ast->addImport($3)) {
135 yyerror(ast,
136 android::String8::format(
137 "Unable to import '%s'.", $3));
138
139 YYERROR;
140 }
Andreas Hubereb1081f2016-07-28 13:13:24 -0700141 }
Andreas Huber5345ec22016-07-29 13:33:27 -0700142 | imports IMPORT IDENTIFIER ';'
143 {
Andreas Huber68f24592016-07-29 14:53:48 -0700144 if (!ast->addImport($3)) {
145 yyerror(ast,
146 android::String8::format(
147 "Unable to import '%s'.", $3));
148
149 YYERROR;
150 }
Andreas Huber5345ec22016-07-29 13:33:27 -0700151 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700152 ;
153
154opt_extends
155 : /* empty */ { $$ = NULL; }
Andreas Huber84f89de2016-07-28 15:39:51 -0700156 | EXTENDS fqname { $$ = $2; }
Andreas Huberc9410c72016-07-28 12:18:40 -0700157
158body
159 : INTERFACE IDENTIFIER opt_extends
160 {
Andreas Huber31629bc2016-08-03 09:06:40 -0700161 Interface *iface = new Interface($3);
Andreas Hubereb1081f2016-07-28 13:13:24 -0700162
163 // Register interface immediately so it can be referenced inside
164 // definition.
Andreas Huber5a545442016-08-03 10:44:56 -0700165 if (!ast->addScopedType($2, iface)) {
166 YYERROR;
167 }
Andreas Hubereb1081f2016-07-28 13:13:24 -0700168
Andreas Huberc9410c72016-07-28 12:18:40 -0700169 ast->enterScope(iface);
170 }
171 '{' interface_declarations '}' ';'
172 {
173 Interface *iface = static_cast<Interface *>(ast->scope());
174
175 ast->leaveScope();
Andreas Huberc9410c72016-07-28 12:18:40 -0700176 }
177 | type_declarations
178 ;
179
180interface_declarations
181 : /* empty */
182 | interface_declarations type_declaration
183 | interface_declarations method_declaration
184 {
185 Interface *iface = static_cast<Interface *>(ast->scope());
186 iface->addMethod($2);
187 }
188 ;
189
190type_declarations
Andreas Hubera2723d22016-07-29 15:36:07 -0700191 : /* empty */
Andreas Huberc9410c72016-07-28 12:18:40 -0700192 | type_declarations type_declaration
193 ;
194
195type_declaration
196 : named_struct_or_union_declaration ';'
197 | named_enum_declaration ';'
198 | typedef_declaration ';'
199 | const_declaration ';'
200 ;
201
202typedef_declaration
203 : TYPEDEF type IDENTIFIER
204 {
Andreas Huber31629bc2016-08-03 09:06:40 -0700205 TypeDef *def = new TypeDef($2);
Andreas Huber5a545442016-08-03 10:44:56 -0700206 if (!ast->addScopedType($3, def)) {
207 YYERROR;
208 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700209 }
210 ;
211
212const_value
213 : INTEGER
214 | STRING_LITERAL ;
215
216const_declaration
Andreas Huber84f89de2016-07-28 15:39:51 -0700217 : CONST fqname IDENTIFIER '=' const_value
Andreas Huberc9410c72016-07-28 12:18:40 -0700218 {
219 Constant *constant = new Constant($3, $2, $5);
220 ast->scope()->addConstant(constant);
221 }
222 ;
223
224method_declaration
225 : IDENTIFIER '(' typed_vars ')' ';'
226 {
Andreas Huber881227d2016-08-02 14:20:21 -0700227 $$ = new Method($1, $3, new std::vector<TypedVar *>);
Andreas Huberc9410c72016-07-28 12:18:40 -0700228 }
229 | IDENTIFIER '(' typed_vars ')' GENERATES '(' typed_vars ')' ';'
230 {
231 $$ = new Method($1, $3, $7);
232 }
233 ;
234
235typed_vars
236 : /* empty */
237 {
Andreas Huber881227d2016-08-02 14:20:21 -0700238 $$ = new std::vector<TypedVar *>;
Andreas Huberc9410c72016-07-28 12:18:40 -0700239 }
240 | typed_var
241 {
Andreas Huber881227d2016-08-02 14:20:21 -0700242 $$ = new std::vector<TypedVar *>;
Andreas Huberc9410c72016-07-28 12:18:40 -0700243 $$->push_back($1);
244 }
245 | typed_vars ',' typed_var
246 {
247 $$ = $1;
248 $$->push_back($3);
249 }
250 ;
251
252typed_var : type IDENTIFIER { $$ = new TypedVar($2, $1); }
253 ;
254
255
256struct_or_union_keyword
257 : STRUCT { $$ = CompoundType::STYLE_STRUCT; }
258 | UNION { $$ = CompoundType::STYLE_UNION; }
259 ;
260
261named_struct_or_union_declaration
262 : struct_or_union_keyword IDENTIFIER
263 {
Andreas Huber31629bc2016-08-03 09:06:40 -0700264 CompoundType *container = new CompoundType($1);
Andreas Huberc9410c72016-07-28 12:18:40 -0700265 ast->enterScope(container);
266 }
267 struct_or_union_body
268 {
269 CompoundType *container = static_cast<CompoundType *>(ast->scope());
270
Andreas Huber5a545442016-08-03 10:44:56 -0700271 if (!container->setFields($4)) {
272 YYERROR;
273 }
274
Andreas Huberc9410c72016-07-28 12:18:40 -0700275 ast->leaveScope();
Andreas Huber5a545442016-08-03 10:44:56 -0700276 if (!ast->addScopedType($2, container)) {
277 YYERROR;
278 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700279 }
280 ;
281
282struct_or_union_declaration
283 : struct_or_union_keyword optIdentifier
284 {
Andreas Huber31629bc2016-08-03 09:06:40 -0700285 CompoundType *container = new CompoundType($1);
Andreas Huberc9410c72016-07-28 12:18:40 -0700286 ast->enterScope(container);
287 }
288 struct_or_union_body
289 {
290 CompoundType *container = static_cast<CompoundType *>(ast->scope());
291
Andreas Huber5a545442016-08-03 10:44:56 -0700292 if (!container->setFields($4)) {
293 YYERROR;
294 }
295
Andreas Huberc9410c72016-07-28 12:18:40 -0700296 ast->leaveScope();
Andreas Huber5a545442016-08-03 10:44:56 -0700297 if (!ast->addScopedType($2, container)) {
298 YYERROR;
299 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700300
Andreas Huber867fcb62016-08-02 16:26:34 -0700301 $$ = new RefType(container);
Andreas Huberc9410c72016-07-28 12:18:40 -0700302 }
303 ;
304
305struct_or_union_body
306 : '{' field_declarations '}' { $$ = $2; }
307 ;
308
309field_declarations
Andreas Huber881227d2016-08-02 14:20:21 -0700310 : /* empty */ { $$ = new std::vector<CompoundField *>; }
Andreas Huberc9410c72016-07-28 12:18:40 -0700311 | field_declarations field_declaration
312 {
313 $$ = $1;
314
315 if ($2 != NULL) {
316 $$->push_back($2);
317 }
318 }
319 ;
320
321field_declaration
322 : type IDENTIFIER ';' { $$ = new CompoundField($2, $1); }
323 | struct_or_union_declaration ';' { $$ = NULL; }
324 | enum_declaration ';' { $$ = NULL; }
325 ;
326
327opt_storage_type
328 : /* empty */ { $$ = NULL; }
Andreas Huber84f89de2016-07-28 15:39:51 -0700329 | ':' fqname { $$ = $2; }
Andreas Huberc9410c72016-07-28 12:18:40 -0700330 ;
331
332opt_comma
333 : /* empty */
334 | ','
335 ;
336
337named_enum_declaration
338 : ENUM IDENTIFIER opt_storage_type '{' enum_values opt_comma '}'
339 {
Andreas Huber31629bc2016-08-03 09:06:40 -0700340 EnumType *enumType = new EnumType($5, $3);
Andreas Huber5a545442016-08-03 10:44:56 -0700341 if (!ast->addScopedType($2, enumType)) {
342 YYERROR;
343 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700344 }
345 ;
346
347enum_declaration
348 : ENUM '{' enum_values opt_comma '}'
349 {
Andreas Huber31629bc2016-08-03 09:06:40 -0700350 EnumType *enumType = new EnumType($3);
Andreas Huber5a545442016-08-03 10:44:56 -0700351 if (!ast->addScopedType(NULL /* localName */, enumType)) {
352 YYERROR;
353 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700354
Andreas Huber867fcb62016-08-02 16:26:34 -0700355 $$ = new RefType(enumType);
Andreas Huberc9410c72016-07-28 12:18:40 -0700356 }
357 | ENUM IDENTIFIER opt_storage_type '{' enum_values opt_comma '}'
358 {
Andreas Huber31629bc2016-08-03 09:06:40 -0700359 EnumType *enumType = new EnumType($5, $3);
Andreas Huber5a545442016-08-03 10:44:56 -0700360 if (!ast->addScopedType($2, enumType)) {
361 YYERROR;
362 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700363
Andreas Huber867fcb62016-08-02 16:26:34 -0700364 $$ = new RefType(enumType);
Andreas Huberc9410c72016-07-28 12:18:40 -0700365 }
366 ;
367
368enum_value
369 : IDENTIFIER { $$ = new EnumValue($1); }
370 | IDENTIFIER '=' INTEGER { $$ = new EnumValue($1, $3); }
371 | IDENTIFIER '=' IDENTIFIER { $$ = new EnumValue($1, $3); }
Andreas Huber006189f2016-07-29 15:51:17 -0700372 | IDENTIFIER '=' IDENTIFIER '+' INTEGER
373 {
374 $$ = new EnumValue(
375 $1, strdup(
376 android::String8::format("%s + %s", $3, $5).string()));
377 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700378 ;
379
380enum_values
381 : /* empty */
382 {
Andreas Huber881227d2016-08-02 14:20:21 -0700383 $$ = new std::vector<EnumValue *>;
Andreas Huberc9410c72016-07-28 12:18:40 -0700384 }
385 | enum_value
386 {
Andreas Huber881227d2016-08-02 14:20:21 -0700387 $$ = new std::vector<EnumValue *>;
Andreas Huberc9410c72016-07-28 12:18:40 -0700388 $$->push_back($1);
389 }
390 | enum_values ',' enum_value
391 {
392 $$ = $1;
393 $$->push_back($3);
394 }
395 ;
396
397type
Andreas Huber84f89de2016-07-28 15:39:51 -0700398 : fqname { $$ = $1; }
399 | fqname '[' INTEGER ']' { $$ = new ArrayType($1, $3); }
400 | VEC '<' fqname '>' { $$ = new VectorType($3); }
Andreas Huberc9410c72016-07-28 12:18:40 -0700401 | struct_or_union_declaration { $$ = $1; }
402 | enum_declaration { $$ = $1; }
403 ;
404
405optIdentifier
406 : /* empty */ { $$ = NULL; }
407 | IDENTIFIER { $$ = $1; }
408 ;
409
410%%