Home | History | Annotate | Download | only in aidl
      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