blob: 9c5d10e6892a55a02c2cd19bb58ce85eaacc0429 [file] [log] [blame]
Adam Lesinskiffa16862014-01-23 18:17:42 -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
18%token IDVALUE
19%token GENERIC
20%token ARRAY
21%token PARCELABLE
22%token INTERFACE
Adam Lesinskiffa16862014-01-23 18:17:42 -080023%token IN
24%token OUT
25%token INOUT
26%token ONEWAY
27
28%%
29document:
30 document_items { g_callbacks->document($1.document_item); }
31 | headers document_items { g_callbacks->document($2.document_item); }
32 ;
33
34headers:
35 package { }
36 | imports { }
37 | package imports { }
38 ;
39
40package:
41 PACKAGE { }
42 ;
43
44imports:
45 IMPORT { g_callbacks->import(&($1.buffer)); }
46 | IMPORT imports { g_callbacks->import(&($1.buffer)); }
47 ;
48
49document_items:
50 { $$.document_item = NULL; }
51 | document_items declaration {
52 if ($2.document_item == NULL) {
53 // error cases only
54 $$ = $1;
55 } else {
56 document_item_type* p = $1.document_item;
57 while (p && p->next) {
58 p=p->next;
59 }
60 if (p) {
61 p->next = (document_item_type*)$2.document_item;
62 $$ = $1;
63 } else {
64 $$.document_item = (document_item_type*)$2.document_item;
65 }
66 }
67 }
68 | document_items error {
69 fprintf(stderr, "%s:%d: syntax error don't know what to do with \"%s\"\n", g_currentFilename,
70 $2.buffer.lineno, $2.buffer.data);
71 $$ = $1;
72 }
73 ;
74
75declaration:
76 parcelable_decl { $$.document_item = (document_item_type*)$1.user_data; }
77 | interface_decl { $$.document_item = (document_item_type*)$1.interface_item; }
78 ;
79
80parcelable_decl:
81 PARCELABLE IDENTIFIER ';' {
82 user_data_type* b = (user_data_type*)malloc(sizeof(user_data_type));
83 b->document_item.item_type = USER_DATA_TYPE;
84 b->document_item.next = NULL;
85 b->keyword_token = $1.buffer;
86 b->name = $2.buffer;
87 b->package = g_currentPackage ? strdup(g_currentPackage) : NULL;
88 b->semicolon_token = $3.buffer;
Casey Dahlin88868fc2015-09-01 13:21:26 -070089 b->parcelable = true;
Adam Lesinskiffa16862014-01-23 18:17:42 -080090 $$.user_data = b;
91 }
92 | PARCELABLE ';' {
93 fprintf(stderr, "%s:%d syntax error in parcelable declaration. Expected type name.\n",
94 g_currentFilename, $1.buffer.lineno);
95 $$.user_data = NULL;
96 }
97 | PARCELABLE error ';' {
98 fprintf(stderr, "%s:%d syntax error in parcelable declaration. Expected type name, saw \"%s\".\n",
99 g_currentFilename, $2.buffer.lineno, $2.buffer.data);
100 $$.user_data = NULL;
101 }
Adam Lesinskiffa16862014-01-23 18:17:42 -0800102 ;
103
104interface_header:
105 INTERFACE {
106 interface_type* c = (interface_type*)malloc(sizeof(interface_type));
107 c->document_item.item_type = INTERFACE_TYPE_BINDER;
108 c->document_item.next = NULL;
109 c->interface_token = $1.buffer;
110 c->oneway = false;
111 memset(&c->oneway_token, 0, sizeof(buffer_type));
112 c->comments_token = &c->interface_token;
113 $$.interface_obj = c;
114 }
115 | ONEWAY INTERFACE {
116 interface_type* c = (interface_type*)malloc(sizeof(interface_type));
117 c->document_item.item_type = INTERFACE_TYPE_BINDER;
118 c->document_item.next = NULL;
119 c->interface_token = $2.buffer;
120 c->oneway = true;
121 c->oneway_token = $1.buffer;
122 c->comments_token = &c->oneway_token;
123 $$.interface_obj = c;
124 }
Adam Lesinskiffa16862014-01-23 18:17:42 -0800125 ;
126
127interface_decl:
128 interface_header IDENTIFIER '{' interface_items '}' {
129 interface_type* c = $1.interface_obj;
130 c->name = $2.buffer;
131 c->package = g_currentPackage ? strdup(g_currentPackage) : NULL;
132 c->open_brace_token = $3.buffer;
133 c->interface_items = $4.interface_item;
134 c->close_brace_token = $5.buffer;
135 $$.interface_obj = c;
136 }
Casey Dahlin88868fc2015-09-01 13:21:26 -0700137 | INTERFACE error '{' interface_items '}' {
Adam Lesinskiffa16862014-01-23 18:17:42 -0800138 fprintf(stderr, "%s:%d: syntax error in interface declaration. Expected type name, saw \"%s\"\n",
139 g_currentFilename, $2.buffer.lineno, $2.buffer.data);
140 $$.document_item = NULL;
141 }
Casey Dahlin88868fc2015-09-01 13:21:26 -0700142 | INTERFACE error '}' {
Adam Lesinskiffa16862014-01-23 18:17:42 -0800143 fprintf(stderr, "%s:%d: syntax error in interface declaration. Expected type name, saw \"%s\"\n",
144 g_currentFilename, $2.buffer.lineno, $2.buffer.data);
145 $$.document_item = NULL;
146 }
147
148 ;
149
150interface_items:
151 { $$.interface_item = NULL; }
152 | interface_items method_decl {
153 interface_item_type* p=$1.interface_item;
154 while (p && p->next) {
155 p=p->next;
156 }
157 if (p) {
158 p->next = (interface_item_type*)$2.method;
159 $$ = $1;
160 } else {
161 $$.interface_item = (interface_item_type*)$2.method;
162 }
163 }
164 | interface_items error ';' {
165 fprintf(stderr, "%s:%d: syntax error before ';' (expected method declaration)\n",
166 g_currentFilename, $3.buffer.lineno);
167 $$ = $1;
168 }
169 ;
170
171method_decl:
172 type IDENTIFIER '(' arg_list ')' ';' {
173 method_type *method = (method_type*)malloc(sizeof(method_type));
174 method->interface_item.item_type = METHOD_TYPE;
175 method->interface_item.next = NULL;
176 method->oneway = false;
177 method->type = $1.type;
178 memset(&method->oneway_token, 0, sizeof(buffer_type));
179 method->name = $2.buffer;
180 method->open_paren_token = $3.buffer;
181 method->args = $4.arg;
182 method->close_paren_token = $5.buffer;
183 method->hasId = false;
184 memset(&method->equals_token, 0, sizeof(buffer_type));
185 memset(&method->id, 0, sizeof(buffer_type));
186 method->semicolon_token = $6.buffer;
187 method->comments_token = &method->type.type;
188 $$.method = method;
189 }
190 | ONEWAY type IDENTIFIER '(' arg_list ')' ';' {
191 method_type *method = (method_type*)malloc(sizeof(method_type));
192 method->interface_item.item_type = METHOD_TYPE;
193 method->interface_item.next = NULL;
194 method->oneway = true;
195 method->oneway_token = $1.buffer;
196 method->type = $2.type;
197 method->name = $3.buffer;
198 method->open_paren_token = $4.buffer;
199 method->args = $5.arg;
200 method->close_paren_token = $6.buffer;
201 method->hasId = false;
202 memset(&method->equals_token, 0, sizeof(buffer_type));
203 memset(&method->id, 0, sizeof(buffer_type));
204 method->semicolon_token = $7.buffer;
205 method->comments_token = &method->oneway_token;
206 $$.method = method;
207 }
208 | type IDENTIFIER '(' arg_list ')' '=' IDVALUE ';' {
209 method_type *method = (method_type*)malloc(sizeof(method_type));
210 method->interface_item.item_type = METHOD_TYPE;
211 method->interface_item.next = NULL;
212 method->oneway = false;
213 memset(&method->oneway_token, 0, sizeof(buffer_type));
214 method->type = $1.type;
215 method->name = $2.buffer;
216 method->open_paren_token = $3.buffer;
217 method->args = $4.arg;
218 method->close_paren_token = $5.buffer;
219 method->hasId = true;
220 method->equals_token = $6.buffer;
221 method->id = $7.buffer;
222 method->semicolon_token = $8.buffer;
223 method->comments_token = &method->type.type;
224 $$.method = method;
225 }
226 | ONEWAY type IDENTIFIER '(' arg_list ')' '=' IDVALUE ';' {
227 method_type *method = (method_type*)malloc(sizeof(method_type));
228 method->interface_item.item_type = METHOD_TYPE;
229 method->interface_item.next = NULL;
230 method->oneway = true;
231 method->oneway_token = $1.buffer;
232 method->type = $2.type;
233 method->name = $3.buffer;
234 method->open_paren_token = $4.buffer;
235 method->args = $5.arg;
236 method->close_paren_token = $6.buffer;
237 method->hasId = true;
238 method->equals_token = $7.buffer;
239 method->id = $8.buffer;
240 method->semicolon_token = $9.buffer;
241 method->comments_token = &method->oneway_token;
242 $$.method = method;
243 }
244 ;
245
246arg_list:
247 { $$.arg = NULL; }
248 | arg { $$ = $1; }
249 | arg_list ',' arg {
250 if ($$.arg != NULL) {
251 // only NULL on error
252 $$ = $1;
253 arg_type *p = $1.arg;
254 while (p && p->next) {
255 p=p->next;
256 }
257 $3.arg->comma_token = $2.buffer;
258 p->next = $3.arg;
259 }
260 }
261 | error {
262 fprintf(stderr, "%s:%d: syntax error in parameter list\n", g_currentFilename, $1.buffer.lineno);
263 $$.arg = NULL;
264 }
265 ;
266
267arg:
268 direction type IDENTIFIER {
269 arg_type* arg = (arg_type*)malloc(sizeof(arg_type));
270 memset(&arg->comma_token, 0, sizeof(buffer_type));
271 arg->direction = $1.buffer;
272 arg->type = $2.type;
273 arg->name = $3.buffer;
274 arg->next = NULL;
275 $$.arg = arg;
276 }
277 ;
278
279type:
280 IDENTIFIER {
281 $$.type.type = $1.buffer;
282 init_buffer_type(&$$.type.array_token, yylineno);
283 $$.type.dimension = 0;
284 }
285 | IDENTIFIER ARRAY {
286 $$.type.type = $1.buffer;
287 $$.type.array_token = $2.buffer;
288 $$.type.dimension = count_brackets($2.buffer.data);
289 }
290 | GENERIC {
291 $$.type.type = $1.buffer;
292 init_buffer_type(&$$.type.array_token, yylineno);
293 $$.type.dimension = 0;
294 }
295 ;
296
297direction:
298 { init_buffer_type(&$$.buffer, yylineno); }
299 | IN { $$.buffer = $1.buffer; }
300 | OUT { $$.buffer = $1.buffer; }
301 | INOUT { $$.buffer = $1.buffer; }
302 ;
303
304%%
305
306#include <ctype.h>
307#include <stdio.h>
308
309int g_error = 0;
310
311int yyerror(char* errstr)
312{
313 fprintf(stderr, "%s:%d: %s\n", g_currentFilename, yylineno, errstr);
314 g_error = 1;
315 return 1;
316}
317
318void init_buffer_type(buffer_type* buf, int lineno)
319{
320 buf->lineno = lineno;
321 buf->token = 0;
322 buf->data = NULL;
323 buf->extra = NULL;
324}
325
326static int count_brackets(const char* s)
327{
328 int n=0;
329 while (*s) {
330 if (*s == '[') n++;
331 s++;
332 }
333 return n;
334}