blob: e1d46cea22875894179d7b1b18135d824c875ec5 [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;
81 android::Vector<android::CompoundField *> *fields;
82 android::EnumValue *enumValue;
83 android::Vector<android::EnumValue *> *enumValues;
84 android::TypedVar *typedVar;
85 android::Vector<android::TypedVar *> *typedVars;
86 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 {
161 Interface *iface = new Interface($2, $3);
Andreas Hubereb1081f2016-07-28 13:13:24 -0700162
163 // Register interface immediately so it can be referenced inside
164 // definition.
165 ast->scope()->addType(iface);
166
Andreas Huberc9410c72016-07-28 12:18:40 -0700167 ast->enterScope(iface);
168 }
169 '{' interface_declarations '}' ';'
170 {
171 Interface *iface = static_cast<Interface *>(ast->scope());
172
173 ast->leaveScope();
Andreas Huberc9410c72016-07-28 12:18:40 -0700174 }
175 | type_declarations
176 ;
177
178interface_declarations
179 : /* empty */
180 | interface_declarations type_declaration
181 | interface_declarations method_declaration
182 {
183 Interface *iface = static_cast<Interface *>(ast->scope());
184 iface->addMethod($2);
185 }
186 ;
187
188type_declarations
Andreas Hubera2723d22016-07-29 15:36:07 -0700189 : /* empty */
Andreas Huberc9410c72016-07-28 12:18:40 -0700190 | type_declarations type_declaration
191 ;
192
193type_declaration
194 : named_struct_or_union_declaration ';'
195 | named_enum_declaration ';'
196 | typedef_declaration ';'
197 | const_declaration ';'
198 ;
199
200typedef_declaration
201 : TYPEDEF type IDENTIFIER
202 {
203 TypeDef *def = new TypeDef($3, $2);
204 ast->scope()->addType(def);
205 }
206 ;
207
208const_value
209 : INTEGER
210 | STRING_LITERAL ;
211
212const_declaration
Andreas Huber84f89de2016-07-28 15:39:51 -0700213 : CONST fqname IDENTIFIER '=' const_value
Andreas Huberc9410c72016-07-28 12:18:40 -0700214 {
215 Constant *constant = new Constant($3, $2, $5);
216 ast->scope()->addConstant(constant);
217 }
218 ;
219
220method_declaration
221 : IDENTIFIER '(' typed_vars ')' ';'
222 {
223 $$ = new Method($1, $3);
224 }
225 | IDENTIFIER '(' typed_vars ')' GENERATES '(' typed_vars ')' ';'
226 {
227 $$ = new Method($1, $3, $7);
228 }
229 ;
230
231typed_vars
232 : /* empty */
233 {
234 $$ = new Vector<TypedVar *>;
235 }
236 | typed_var
237 {
238 $$ = new Vector<TypedVar *>;
239 $$->push_back($1);
240 }
241 | typed_vars ',' typed_var
242 {
243 $$ = $1;
244 $$->push_back($3);
245 }
246 ;
247
248typed_var : type IDENTIFIER { $$ = new TypedVar($2, $1); }
249 ;
250
251
252struct_or_union_keyword
253 : STRUCT { $$ = CompoundType::STYLE_STRUCT; }
254 | UNION { $$ = CompoundType::STYLE_UNION; }
255 ;
256
257named_struct_or_union_declaration
258 : struct_or_union_keyword IDENTIFIER
259 {
260 CompoundType *container = new CompoundType($1, $2);
261 ast->enterScope(container);
262 }
263 struct_or_union_body
264 {
265 CompoundType *container = static_cast<CompoundType *>(ast->scope());
266
267 container->setFields($4);
268 ast->leaveScope();
269 ast->scope()->addType(container);
270 }
271 ;
272
273struct_or_union_declaration
274 : struct_or_union_keyword optIdentifier
275 {
276 CompoundType *container = new CompoundType($1, $2);
277 ast->enterScope(container);
278 }
279 struct_or_union_body
280 {
281 CompoundType *container = static_cast<CompoundType *>(ast->scope());
282
283 container->setFields($4);
284 ast->leaveScope();
285 ast->scope()->addType(container);
286
287 $$ = new RefType(container->name().c_str(), container);
288 }
289 ;
290
291struct_or_union_body
292 : '{' field_declarations '}' { $$ = $2; }
293 ;
294
295field_declarations
296 : /* empty */ { $$ = new Vector<CompoundField *>; }
297 | field_declarations field_declaration
298 {
299 $$ = $1;
300
301 if ($2 != NULL) {
302 $$->push_back($2);
303 }
304 }
305 ;
306
307field_declaration
308 : type IDENTIFIER ';' { $$ = new CompoundField($2, $1); }
309 | struct_or_union_declaration ';' { $$ = NULL; }
310 | enum_declaration ';' { $$ = NULL; }
311 ;
312
313opt_storage_type
314 : /* empty */ { $$ = NULL; }
Andreas Huber84f89de2016-07-28 15:39:51 -0700315 | ':' fqname { $$ = $2; }
Andreas Huberc9410c72016-07-28 12:18:40 -0700316 ;
317
318opt_comma
319 : /* empty */
320 | ','
321 ;
322
323named_enum_declaration
324 : ENUM IDENTIFIER opt_storage_type '{' enum_values opt_comma '}'
325 {
326 EnumType *enumType = new EnumType($2, $5, $3);
327 ast->scope()->addType(enumType);
328 }
329 ;
330
331enum_declaration
332 : ENUM '{' enum_values opt_comma '}'
333 {
334 EnumType *enumType = new EnumType(NULL /* name */, $3);
335 ast->scope()->addType(enumType);
336
337 $$ = new RefType(enumType->name().c_str(), enumType);
338 }
339 | ENUM IDENTIFIER opt_storage_type '{' enum_values opt_comma '}'
340 {
341 EnumType *enumType = new EnumType($2, $5, $3);
342 ast->scope()->addType(enumType);
343
344 $$ = new RefType(enumType->name().c_str(), enumType);
345 }
346 ;
347
348enum_value
349 : IDENTIFIER { $$ = new EnumValue($1); }
350 | IDENTIFIER '=' INTEGER { $$ = new EnumValue($1, $3); }
351 | IDENTIFIER '=' IDENTIFIER { $$ = new EnumValue($1, $3); }
352 ;
353
354enum_values
355 : /* empty */
356 {
357 $$ = new Vector<EnumValue *>;
358 }
359 | enum_value
360 {
361 $$ = new Vector<EnumValue *>;
362 $$->push_back($1);
363 }
364 | enum_values ',' enum_value
365 {
366 $$ = $1;
367 $$->push_back($3);
368 }
369 ;
370
371type
Andreas Huber84f89de2016-07-28 15:39:51 -0700372 : fqname { $$ = $1; }
373 | fqname '[' INTEGER ']' { $$ = new ArrayType($1, $3); }
374 | VEC '<' fqname '>' { $$ = new VectorType($3); }
Andreas Huberc9410c72016-07-28 12:18:40 -0700375 | struct_or_union_declaration { $$ = $1; }
376 | enum_declaration { $$ = $1; }
377 ;
378
379optIdentifier
380 : /* empty */ { $$ = NULL; }
381 | IDENTIFIER { $$ = $1; }
382 ;
383
384%%