blob: 9b09c30ae947df6a9d5ccbebc9adbaf317d474c7 [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
55%token<str> VERSION
56
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
74
75%start program
76
77%union {
78 const char *str;
79 android::Type *type;
80 android::CompoundType *compoundType;
81 android::CompoundField *field;
82 android::Vector<android::CompoundField *> *fields;
83 android::EnumValue *enumValue;
84 android::Vector<android::EnumValue *> *enumValues;
85 android::TypedVar *typedVar;
86 android::Vector<android::TypedVar *> *typedVars;
87 android::Method *method;
88 android::CompoundType::Style compoundStyle;
Andreas Hubereb1081f2016-07-28 13:13:24 -070089 android::Vector<std::string> *stringVec;
Andreas Huberc9410c72016-07-28 12:18:40 -070090}
91
92%%
93
94program
95 : version package imports body
96 ;
97
98version
99 : VERSION INTEGER '.' INTEGER ';'
Andreas Hubereb1081f2016-07-28 13:13:24 -0700100 {
101 ast->setVersion($2, $4);
102 }
Andreas Huber84f89de2016-07-28 15:39:51 -0700103 ;
104
105fqname
106 : FQNAME
107 {
108 $$ = ast->lookupType($1);
109 if ($$ == NULL) {
110 yyerror(ast,
111 android::String8::format(
112 "Failed to lookup type '%s'.", $1).string());
113 YYERROR;
114 }
115 }
116 | IDENTIFIER
117 {
118 $$ = ast->lookupType($1);
119 if ($$ == NULL) {
120 yyerror(ast,
121 android::String8::format(
122 "Failed to lookup type '%s'.", $1).string());
123 YYERROR;
124 }
125 }
126 | SCALAR
127 ;
Andreas Huberc9410c72016-07-28 12:18:40 -0700128
129package
Andreas Huber84f89de2016-07-28 15:39:51 -0700130 : PACKAGE FQNAME ';'
Andreas Hubereb1081f2016-07-28 13:13:24 -0700131 {
Andreas Huber84f89de2016-07-28 15:39:51 -0700132 if (!ast->setPackage($2)) {
133 yyerror(ast, "Malformed package identifier.");
134 YYERROR;
135 }
Andreas Hubereb1081f2016-07-28 13:13:24 -0700136 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700137
Andreas Huberc9410c72016-07-28 12:18:40 -0700138imports
139 : /* empty */
Andreas Huber84f89de2016-07-28 15:39:51 -0700140 | imports IMPORT FQNAME ';'
Andreas Hubereb1081f2016-07-28 13:13:24 -0700141 {
142 ast->addImport($3);
143 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700144 ;
145
146opt_extends
147 : /* empty */ { $$ = NULL; }
Andreas Huber84f89de2016-07-28 15:39:51 -0700148 | EXTENDS fqname { $$ = $2; }
Andreas Huberc9410c72016-07-28 12:18:40 -0700149
150body
151 : INTERFACE IDENTIFIER opt_extends
152 {
153 Interface *iface = new Interface($2, $3);
Andreas Hubereb1081f2016-07-28 13:13:24 -0700154
155 // Register interface immediately so it can be referenced inside
156 // definition.
157 ast->scope()->addType(iface);
158
Andreas Huberc9410c72016-07-28 12:18:40 -0700159 ast->enterScope(iface);
160 }
161 '{' interface_declarations '}' ';'
162 {
163 Interface *iface = static_cast<Interface *>(ast->scope());
164
165 ast->leaveScope();
Andreas Huberc9410c72016-07-28 12:18:40 -0700166 }
167 | type_declarations
168 ;
169
170interface_declarations
171 : /* empty */
172 | interface_declarations type_declaration
173 | interface_declarations method_declaration
174 {
175 Interface *iface = static_cast<Interface *>(ast->scope());
176 iface->addMethod($2);
177 }
178 ;
179
180type_declarations
181 : type_declaration
182 | type_declarations type_declaration
183 ;
184
185type_declaration
186 : named_struct_or_union_declaration ';'
187 | named_enum_declaration ';'
188 | typedef_declaration ';'
189 | const_declaration ';'
190 ;
191
192typedef_declaration
193 : TYPEDEF type IDENTIFIER
194 {
195 TypeDef *def = new TypeDef($3, $2);
196 ast->scope()->addType(def);
197 }
198 ;
199
200const_value
201 : INTEGER
202 | STRING_LITERAL ;
203
204const_declaration
Andreas Huber84f89de2016-07-28 15:39:51 -0700205 : CONST fqname IDENTIFIER '=' const_value
Andreas Huberc9410c72016-07-28 12:18:40 -0700206 {
207 Constant *constant = new Constant($3, $2, $5);
208 ast->scope()->addConstant(constant);
209 }
210 ;
211
212method_declaration
213 : IDENTIFIER '(' typed_vars ')' ';'
214 {
215 $$ = new Method($1, $3);
216 }
217 | IDENTIFIER '(' typed_vars ')' GENERATES '(' typed_vars ')' ';'
218 {
219 $$ = new Method($1, $3, $7);
220 }
221 ;
222
223typed_vars
224 : /* empty */
225 {
226 $$ = new Vector<TypedVar *>;
227 }
228 | typed_var
229 {
230 $$ = new Vector<TypedVar *>;
231 $$->push_back($1);
232 }
233 | typed_vars ',' typed_var
234 {
235 $$ = $1;
236 $$->push_back($3);
237 }
238 ;
239
240typed_var : type IDENTIFIER { $$ = new TypedVar($2, $1); }
241 ;
242
243
244struct_or_union_keyword
245 : STRUCT { $$ = CompoundType::STYLE_STRUCT; }
246 | UNION { $$ = CompoundType::STYLE_UNION; }
247 ;
248
249named_struct_or_union_declaration
250 : struct_or_union_keyword IDENTIFIER
251 {
252 CompoundType *container = new CompoundType($1, $2);
253 ast->enterScope(container);
254 }
255 struct_or_union_body
256 {
257 CompoundType *container = static_cast<CompoundType *>(ast->scope());
258
259 container->setFields($4);
260 ast->leaveScope();
261 ast->scope()->addType(container);
262 }
263 ;
264
265struct_or_union_declaration
266 : struct_or_union_keyword optIdentifier
267 {
268 CompoundType *container = new CompoundType($1, $2);
269 ast->enterScope(container);
270 }
271 struct_or_union_body
272 {
273 CompoundType *container = static_cast<CompoundType *>(ast->scope());
274
275 container->setFields($4);
276 ast->leaveScope();
277 ast->scope()->addType(container);
278
279 $$ = new RefType(container->name().c_str(), container);
280 }
281 ;
282
283struct_or_union_body
284 : '{' field_declarations '}' { $$ = $2; }
285 ;
286
287field_declarations
288 : /* empty */ { $$ = new Vector<CompoundField *>; }
289 | field_declarations field_declaration
290 {
291 $$ = $1;
292
293 if ($2 != NULL) {
294 $$->push_back($2);
295 }
296 }
297 ;
298
299field_declaration
300 : type IDENTIFIER ';' { $$ = new CompoundField($2, $1); }
301 | struct_or_union_declaration ';' { $$ = NULL; }
302 | enum_declaration ';' { $$ = NULL; }
303 ;
304
305opt_storage_type
306 : /* empty */ { $$ = NULL; }
Andreas Huber84f89de2016-07-28 15:39:51 -0700307 | ':' fqname { $$ = $2; }
Andreas Huberc9410c72016-07-28 12:18:40 -0700308 ;
309
310opt_comma
311 : /* empty */
312 | ','
313 ;
314
315named_enum_declaration
316 : ENUM IDENTIFIER opt_storage_type '{' enum_values opt_comma '}'
317 {
318 EnumType *enumType = new EnumType($2, $5, $3);
319 ast->scope()->addType(enumType);
320 }
321 ;
322
323enum_declaration
324 : ENUM '{' enum_values opt_comma '}'
325 {
326 EnumType *enumType = new EnumType(NULL /* name */, $3);
327 ast->scope()->addType(enumType);
328
329 $$ = new RefType(enumType->name().c_str(), enumType);
330 }
331 | ENUM IDENTIFIER opt_storage_type '{' enum_values opt_comma '}'
332 {
333 EnumType *enumType = new EnumType($2, $5, $3);
334 ast->scope()->addType(enumType);
335
336 $$ = new RefType(enumType->name().c_str(), enumType);
337 }
338 ;
339
340enum_value
341 : IDENTIFIER { $$ = new EnumValue($1); }
342 | IDENTIFIER '=' INTEGER { $$ = new EnumValue($1, $3); }
343 | IDENTIFIER '=' IDENTIFIER { $$ = new EnumValue($1, $3); }
344 ;
345
346enum_values
347 : /* empty */
348 {
349 $$ = new Vector<EnumValue *>;
350 }
351 | enum_value
352 {
353 $$ = new Vector<EnumValue *>;
354 $$->push_back($1);
355 }
356 | enum_values ',' enum_value
357 {
358 $$ = $1;
359 $$->push_back($3);
360 }
361 ;
362
363type
Andreas Huber84f89de2016-07-28 15:39:51 -0700364 : fqname { $$ = $1; }
365 | fqname '[' INTEGER ']' { $$ = new ArrayType($1, $3); }
366 | VEC '<' fqname '>' { $$ = new VectorType($3); }
Andreas Huberc9410c72016-07-28 12:18:40 -0700367 | struct_or_union_declaration { $$ = $1; }
368 | enum_declaration { $$ = $1; }
369 ;
370
371optIdentifier
372 : /* empty */ { $$ = NULL; }
373 | IDENTIFIER { $$ = $1; }
374 ;
375
376%%