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 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