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     delete $3;
    109   };
    110 
    111 parcelable_decls
    112  :
    113   { $$ = new AidlDocument(); }
    114  | parcelable_decls parcelable_decl {
    115    $$ = $1;
    116    $$->AddParcelable($2);
    117   }
    118  | parcelable_decls error {
    119     fprintf(stderr, "%s:%d: syntax error don't know what to do with \"%s\"\n",
    120             ps->FileName().c_str(),
    121             @2.begin.line, $2->GetText().c_str());
    122     $$ = $1;
    123   };
    124 
    125 parcelable_decl
    126  : PARCELABLE qualified_name ';' {
    127     $$ = new AidlParcelable($2, @2.begin.line, ps->Package());
    128   }
    129  | PARCELABLE qualified_name CPP_HEADER C_STR ';' {
    130     $$ = new AidlParcelable($2, @2.begin.line, ps->Package(), $4->GetText());
    131   }
    132  | PARCELABLE ';' {
    133     fprintf(stderr, "%s:%d syntax error in parcelable declaration. Expected type name.\n",
    134             ps->FileName().c_str(), @1.begin.line);
    135     $$ = NULL;
    136   }
    137  | PARCELABLE error ';' {
    138     fprintf(stderr, "%s:%d syntax error in parcelable declaration. Expected type name, saw \"%s\".\n",
    139             ps->FileName().c_str(), @2.begin.line, $2->GetText().c_str());
    140     $$ = NULL;
    141   };
    142 
    143 interface_decl
    144  : annotation_list INTERFACE identifier '{' members '}' {
    145     $$ = new AidlInterface($3->GetText(), @2.begin.line, $2->GetComments(),
    146                            false, $5, ps->Package());
    147     $$->Annotate($1);
    148     delete $2;
    149     delete $3;
    150   }
    151  | annotation_list ONEWAY INTERFACE identifier '{' members '}' {
    152     $$ = new AidlInterface($4->GetText(), @4.begin.line, $2->GetComments(),
    153                            true, $6, ps->Package());
    154     $$->Annotate($1);
    155     delete $2;
    156     delete $3;
    157     delete $4;
    158   }
    159  | annotation_list INTERFACE error '{' members '}' {
    160     fprintf(stderr, "%s:%d: syntax error in interface declaration.  Expected "
    161                     "type name, saw \"%s\"\n",
    162             ps->FileName().c_str(), @3.begin.line, $3->GetText().c_str());
    163     $$ = NULL;
    164     delete $2;
    165     delete $3;
    166     delete $5;
    167   }
    168  | annotation_list INTERFACE error '}' {
    169     fprintf(stderr, "%s:%d: syntax error in interface declaration.  Expected "
    170                     "type name, saw \"%s\"\n",
    171             ps->FileName().c_str(), @3.begin.line, $3->GetText().c_str());
    172     $$ = NULL;
    173     delete $2;
    174     delete $3;
    175   };
    176 
    177 members
    178  :
    179   { $$ = new std::vector<std::unique_ptr<AidlMember>>(); }
    180  | members method_decl
    181   { $1->push_back(std::unique_ptr<AidlMember>($2)); }
    182  | members constant_decl
    183   { $1->push_back(std::unique_ptr<AidlMember>($2)); }
    184  | members error ';' {
    185     fprintf(stderr, "%s:%d: syntax error before ';' "
    186                     "(expected method or constant declaration)\n",
    187             ps->FileName().c_str(), @3.begin.line);
    188     $$ = $1;
    189   };
    190 
    191 constant_decl
    192  : CONST INT identifier '=' INTVALUE ';' {
    193     $$ = new AidlIntConstant($3->GetText(), $5);
    194     delete $3;
    195    }
    196  | CONST INT identifier '=' HEXVALUE ';' {
    197     $$ = new AidlIntConstant($3->GetText(), $5->GetText(), @5.begin.line);
    198     delete $3;
    199    }
    200  | CONST STRING identifier '=' C_STR ';' {
    201     $$ = new AidlStringConstant($3->GetText(), $5->GetText(), @5.begin.line);
    202     delete $3;
    203     delete $5;
    204    }
    205  ;
    206 
    207 method_decl
    208  : type identifier '(' arg_list ')' ';' {
    209     $$ = new AidlMethod(false, $1, $2->GetText(), $4, @2.begin.line,
    210                         $1->GetComments());
    211     delete $2;
    212   }
    213  | ONEWAY type identifier '(' arg_list ')' ';' {
    214     $$ = new AidlMethod(true, $2, $3->GetText(), $5, @3.begin.line,
    215                         $1->GetComments());
    216     delete $1;
    217     delete $3;
    218   }
    219  | type identifier '(' arg_list ')' '=' INTVALUE ';' {
    220     $$ = new AidlMethod(false, $1, $2->GetText(), $4, @2.begin.line,
    221                         $1->GetComments(), $7);
    222     delete $2;
    223   }
    224  | ONEWAY type identifier '(' arg_list ')' '=' INTVALUE ';' {
    225     $$ = new AidlMethod(true, $2, $3->GetText(), $5, @3.begin.line,
    226                         $1->GetComments(), $8);
    227     delete $1;
    228     delete $3;
    229   };
    230 
    231 arg_list
    232  :
    233   { $$ = new std::vector<std::unique_ptr<AidlArgument>>(); }
    234  | arg {
    235     $$ = new std::vector<std::unique_ptr<AidlArgument>>();
    236     $$->push_back(std::unique_ptr<AidlArgument>($1));
    237   }
    238  | arg_list ',' arg {
    239     $$ = $1;
    240     $$->push_back(std::unique_ptr<AidlArgument>($3));
    241   }
    242  | error {
    243     fprintf(stderr, "%s:%d: syntax error in parameter list\n",
    244             ps->FileName().c_str(), @1.begin.line);
    245     $$ = new std::vector<std::unique_ptr<AidlArgument>>();
    246   };
    247 
    248 arg
    249  : direction type identifier {
    250     $$ = new AidlArgument($1, $2, $3->GetText(), @3.begin.line);
    251     delete $3;
    252   };
    253  | type identifier {
    254     $$ = new AidlArgument($1, $2->GetText(), @2.begin.line);
    255     delete $2;
    256   };
    257 
    258 unannotated_type
    259  : qualified_name {
    260     $$ = new AidlType($1->GetDotName(), @1.begin.line, $1->GetComments(), false);
    261     delete $1;
    262   }
    263  | qualified_name '[' ']' {
    264     $$ = new AidlType($1->GetDotName(), @1.begin.line, $1->GetComments(),
    265                       true);
    266     delete $1;
    267   }
    268  | qualified_name '<' generic_list '>' {
    269     $$ = new AidlType($1->GetDotName() + "<" + *$3 + ">", @1.begin.line,
    270                       $1->GetComments(), false);
    271     delete $1;
    272     delete $3;
    273   };
    274 
    275 type
    276  : annotation_list unannotated_type {
    277     $$ = $2;
    278     $2->Annotate($1);
    279   };
    280 
    281 generic_list
    282  : qualified_name {
    283     $$ = new std::string($1->GetDotName());
    284     delete $1;
    285   }
    286  | generic_list ',' qualified_name {
    287     $$ = new std::string(*$1 + "," + $3->GetDotName());
    288     delete $1;
    289     delete $3;
    290   };
    291 
    292 annotation_list
    293  :
    294   { $$ = AidlType::AnnotationNone; }
    295  | annotation_list annotation
    296   { $$ = static_cast<AidlType::Annotation>($1 | $2); };
    297 
    298 annotation
    299  : ANNOTATION_NULLABLE
    300   { $$ = AidlType::AnnotationNullable; }
    301  | ANNOTATION_UTF8
    302   { $$ = AidlType::AnnotationUtf8; }
    303  | ANNOTATION_UTF8_CPP
    304   { $$ = AidlType::AnnotationUtf8InCpp; };
    305 
    306 direction
    307  : IN
    308   { $$ = AidlArgument::IN_DIR; }
    309  | OUT
    310   { $$ = AidlArgument::OUT_DIR; }
    311  | INOUT
    312   { $$ = AidlArgument::INOUT_DIR; };
    313 
    314 %%
    315 
    316 #include <ctype.h>
    317 #include <stdio.h>
    318 
    319 void yy::parser::error(const yy::parser::location_type& l,
    320                        const std::string& errstr) {
    321   ps->ReportError(errstr, l.begin.line);
    322 }
    323