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 IDVALUE 19 %token GENERIC 20 %token ARRAY 21 %token PARCELABLE 22 %token INTERFACE 23 %token FLATTENABLE 24 %token RPC 25 %token IN 26 %token OUT 27 %token INOUT 28 %token ONEWAY 29 30 %% 31 document: 32 document_items { g_callbacks->document($1.document_item); } 33 | headers document_items { g_callbacks->document($2.document_item); } 34 ; 35 36 headers: 37 package { } 38 | imports { } 39 | package imports { } 40 ; 41 42 package: 43 PACKAGE { } 44 ; 45 46 imports: 47 IMPORT { g_callbacks->import(&($1.buffer)); } 48 | IMPORT imports { g_callbacks->import(&($1.buffer)); } 49 ; 50 51 document_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 77 declaration: 78 parcelable_decl { $$.document_item = (document_item_type*)$1.user_data; } 79 | interface_decl { $$.document_item = (document_item_type*)$1.interface_item; } 80 ; 81 82 parcelable_decl: 83 PARCELABLE IDENTIFIER ';' { 84 user_data_type* b = (user_data_type*)malloc(sizeof(user_data_type)); 85 b->document_item.item_type = USER_DATA_TYPE; 86 b->document_item.next = NULL; 87 b->keyword_token = $1.buffer; 88 b->name = $2.buffer; 89 b->package = g_currentPackage ? strdup(g_currentPackage) : NULL; 90 b->semicolon_token = $3.buffer; 91 b->flattening_methods = PARCELABLE_DATA; 92 $$.user_data = b; 93 } 94 | PARCELABLE ';' { 95 fprintf(stderr, "%s:%d syntax error in parcelable declaration. Expected type name.\n", 96 g_currentFilename, $1.buffer.lineno); 97 $$.user_data = NULL; 98 } 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); 102 $$.user_data = NULL; 103 } 104 | FLATTENABLE IDENTIFIER ';' { 105 user_data_type* b = (user_data_type*)malloc(sizeof(user_data_type)); 106 b->document_item.item_type = USER_DATA_TYPE; 107 b->document_item.next = NULL; 108 b->keyword_token = $1.buffer; 109 b->name = $2.buffer; 110 b->package = g_currentPackage ? strdup(g_currentPackage) : NULL; 111 b->semicolon_token = $3.buffer; 112 b->flattening_methods = PARCELABLE_DATA | RPC_DATA; 113 $$.user_data = b; 114 } 115 | FLATTENABLE ';' { 116 fprintf(stderr, "%s:%d syntax error in flattenable declaration. Expected type name.\n", 117 g_currentFilename, $1.buffer.lineno); 118 $$.user_data = NULL; 119 } 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); 123 $$.user_data = NULL; 124 } 125 126 ; 127 128 interface_header: 129 INTERFACE { 130 interface_type* c = (interface_type*)malloc(sizeof(interface_type)); 131 c->document_item.item_type = INTERFACE_TYPE_BINDER; 132 c->document_item.next = NULL; 133 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)); 141 c->document_item.item_type = INTERFACE_TYPE_BINDER; 142 c->document_item.next = NULL; 143 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 } 149 | 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 161 interface_keywords: 162 INTERFACE 163 | RPC 164 ; 165 166 interface_decl: 167 interface_header IDENTIFIER '{' interface_items '}' { 168 interface_type* c = $1.interface_obj; 169 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 } 176 | interface_keywords error '{' interface_items '}' { 177 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 } 181 | interface_keywords error '}' { 182 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 189 interface_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 210 method_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; 215 method->oneway = false; 216 method->type = $1.type; 217 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; 222 method->hasId = false; 223 memset(&method->equals_token, 0, sizeof(buffer_type)); 224 memset(&method->id, 0, sizeof(buffer_type)); 225 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; 240 method->hasId = false; 241 memset(&method->equals_token, 0, sizeof(buffer_type)); 242 memset(&method->id, 0, sizeof(buffer_type)); 243 method->semicolon_token = $7.buffer; 244 method->comments_token = &method->oneway_token; 245 $$.method = method; 246 } 247 | 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 } 283 ; 284 285 arg_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 306 arg: 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 318 type: 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 336 direction: 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 348 int g_error = 0; 349 350 int yyerror(char* errstr) 351 { 352 fprintf(stderr, "%s:%d: %s\n", g_currentFilename, yylineno, errstr); 353 g_error = 1; 354 return 1; 355 } 356 357 void 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 365 static 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 } 374