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