Home | History | Annotate | Download | only in aidl
      1 %{
      2 #include "aidl_language.h"
      3 #include "aidl_language_y.h"
      4 #include <stdio.h>
      5 #include <stdlib.h>
      6 #include <string.h>
      7 
      8 int yylex(yy::parser::semantic_type *, yy::parser::location_type *, void *);
      9 
     10 #define lex_scanner ps->Scanner()
     11 
     12 %}
     13 
     14 %parse-param { Parser* ps }
     15 %lex-param { void *lex_scanner }
     16 
     17 %pure-parser
     18 %skeleton "glr.cc"
     19 
     20 %union {
     21     AidlToken* token;
     22     int integer;
     23     std::string *str;
     24     AidlType::Annotation annotation;
     25     AidlType::Annotation annotation_list;
     26     AidlType* type;
     27     AidlType* unannotated_type;
     28     AidlArgument* arg;
     29     AidlArgument::Direction direction;
     30     std::vector<std::unique_ptr<AidlArgument>>* arg_list;
     31     AidlMethod* method;
     32     AidlMember* constant;
     33     std::vector<std::unique_ptr<AidlMember>>* members;
     34     AidlQualifiedName* qname;
     35     AidlInterface* interface_obj;
     36     AidlParcelable* parcelable;
     37     AidlDocument* parcelable_list;
     38 }
     39 
     40 %token<token> IDENTIFIER INTERFACE ONEWAY C_STR HEXVALUE
     41 %token<integer> INTVALUE
     42 
     43 %token '(' ')' ',' '=' '[' ']' '<' '>' '.' '{' '}' ';'
     44 %token IN OUT INOUT PACKAGE IMPORT PARCELABLE CPP_HEADER CONST INT STRING
     45 %token ANNOTATION_NULLABLE ANNOTATION_UTF8 ANNOTATION_UTF8_CPP
     46 
     47 %type<parcelable_list> parcelable_decls
     48 %type<parcelable> parcelable_decl
     49 %type<members> members
     50 %type<interface_obj> interface_decl
     51 %type<method> method_decl
     52 %type<constant> constant_decl
     53 %type<annotation> annotation
     54 %type<annotation_list>annotation_list
     55 %type<type> type
     56 %type<unannotated_type> unannotated_type
     57 %type<arg_list> arg_list
     58 %type<arg> arg
     59 %type<direction> direction
     60 %type<str> generic_list
     61 %type<qname> qualified_name
     62 
     63 %type<token> identifier error
     64 %%
     65 document
     66  : package imports parcelable_decls
     67   { ps->SetDocument($3); }
     68  | package imports interface_decl
     69   { ps->SetDocument(new AidlDocument($3)); };
     70 
     71 /* A couple of tokens that are keywords elsewhere are identifiers when
     72  * occurring in the identifier position. Therefore identifier is a
     73  * non-terminal, which is either an IDENTIFIER token, or one of the
     74  * aforementioned keyword tokens.
     75  */
     76 identifier
     77  : IDENTIFIER
     78   { $$ = $1; }
     79  | CPP_HEADER
     80   { $$ = new AidlToken("cpp_header", ""); }
     81  | INT
     82   { $$ = new AidlToken("int", ""); }
     83  | STRING
     84   { $$ = new AidlToken("String", ""); }
     85  ;
     86 
     87 package
     88  : {}
     89  | PACKAGE qualified_name ';'
     90   { ps->SetPackage($2); };
     91 
     92 imports
     93  : {}
     94  | import imports {};
     95 
     96 import
     97  : IMPORT qualified_name ';'
     98   { ps->AddImport($2, @1.begin.line); };
     99 
    100 qualified_name
    101  : identifier {
    102     $$ = new AidlQualifiedName($1->GetText(), $1->GetComments());
    103     delete $1;
    104   }
    105  | qualified_name '.' identifier
    106   { $$ = $1;
    107     $$->AddTerm($3->GetText());
    108   };
    109 
    110 parcelable_decls
    111  :
    112   { $$ = new AidlDocument(); }
    113  | parcelable_decls parcelable_decl {
    114    $$ = $1;
    115    $$->AddParcelable($2);
    116   }
    117  | parcelable_decls error {
    118     fprintf(stderr, "%s:%d: syntax error don't know what to do with \"%s\"\n",
    119             ps->FileName().c_str(),
    120             @2.begin.line, $2->GetText().c_str());
    121     $$ = $1;
    122   };
    123 
    124 parcelable_decl
    125  : PARCELABLE qualified_name ';' {
    126     $$ = new AidlParcelable($2, @2.begin.line, ps->Package());
    127   }
    128  | PARCELABLE qualified_name CPP_HEADER C_STR ';' {
    129     $$ = new AidlParcelable($2, @2.begin.line, ps->Package(), $4->GetText());
    130   }
    131  | PARCELABLE ';' {
    132     fprintf(stderr, "%s:%d syntax error in parcelable declaration. Expected type name.\n",
    133             ps->FileName().c_str(), @1.begin.line);
    134     $$ = NULL;
    135   }
    136  | PARCELABLE error ';' {
    137     fprintf(stderr, "%s:%d syntax error in parcelable declaration. Expected type name, saw \"%s\".\n",
    138             ps->FileName().c_str(), @2.begin.line, $2->GetText().c_str());
    139     $$ = NULL;
    140   };
    141 
    142 interface_decl
    143  : annotation_list INTERFACE identifier '{' members '}' {
    144     $$ = new AidlInterface($3->GetText(), @2.begin.line, $2->GetComments(),
    145                            false, $5, ps->Package());
    146     $$->Annotate($1);
    147     delete $2;
    148     delete $3;
    149   }
    150  | annotation_list ONEWAY INTERFACE identifier '{' members '}' {
    151     $$ = new AidlInterface($4->GetText(), @4.begin.line, $2->GetComments(),
    152                            true, $6, ps->Package());
    153     $$->Annotate($1);
    154     delete $2;
    155     delete $3;
    156     delete $4;
    157   }
    158  | annotation_list INTERFACE error '{' members '}' {
    159     fprintf(stderr, "%s:%d: syntax error in interface declaration.  Expected "
    160                     "type name, saw \"%s\"\n",
    161             ps->FileName().c_str(), @3.begin.line, $3->GetText().c_str());
    162     $$ = NULL;
    163     delete $2;
    164     delete $3;
    165     delete $5;
    166   }
    167  | annotation_list INTERFACE error '}' {
    168     fprintf(stderr, "%s:%d: syntax error in interface declaration.  Expected "
    169                     "type name, saw \"%s\"\n",
    170             ps->FileName().c_str(), @3.begin.line, $3->GetText().c_str());
    171     $$ = NULL;
    172     delete $2;
    173     delete $3;
    174   };
    175 
    176 members
    177  :
    178   { $$ = new std::vector<std::unique_ptr<AidlMember>>(); }
    179  | members method_decl
    180   { $1->push_back(std::unique_ptr<AidlMember>($2)); }
    181  | members constant_decl
    182   { $1->push_back(std::unique_ptr<AidlMember>($2)); }
    183  | members error ';' {
    184     fprintf(stderr, "%s:%d: syntax error before ';' "
    185                     "(expected method or constant declaration)\n",
    186             ps->FileName().c_str(), @3.begin.line);
    187     $$ = $1;
    188   };
    189 
    190 constant_decl
    191  : CONST INT identifier '=' INTVALUE ';' {
    192     $$ = new AidlIntConstant($3->GetText(), $5);
    193     delete $3;
    194    }
    195  | CONST INT identifier '=' HEXVALUE ';' {
    196     $$ = new AidlIntConstant($3->GetText(), $5->GetText(), @5.begin.line);
    197     delete $3;
    198    }
    199  | CONST STRING identifier '=' C_STR ';' {
    200     $$ = new AidlStringConstant($3->GetText(), $5->GetText(), @5.begin.line);
    201     delete $3;
    202     delete $5;
    203    }
    204  ;
    205 
    206 method_decl
    207  : type identifier '(' arg_list ')' ';' {
    208     $$ = new AidlMethod(false, $1, $2->GetText(), $4, @2.begin.line,
    209                         $1->GetComments());
    210     delete $2;
    211   }
    212  | ONEWAY type identifier '(' arg_list ')' ';' {
    213     $$ = new AidlMethod(true, $2, $3->GetText(), $5, @3.begin.line,
    214                         $1->GetComments());
    215     delete $1;
    216     delete $3;
    217   }
    218  | type identifier '(' arg_list ')' '=' INTVALUE ';' {
    219     $$ = new AidlMethod(false, $1, $2->GetText(), $4, @2.begin.line,
    220                         $1->GetComments(), $7);
    221     delete $2;
    222   }
    223  | ONEWAY type identifier '(' arg_list ')' '=' INTVALUE ';' {
    224     $$ = new AidlMethod(true, $2, $3->GetText(), $5, @3.begin.line,
    225                         $1->GetComments(), $8);
    226     delete $1;
    227     delete $3;
    228   };
    229 
    230 arg_list
    231  :
    232   { $$ = new std::vector<std::unique_ptr<AidlArgument>>(); }
    233  | arg {
    234     $$ = new std::vector<std::unique_ptr<AidlArgument>>();
    235     $$->push_back(std::unique_ptr<AidlArgument>($1));
    236   }
    237  | arg_list ',' arg {
    238     $$ = $1;
    239     $$->push_back(std::unique_ptr<AidlArgument>($3));
    240   }
    241  | error {
    242     fprintf(stderr, "%s:%d: syntax error in parameter list\n",
    243             ps->FileName().c_str(), @1.begin.line);
    244     $$ = new std::vector<std::unique_ptr<AidlArgument>>();
    245   };
    246 
    247 arg
    248  : direction type identifier {
    249     $$ = new AidlArgument($1, $2, $3->GetText(), @3.begin.line);
    250     delete $3;
    251   };
    252  | type identifier {
    253     $$ = new AidlArgument($1, $2->GetText(), @2.begin.line);
    254     delete $2;
    255   };
    256 
    257 unannotated_type
    258  : qualified_name {
    259     $$ = new AidlType($1->GetDotName(), @1.begin.line, $1->GetComments(), false);
    260     delete $1;
    261   }
    262  | qualified_name '[' ']' {
    263     $$ = new AidlType($1->GetDotName(), @1.begin.line, $1->GetComments(),
    264                       true);
    265     delete $1;
    266   }
    267  | qualified_name '<' generic_list '>' {
    268     $$ = new AidlType($1->GetDotName() + "<" + *$3 + ">", @1.begin.line,
    269                       $1->GetComments(), false);
    270     delete $1;
    271     delete $3;
    272   };
    273 
    274 type
    275  : annotation_list unannotated_type {
    276     $$ = $2;
    277     $2->Annotate($1);
    278   };
    279 
    280 generic_list
    281  : qualified_name {
    282     $$ = new std::string($1->GetDotName());
    283     delete $1;
    284   }
    285  | generic_list ',' qualified_name {
    286     $$ = new std::string(*$1 + "," + $3->GetDotName());
    287     delete $1;
    288     delete $3;
    289   };
    290 
    291 annotation_list
    292  :
    293   { $$ = AidlType::AnnotationNone; }
    294  | annotation_list annotation
    295   { $$ = static_cast<AidlType::Annotation>($1 | $2); };
    296 
    297 annotation
    298  : ANNOTATION_NULLABLE
    299   { $$ = AidlType::AnnotationNullable; }
    300  | ANNOTATION_UTF8
    301   { $$ = AidlType::AnnotationUtf8; }
    302  | ANNOTATION_UTF8_CPP
    303   { $$ = AidlType::AnnotationUtf8InCpp; };
    304 
    305 direction
    306  : IN
    307   { $$ = AidlArgument::IN_DIR; }
    308  | OUT
    309   { $$ = AidlArgument::OUT_DIR; }
    310  | INOUT
    311   { $$ = AidlArgument::INOUT_DIR; };
    312 
    313 %%
    314 
    315 #include <ctype.h>
    316 #include <stdio.h>
    317 
    318 void yy::parser::error(const yy::parser::location_type& l,
    319                        const std::string& errstr) {
    320   ps->ReportError(errstr, l.begin.line);
    321 }
    322