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