blob: 9b40d28ad5988a79278f38272ef8a7e3186cfcf5 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001%{
2#include "aidl_language.h"
3#include <stdio.h>
4#include <stdlib.h>
5#include <string.h>
6
7int yyerror(char* errstr);
8int yylex(void);
9extern int yylineno;
10
11static int count_brackets(const char*);
12
13%}
14
15%token IMPORT
16%token PACKAGE
17%token IDENTIFIER
Maurice Chu02822d02012-10-18 14:47:13 -070018%token IDVALUE
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080019%token GENERIC
20%token ARRAY
21%token PARCELABLE
22%token INTERFACE
Joe Onorato7db766c2011-09-15 21:31:15 -070023%token FLATTENABLE
Joe Onoratofdfe2ff2011-08-30 17:24:17 -070024%token RPC
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080025%token IN
26%token OUT
27%token INOUT
28%token ONEWAY
29
30%%
31document:
32 document_items { g_callbacks->document($1.document_item); }
33 | headers document_items { g_callbacks->document($2.document_item); }
34 ;
35
36headers:
37 package { }
38 | imports { }
39 | package imports { }
40 ;
41
42package:
43 PACKAGE { }
44 ;
45
46imports:
47 IMPORT { g_callbacks->import(&($1.buffer)); }
48 | IMPORT imports { g_callbacks->import(&($1.buffer)); }
49 ;
50
51document_items:
52 { $$.document_item = NULL; }
53 | document_items declaration {
54 if ($2.document_item == NULL) {
55 // error cases only
56 $$ = $1;
57 } else {
58 document_item_type* p = $1.document_item;
59 while (p && p->next) {
60 p=p->next;
61 }
62 if (p) {
63 p->next = (document_item_type*)$2.document_item;
64 $$ = $1;
65 } else {
66 $$.document_item = (document_item_type*)$2.document_item;
67 }
68 }
69 }
70 | document_items error {
71 fprintf(stderr, "%s:%d: syntax error don't know what to do with \"%s\"\n", g_currentFilename,
72 $2.buffer.lineno, $2.buffer.data);
73 $$ = $1;
74 }
75 ;
76
77declaration:
Joe Onoratoa1c6d902011-10-09 22:31:16 -070078 parcelable_decl { $$.document_item = (document_item_type*)$1.user_data; }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080079 | interface_decl { $$.document_item = (document_item_type*)$1.interface_item; }
80 ;
81
82parcelable_decl:
Joe Onorato7db766c2011-09-15 21:31:15 -070083 PARCELABLE IDENTIFIER ';' {
Joe Onoratoa1c6d902011-10-09 22:31:16 -070084 user_data_type* b = (user_data_type*)malloc(sizeof(user_data_type));
85 b->document_item.item_type = USER_DATA_TYPE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080086 b->document_item.next = NULL;
Joe Onoratoa1c6d902011-10-09 22:31:16 -070087 b->keyword_token = $1.buffer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080088 b->name = $2.buffer;
89 b->package = g_currentPackage ? strdup(g_currentPackage) : NULL;
90 b->semicolon_token = $3.buffer;
Joe Onoratoa1c6d902011-10-09 22:31:16 -070091 b->flattening_methods = PARCELABLE_DATA;
92 $$.user_data = b;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080093 }
94 | PARCELABLE ';' {
95 fprintf(stderr, "%s:%d syntax error in parcelable declaration. Expected type name.\n",
96 g_currentFilename, $1.buffer.lineno);
Joe Onoratoa1c6d902011-10-09 22:31:16 -070097 $$.user_data = NULL;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080098 }
99 | PARCELABLE error ';' {
100 fprintf(stderr, "%s:%d syntax error in parcelable declaration. Expected type name, saw \"%s\".\n",
101 g_currentFilename, $2.buffer.lineno, $2.buffer.data);
Joe Onoratoa1c6d902011-10-09 22:31:16 -0700102 $$.user_data = NULL;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800103 }
Joe Onorato7db766c2011-09-15 21:31:15 -0700104 | FLATTENABLE IDENTIFIER ';' {
Joe Onoratoa1c6d902011-10-09 22:31:16 -0700105 user_data_type* b = (user_data_type*)malloc(sizeof(user_data_type));
106 b->document_item.item_type = USER_DATA_TYPE;
Joe Onorato7db766c2011-09-15 21:31:15 -0700107 b->document_item.next = NULL;
Joe Onoratoa1c6d902011-10-09 22:31:16 -0700108 b->keyword_token = $1.buffer;
Joe Onorato7db766c2011-09-15 21:31:15 -0700109 b->name = $2.buffer;
110 b->package = g_currentPackage ? strdup(g_currentPackage) : NULL;
111 b->semicolon_token = $3.buffer;
Joe Onoratoa1c6d902011-10-09 22:31:16 -0700112 b->flattening_methods = PARCELABLE_DATA | RPC_DATA;
113 $$.user_data = b;
Joe Onorato7db766c2011-09-15 21:31:15 -0700114 }
115 | FLATTENABLE ';' {
116 fprintf(stderr, "%s:%d syntax error in flattenable declaration. Expected type name.\n",
117 g_currentFilename, $1.buffer.lineno);
Joe Onoratoa1c6d902011-10-09 22:31:16 -0700118 $$.user_data = NULL;
Joe Onorato7db766c2011-09-15 21:31:15 -0700119 }
120 | FLATTENABLE error ';' {
121 fprintf(stderr, "%s:%d syntax error in flattenable declaration. Expected type name, saw \"%s\".\n",
122 g_currentFilename, $2.buffer.lineno, $2.buffer.data);
Joe Onoratoa1c6d902011-10-09 22:31:16 -0700123 $$.user_data = NULL;
Joe Onorato7db766c2011-09-15 21:31:15 -0700124 }
125
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800126 ;
127
128interface_header:
129 INTERFACE {
130 interface_type* c = (interface_type*)malloc(sizeof(interface_type));
Joe Onoratofdfe2ff2011-08-30 17:24:17 -0700131 c->document_item.item_type = INTERFACE_TYPE_BINDER;
132 c->document_item.next = NULL;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800133 c->interface_token = $1.buffer;
134 c->oneway = false;
135 memset(&c->oneway_token, 0, sizeof(buffer_type));
136 c->comments_token = &c->interface_token;
137 $$.interface_obj = c;
138 }
139 | ONEWAY INTERFACE {
140 interface_type* c = (interface_type*)malloc(sizeof(interface_type));
Joe Onoratofdfe2ff2011-08-30 17:24:17 -0700141 c->document_item.item_type = INTERFACE_TYPE_BINDER;
142 c->document_item.next = NULL;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800143 c->interface_token = $2.buffer;
144 c->oneway = true;
145 c->oneway_token = $1.buffer;
146 c->comments_token = &c->oneway_token;
147 $$.interface_obj = c;
148 }
Joe Onoratofdfe2ff2011-08-30 17:24:17 -0700149 | RPC {
150 interface_type* c = (interface_type*)malloc(sizeof(interface_type));
151 c->document_item.item_type = INTERFACE_TYPE_RPC;
152 c->document_item.next = NULL;
153 c->interface_token = $1.buffer;
154 c->oneway = false;
155 memset(&c->oneway_token, 0, sizeof(buffer_type));
156 c->comments_token = &c->interface_token;
157 $$.interface_obj = c;
158 }
159 ;
160
161interface_keywords:
162 INTERFACE
163 | RPC
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800164 ;
165
166interface_decl:
167 interface_header IDENTIFIER '{' interface_items '}' {
168 interface_type* c = $1.interface_obj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800169 c->name = $2.buffer;
170 c->package = g_currentPackage ? strdup(g_currentPackage) : NULL;
171 c->open_brace_token = $3.buffer;
172 c->interface_items = $4.interface_item;
173 c->close_brace_token = $5.buffer;
174 $$.interface_obj = c;
175 }
Joe Onoratofdfe2ff2011-08-30 17:24:17 -0700176 | interface_keywords error '{' interface_items '}' {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800177 fprintf(stderr, "%s:%d: syntax error in interface declaration. Expected type name, saw \"%s\"\n",
178 g_currentFilename, $2.buffer.lineno, $2.buffer.data);
179 $$.document_item = NULL;
180 }
Joe Onoratofdfe2ff2011-08-30 17:24:17 -0700181 | interface_keywords error '}' {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800182 fprintf(stderr, "%s:%d: syntax error in interface declaration. Expected type name, saw \"%s\"\n",
183 g_currentFilename, $2.buffer.lineno, $2.buffer.data);
184 $$.document_item = NULL;
185 }
186
187 ;
188
189interface_items:
190 { $$.interface_item = NULL; }
191 | interface_items method_decl {
192 interface_item_type* p=$1.interface_item;
193 while (p && p->next) {
194 p=p->next;
195 }
196 if (p) {
197 p->next = (interface_item_type*)$2.method;
198 $$ = $1;
199 } else {
200 $$.interface_item = (interface_item_type*)$2.method;
201 }
202 }
203 | interface_items error ';' {
204 fprintf(stderr, "%s:%d: syntax error before ';' (expected method declaration)\n",
205 g_currentFilename, $3.buffer.lineno);
206 $$ = $1;
207 }
208 ;
209
210method_decl:
211 type IDENTIFIER '(' arg_list ')' ';' {
212 method_type *method = (method_type*)malloc(sizeof(method_type));
213 method->interface_item.item_type = METHOD_TYPE;
214 method->interface_item.next = NULL;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800215 method->oneway = false;
Maurice Chu02822d02012-10-18 14:47:13 -0700216 method->type = $1.type;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800217 memset(&method->oneway_token, 0, sizeof(buffer_type));
218 method->name = $2.buffer;
219 method->open_paren_token = $3.buffer;
220 method->args = $4.arg;
221 method->close_paren_token = $5.buffer;
Maurice Chu02822d02012-10-18 14:47:13 -0700222 method->hasId = false;
223 memset(&method->equals_token, 0, sizeof(buffer_type));
224 memset(&method->id, 0, sizeof(buffer_type));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800225 method->semicolon_token = $6.buffer;
226 method->comments_token = &method->type.type;
227 $$.method = method;
228 }
229 | ONEWAY type IDENTIFIER '(' arg_list ')' ';' {
230 method_type *method = (method_type*)malloc(sizeof(method_type));
231 method->interface_item.item_type = METHOD_TYPE;
232 method->interface_item.next = NULL;
233 method->oneway = true;
234 method->oneway_token = $1.buffer;
235 method->type = $2.type;
236 method->name = $3.buffer;
237 method->open_paren_token = $4.buffer;
238 method->args = $5.arg;
239 method->close_paren_token = $6.buffer;
Maurice Chu02822d02012-10-18 14:47:13 -0700240 method->hasId = false;
241 memset(&method->equals_token, 0, sizeof(buffer_type));
242 memset(&method->id, 0, sizeof(buffer_type));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800243 method->semicolon_token = $7.buffer;
244 method->comments_token = &method->oneway_token;
245 $$.method = method;
246 }
Maurice Chu02822d02012-10-18 14:47:13 -0700247 | type IDENTIFIER '(' arg_list ')' '=' IDVALUE ';' {
248 method_type *method = (method_type*)malloc(sizeof(method_type));
249 method->interface_item.item_type = METHOD_TYPE;
250 method->interface_item.next = NULL;
251 method->oneway = false;
252 memset(&method->oneway_token, 0, sizeof(buffer_type));
253 method->type = $1.type;
254 method->name = $2.buffer;
255 method->open_paren_token = $3.buffer;
256 method->args = $4.arg;
257 method->close_paren_token = $5.buffer;
258 method->hasId = true;
259 method->equals_token = $6.buffer;
260 method->id = $7.buffer;
261 method->semicolon_token = $8.buffer;
262 method->comments_token = &method->type.type;
263 $$.method = method;
264 }
265 | ONEWAY type IDENTIFIER '(' arg_list ')' '=' IDVALUE ';' {
266 method_type *method = (method_type*)malloc(sizeof(method_type));
267 method->interface_item.item_type = METHOD_TYPE;
268 method->interface_item.next = NULL;
269 method->oneway = true;
270 method->oneway_token = $1.buffer;
271 method->type = $2.type;
272 method->name = $3.buffer;
273 method->open_paren_token = $4.buffer;
274 method->args = $5.arg;
275 method->close_paren_token = $6.buffer;
276 method->hasId = true;
277 method->equals_token = $7.buffer;
278 method->id = $8.buffer;
279 method->semicolon_token = $9.buffer;
280 method->comments_token = &method->oneway_token;
281 $$.method = method;
282 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800283 ;
284
285arg_list:
286 { $$.arg = NULL; }
287 | arg { $$ = $1; }
288 | arg_list ',' arg {
289 if ($$.arg != NULL) {
290 // only NULL on error
291 $$ = $1;
292 arg_type *p = $1.arg;
293 while (p && p->next) {
294 p=p->next;
295 }
296 $3.arg->comma_token = $2.buffer;
297 p->next = $3.arg;
298 }
299 }
300 | error {
301 fprintf(stderr, "%s:%d: syntax error in parameter list\n", g_currentFilename, $1.buffer.lineno);
302 $$.arg = NULL;
303 }
304 ;
305
306arg:
307 direction type IDENTIFIER {
308 arg_type* arg = (arg_type*)malloc(sizeof(arg_type));
309 memset(&arg->comma_token, 0, sizeof(buffer_type));
310 arg->direction = $1.buffer;
311 arg->type = $2.type;
312 arg->name = $3.buffer;
313 arg->next = NULL;
314 $$.arg = arg;
315 }
316 ;
317
318type:
319 IDENTIFIER {
320 $$.type.type = $1.buffer;
321 init_buffer_type(&$$.type.array_token, yylineno);
322 $$.type.dimension = 0;
323 }
324 | IDENTIFIER ARRAY {
325 $$.type.type = $1.buffer;
326 $$.type.array_token = $2.buffer;
327 $$.type.dimension = count_brackets($2.buffer.data);
328 }
329 | GENERIC {
330 $$.type.type = $1.buffer;
331 init_buffer_type(&$$.type.array_token, yylineno);
332 $$.type.dimension = 0;
333 }
334 ;
335
336direction:
337 { init_buffer_type(&$$.buffer, yylineno); }
338 | IN { $$.buffer = $1.buffer; }
339 | OUT { $$.buffer = $1.buffer; }
340 | INOUT { $$.buffer = $1.buffer; }
341 ;
342
343%%
344
345#include <ctype.h>
346#include <stdio.h>
347
348int g_error = 0;
349
350int yyerror(char* errstr)
351{
352 fprintf(stderr, "%s:%d: %s\n", g_currentFilename, yylineno, errstr);
353 g_error = 1;
354 return 1;
355}
356
357void init_buffer_type(buffer_type* buf, int lineno)
358{
359 buf->lineno = lineno;
360 buf->token = 0;
361 buf->data = NULL;
362 buf->extra = NULL;
363}
364
365static int count_brackets(const char* s)
366{
367 int n=0;
368 while (*s) {
369 if (*s == '[') n++;
370 s++;
371 }
372 return n;
373}