1/*
2 * Copyright (C) 2016, The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *     http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17%{
18#include "aidl_language.h"
19#include "parser.h"
20#include "aidl_language_y.h"
21#include "logging.h"
22#include <android-base/parseint.h>
23#include <set>
24#include <map>
25#include <stdio.h>
26#include <stdlib.h>
27#include <string.h>
28
29int yylex(yy::parser::semantic_type *, yy::parser::location_type *, void *);
30
31AidlLocation loc(const yy::parser::location_type& begin, const yy::parser::location_type& end) {
32  AIDL_FATAL_IF(begin.begin.filename != begin.end.filename, AIDL_LOCATION_HERE);
33  AIDL_FATAL_IF(begin.end.filename != end.begin.filename, AIDL_LOCATION_HERE);
34  AIDL_FATAL_IF(end.begin.filename != end.end.filename, AIDL_LOCATION_HERE);
35  AidlLocation::Point begin_point {
36    .line = begin.begin.line,
37    .column = begin.begin.column,
38  };
39  AidlLocation::Point end_point {
40    .line = end.end.line,
41    .column = end.end.column,
42  };
43  return AidlLocation(*begin.begin.filename, begin_point, end_point, AidlLocation::Source::EXTERNAL);
44}
45
46AidlLocation loc(const yy::parser::location_type& l) {
47  return loc(l, l);
48}
49
50#define lex_scanner ps->Scanner()
51
52%}
53
54%initial-action {
55    @$.begin.filename = @$.end.filename =
56        const_cast<std::string *>(&ps->FileName());
57}
58
59%parse-param { Parser* ps }
60%lex-param { void *lex_scanner }
61
62%glr-parser
63%skeleton "glr.cc"
64
65%expect-rr 0
66
67%define parse.error verbose
68%locations
69
70%union {
71    AidlToken* token;
72    char character;
73    std::string *str;
74    AidlAnnotation* annotation;
75    AidlAnnotationParameter* param;
76    std::map<std::string, std::shared_ptr<AidlConstantValue>>* param_list;
77    std::vector<AidlAnnotation>* annotation_list;
78    AidlTypeSpecifier* type;
79    AidlArgument* arg;
80    AidlArgument::Direction direction;
81    AidlConstantValue* const_expr;
82    AidlEnumerator* enumerator;
83    std::vector<std::unique_ptr<AidlEnumerator>>* enumerators;
84    std::vector<std::unique_ptr<AidlConstantValue>>* constant_value_list;
85    std::vector<std::unique_ptr<AidlArgument>>* arg_list;
86    AidlVariableDeclaration* variable;
87    AidlMethod* method;
88    AidlMember* constant;
89    std::vector<std::unique_ptr<AidlMember>>* members;
90    AidlDefinedType* declaration;
91    std::vector<std::unique_ptr<AidlTypeSpecifier>>* type_args;
92    std::vector<std::string>* type_params;
93    std::vector<std::unique_ptr<AidlImport>>* imports;
94    AidlImport* import;
95    AidlPackage* package;
96    std::vector<std::unique_ptr<AidlDefinedType>>* declarations;
97}
98
99%destructor { } <direction>
100%destructor { delete ($$); } <*>
101
102%token<token> PACKAGE "package"
103%token<token> IMPORT "import"
104%token<token> ANNOTATION "annotation"
105%token<token> C_STR "string literal"
106%token<token> IDENTIFIER "identifier"
107%token<token> INTERFACE "interface"
108%token<token> PARCELABLE "parcelable"
109%token<token> ONEWAY "oneway"
110%token<token> ENUM "enum"
111%token<token> UNION "union"
112%token<token> CONST "const"
113
114%token<token> CHARVALUE "char literal"
115%token<token> FLOATVALUE "float literal"
116%token<token> HEXVALUE "hex literal"
117%token<token> INTVALUE "int literal"
118
119%token '(' ')' ',' '=' '[' ']' '.' '{' '}' ';'
120%token UNKNOWN "unrecognized character"
121%token<token> CPP_HEADER "cpp_header (which can also be used as an identifier)"
122%token IN "in"
123%token INOUT "inout"
124%token OUT "out"
125%token TRUE_LITERAL "true"
126%token FALSE_LITERAL "false"
127
128/* Operator precedence and associativity, as per
129 * http://en.cppreference.com/w/cpp/language/operator_precedence */
130/* Precedence level 13 - 14, LTR, logical operators*/
131%left LOGICAL_OR
132%left LOGICAL_AND
133/* Precedence level 10 - 12, LTR, bitwise operators*/
134%left '|'
135%left '^'
136%left '&'
137/* Precedence level 9, LTR */
138%left EQUALITY NEQ
139/* Precedence level 8, LTR */
140%left '<' '>' LEQ GEQ
141/* Precedence level 7, LTR */
142%left LSHIFT RSHIFT
143/* Precedence level 6, LTR */
144%left '+' '-'
145/* Precedence level 5, LTR */
146%left '*' '/' '%'
147/* Precedence level 3, RTL; but we have to use %left here */
148%right UNARY_PLUS UNARY_MINUS  '!' '~'
149
150%type<declaration> decl
151%type<declaration> unannotated_decl
152%type<declaration> interface_decl
153%type<declaration> parcelable_decl
154%type<declaration> enum_decl
155%type<declaration> union_decl
156%type<members> parcelable_members interface_members
157%type<variable> variable_decl
158%type<type_params> optional_type_params
159%type<method> method_decl
160%type<constant> constant_decl
161%type<enumerator> enumerator
162%type<enumerators> enumerators enum_decl_body
163%type<param> parameter
164%type<param_list> parameter_list
165%type<param_list> parameter_non_empty_list
166%type<annotation> annotation
167%type<annotation_list>annotation_list
168%type<type> type
169%type<type> non_array_type
170%type<arg_list> arg_list arg_non_empty_list
171%type<arg> arg
172%type<direction> direction
173%type<type_args> type_args
174%type<type_params> type_params
175%type<const_expr> const_expr
176%type<constant_value_list> constant_value_list
177%type<constant_value_list> constant_value_non_empty_list
178%type<imports> imports
179%type<import> import
180%type<package> package
181%type<declarations> decls
182%type<token> identifier error qualified_name
183
184%%
185
186document
187 : package imports decls {
188    Comments comments;
189    if ($1) {
190      comments = $1->GetComments();
191    } else if (!$2->empty()) {
192      comments = $2->front()->GetComments();
193    }
194    ps->SetDocument(std::make_unique<AidlDocument>(loc(@1), comments, std::move(*$2), std::move(*$3)));
195    delete $1;
196    delete $2;
197    delete $3;
198  }
199 ;
200
201/* A couple of tokens that are keywords elsewhere are identifiers when
202 * occurring in the identifier position. Therefore identifier is a
203 * non-terminal, which is either an IDENTIFIER token, or one of the
204 * aforementioned keyword tokens.
205 */
206identifier
207 : IDENTIFIER
208 | CPP_HEADER
209 ;
210
211package
212 : {
213    $$ = nullptr;
214 }
215 | PACKAGE qualified_name ';' {
216    $$ = new AidlPackage(loc(@1, @3), $1->GetComments());
217    ps->SetPackage($2->GetText());
218    delete $1;
219    delete $2;
220  }
221 ;
222
223imports
224 : { $$ = new std::vector<std::unique_ptr<AidlImport>>(); }
225 | imports import
226  {
227    $$ = $1;
228    auto it = std::find_if($$->begin(), $$->end(), [&](const auto& i) {
229      return $2->GetNeededClass() == i->GetNeededClass();
230    });
231    if (it == $$->end()) {
232      $$->emplace_back($2);
233    } else {
234      delete $2;
235    }
236  }
237
238import
239 : IMPORT qualified_name ';' {
240    $$ = new AidlImport(loc(@2), $2->GetText(), $1->GetComments());
241    delete $1;
242    delete $2;
243  };
244
245qualified_name
246 : identifier {
247    $$ = $1;
248  }
249 | qualified_name '.' identifier
250  { $$ = $1;
251    $$->Append('.');
252    $$->Append($3->GetText());
253    delete $3;
254  };
255
256decls
257 : decl
258  { $$ = new std::vector<std::unique_ptr<AidlDefinedType>>();
259    if ($1 != nullptr) {
260      $$->emplace_back($1);
261    }
262  }
263 | decls decl
264  { $$ = $1;
265    if ($2 != nullptr) {
266      $$->emplace_back($2);
267    }
268  }
269
270decl
271 : annotation_list unannotated_decl
272   {
273    $$ = $2;
274
275    if ($1->size() > 0 && $$ != nullptr) {
276      // copy comments from annotation to decl
277      $$->SetComments($1->begin()->GetComments());
278      $$->Annotate(std::move(*$1));
279    }
280
281    delete $1;
282   }
283 ;
284
285unannotated_decl
286 : parcelable_decl
287 | interface_decl
288 | enum_decl
289 | union_decl
290 ;
291
292type_params
293 : identifier {
294    $$ = new std::vector<std::string>();
295    $$->emplace_back($1->GetText());
296    delete $1;
297  }
298 | type_params ',' identifier {
299    $1->emplace_back($3->GetText());
300    $$ = $1;
301    delete $3;
302  };
303
304 optional_type_params
305  : /* none */ { $$ = nullptr; }
306  | '<' type_params '>' {
307    $$ = $2;
308  };
309
310parcelable_decl
311 : PARCELABLE qualified_name optional_type_params ';' {
312    $$ = new AidlParcelable(loc(@2), $2->GetText(), ps->Package(), $1->GetComments(), "", $3);
313    delete $1;
314    delete $2;
315 }
316 | PARCELABLE qualified_name optional_type_params '{' parcelable_members '}' {
317    $$ = new AidlStructuredParcelable(loc(@2), $2->GetText(), ps->Package(), $1->GetComments(), $3, $5);
318    delete $1;
319    delete $2;
320 }
321 | PARCELABLE qualified_name CPP_HEADER C_STR ';' {
322    $$ = new AidlParcelable(loc(@2), $2->GetText(), ps->Package(), $1->GetComments(), $4->GetText());
323    delete $1;
324    delete $2;
325    delete $3;
326    delete $4;
327  }
328 | PARCELABLE error ';' {
329    ps->AddError();
330    $$ = nullptr;
331    delete $1;
332  };
333
334parcelable_members
335 : /* empty */ {
336    $$ = new std::vector<std::unique_ptr<AidlMember>>();
337  }
338 | parcelable_members variable_decl {
339    $1->emplace_back($2);
340    $$ = $1;
341  }
342 | parcelable_members constant_decl {
343    $1->emplace_back($2);
344    $$ = $1;
345  }
346 | parcelable_members error ';' {
347    ps->AddError();
348    $$ = $1;
349  };
350
351variable_decl
352 : type identifier ';' {
353   $$ = new AidlVariableDeclaration(loc(@2), $1, $2->GetText());
354   delete $2;
355 }
356 | type identifier '=' const_expr ';' {
357   // TODO(b/123321528): Support enum type default assignments (TestEnum foo = TestEnum.FOO).
358   $$ = new AidlVariableDeclaration(loc(@2), $1, $2->GetText(),  $4);
359   delete $2;
360 }
361 ;
362
363interface_decl
364 : INTERFACE identifier '{' interface_members '}' {
365    $$ = new AidlInterface(loc(@1), $2->GetText(), $1->GetComments(), false, ps->Package(), $4);
366    delete $1;
367    delete $2;
368  }
369 | ONEWAY INTERFACE identifier '{' interface_members '}' {
370    $$ = new AidlInterface(loc(@2), $3->GetText(),  $1->GetComments(), true, ps->Package(), $5);
371    delete $1;
372    delete $2;
373    delete $3;
374  }
375 | INTERFACE error '{' interface_members '}' {
376    ps->AddError();
377    $$ = nullptr;
378    delete $1;
379    delete $4;
380  };
381
382interface_members
383 :
384  { $$ = new std::vector<std::unique_ptr<AidlMember>>(); }
385 | interface_members method_decl
386  { $1->push_back(std::unique_ptr<AidlMember>($2)); $$ = $1; }
387 | interface_members constant_decl
388  { $1->push_back(std::unique_ptr<AidlMember>($2)); $$ = $1; }
389 | interface_members error ';' {
390    ps->AddError();
391    $$ = $1;
392  };
393
394const_expr
395 : TRUE_LITERAL { $$ = AidlConstantValue::Boolean(loc(@1), true); }
396 | FALSE_LITERAL { $$ = AidlConstantValue::Boolean(loc(@1), false); }
397 | CHARVALUE {
398    $$ = AidlConstantValue::Character(loc(@1), $1->GetText());
399    delete $1;
400  }
401 | INTVALUE {
402    $$ = AidlConstantValue::Integral(loc(@1), $1->GetText());
403    if ($$ == nullptr) {
404      AIDL_ERROR(loc(@1)) << "Could not parse integer: "
405                << $1->GetText();
406      ps->AddError();
407      $$ = AidlConstantValue::Integral(loc(@1), "0");
408    }
409    delete $1;
410  }
411 | FLOATVALUE {
412    $$ = AidlConstantValue::Floating(loc(@1), $1->GetText());
413    delete $1;
414  }
415 | HEXVALUE {
416    $$ = AidlConstantValue::Integral(loc(@1), $1->GetText());
417    if ($$ == nullptr) {
418      AIDL_ERROR(loc(@1)) << "Could not parse hexvalue: "
419                << $1->GetText();
420      ps->AddError();
421      $$ = AidlConstantValue::Integral(loc(@1), "0");
422    }
423    delete $1;
424  }
425 | C_STR {
426    $$ = AidlConstantValue::String(loc(@1), $1->GetText());
427    delete $1;
428  }
429 | qualified_name {
430    $$ = new AidlConstantReference(loc(@1), $1->GetText());
431    delete $1;
432 }
433 | '{' constant_value_list '}' {
434    $$ = AidlConstantValue::Array(loc(@1), std::unique_ptr<vector<unique_ptr<AidlConstantValue>>>($2));
435  }
436 | const_expr LOGICAL_OR const_expr {
437    $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), "||", std::unique_ptr<AidlConstantValue>($3));
438  }
439 | const_expr LOGICAL_AND const_expr {
440    $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), "&&", std::unique_ptr<AidlConstantValue>($3));
441  }
442 | const_expr '|' const_expr {
443    $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), "|" , std::unique_ptr<AidlConstantValue>($3));
444  }
445 | const_expr '^' const_expr {
446    $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), "^" , std::unique_ptr<AidlConstantValue>($3));
447  }
448 | const_expr '&' const_expr {
449    $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), "&" , std::unique_ptr<AidlConstantValue>($3));
450  }
451 | const_expr EQUALITY const_expr {
452    $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), "==", std::unique_ptr<AidlConstantValue>($3));
453  }
454 | const_expr NEQ const_expr {
455    $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), "!=", std::unique_ptr<AidlConstantValue>($3));
456  }
457 | const_expr '<' const_expr {
458    $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), "<" , std::unique_ptr<AidlConstantValue>($3));
459  }
460 | const_expr '>' const_expr {
461    $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), ">" , std::unique_ptr<AidlConstantValue>($3));
462  }
463 | const_expr LEQ const_expr {
464    $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), "<=", std::unique_ptr<AidlConstantValue>($3));
465  }
466 | const_expr GEQ const_expr {
467    $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), ">=", std::unique_ptr<AidlConstantValue>($3));
468  }
469 | const_expr LSHIFT const_expr {
470    $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), "<<", std::unique_ptr<AidlConstantValue>($3));
471  }
472 | const_expr RSHIFT const_expr {
473    $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), ">>", std::unique_ptr<AidlConstantValue>($3));
474  }
475 | const_expr '+' const_expr {
476    $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), "+" , std::unique_ptr<AidlConstantValue>($3));
477  }
478 | const_expr '-' const_expr {
479    $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), "-" , std::unique_ptr<AidlConstantValue>($3));
480  }
481 | const_expr '*' const_expr {
482    $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), "*" , std::unique_ptr<AidlConstantValue>($3));
483  }
484 | const_expr '/' const_expr {
485    $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), "/" , std::unique_ptr<AidlConstantValue>($3));
486  }
487 | const_expr '%' const_expr {
488    $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), "%" , std::unique_ptr<AidlConstantValue>($3));
489  }
490 | '+' const_expr %prec UNARY_PLUS  {
491    $$ = new AidlUnaryConstExpression(loc(@1), "+", std::unique_ptr<AidlConstantValue>($2));
492  }
493 | '-' const_expr %prec UNARY_MINUS {
494    $$ = new AidlUnaryConstExpression(loc(@1), "-", std::unique_ptr<AidlConstantValue>($2));
495  }
496 | '!' const_expr {
497    $$ = new AidlUnaryConstExpression(loc(@1), "!", std::unique_ptr<AidlConstantValue>($2));
498  }
499 | '~' const_expr {
500    $$ = new AidlUnaryConstExpression(loc(@1), "~", std::unique_ptr<AidlConstantValue>($2));
501  }
502 | '(' const_expr ')'
503  {
504    $$ = $2;
505  }
506 | '(' error ')'
507   {
508     AIDL_ERROR(loc(@1)) << "invalid const expression within parenthesis";
509     ps->AddError();
510     // to avoid segfaults
511     $$ = AidlConstantValue::Integral(loc(@1), "0");
512   }
513 ;
514
515constant_value_list
516 : /* empty */ {
517    $$ = new std::vector<std::unique_ptr<AidlConstantValue>>;
518 }
519 | constant_value_non_empty_list {
520    $$ = $1;
521 }
522 | constant_value_non_empty_list  ',' {
523    $$ = $1;
524 }
525 ;
526
527constant_value_non_empty_list
528 : const_expr {
529    $$ = new std::vector<std::unique_ptr<AidlConstantValue>>;
530    $$->push_back(std::unique_ptr<AidlConstantValue>($1));
531 }
532 | constant_value_non_empty_list ',' const_expr {
533    $$ = $1;
534    $$->push_back(std::unique_ptr<AidlConstantValue>($3));
535 }
536 ;
537
538constant_decl
539 : annotation_list CONST type identifier '=' const_expr ';' {
540    if ($1->size() > 0) {
541      $3->SetComments($1->begin()->GetComments());
542    } else {
543      $3->SetComments($2->GetComments());
544    }
545    // TODO(b/151102494) do not merge annotations.
546    $3->Annotate(std::move(*$1));
547    $$ = new AidlConstantDeclaration(loc(@4), $3, $4->GetText(), $6);
548    delete $1;
549    delete $2;
550    delete $4;
551   }
552 ;
553
554enumerator
555 : identifier '=' const_expr {
556    $$ = new AidlEnumerator(loc(@1), $1->GetText(), $3, $1->GetComments());
557    delete $1;
558   }
559 | identifier {
560    $$ = new AidlEnumerator(loc(@1), $1->GetText(), nullptr, $1->GetComments());
561    delete $1;
562   }
563 ;
564
565enumerators
566 : enumerator {
567    $$ = new std::vector<std::unique_ptr<AidlEnumerator>>();
568    $$->push_back(std::unique_ptr<AidlEnumerator>($1));
569   }
570 | enumerators ',' enumerator {
571    $1->push_back(std::unique_ptr<AidlEnumerator>($3));
572    $$ = $1;
573   }
574 ;
575
576enum_decl_body
577 : '{' enumerators '}' { $$ = $2; }
578 | '{' enumerators ',' '}' { $$ = $2; }
579 ;
580
581enum_decl
582 : ENUM identifier enum_decl_body {
583    $$ = new AidlEnumDeclaration(loc(@2), $2->GetText(), $3, ps->Package(), $1->GetComments());
584    delete $1;
585    delete $2;
586    delete $3;
587   }
588 ;
589
590union_decl
591 : UNION qualified_name optional_type_params '{' parcelable_members '}' {
592    $$ = new AidlUnionDecl(loc(@2), $2->GetText(), ps->Package(), $1->GetComments(), $3, $5);
593    delete $1;
594    delete $2;
595  }
596 ;
597
598method_decl
599 : type identifier '(' arg_list ')' ';' {
600    $$ = new AidlMethod(loc(@2), false, $1, $2->GetText(), $4, $1->GetComments());
601    delete $2;
602  }
603 | annotation_list ONEWAY type identifier '(' arg_list ')' ';' {
604    const auto& comments = ($1->size() > 0) ? $1->begin()->GetComments() : $2->GetComments();
605    $$ = new AidlMethod(loc(@4), true, $3, $4->GetText(), $6, comments);
606    $3->Annotate(std::move(*$1));
607    delete $1;
608    delete $2;
609    delete $4;
610  }
611 | type identifier '(' arg_list ')' '=' INTVALUE ';' {
612    int32_t serial = 0;
613    if (!android::base::ParseInt($7->GetText(), &serial)) {
614        AIDL_ERROR(loc(@7)) << "Could not parse int value: " << $7->GetText();
615        ps->AddError();
616    }
617    $$ = new AidlMethod(loc(@2), false, $1, $2->GetText(), $4, $1->GetComments(), serial);
618    delete $2;
619    delete $7;
620  }
621 | annotation_list ONEWAY type identifier '(' arg_list ')' '=' INTVALUE ';' {
622    const auto& comments = ($1->size() > 0) ? $1->begin()->GetComments() : $2->GetComments();
623    int32_t serial = 0;
624    if (!android::base::ParseInt($9->GetText(), &serial)) {
625        AIDL_ERROR(loc(@9)) << "Could not parse int value: " << $9->GetText();
626        ps->AddError();
627    }
628    $$ = new AidlMethod(loc(@4), true, $3, $4->GetText(), $6, comments, serial);
629    $3->Annotate(std::move(*$1));
630    delete $1;
631    delete $2;
632    delete $4;
633    delete $9;
634  };
635
636arg_non_empty_list
637 : arg {
638    $$ = new std::vector<std::unique_ptr<AidlArgument>>();
639    $$->push_back(std::unique_ptr<AidlArgument>($1));
640  }
641 | arg_non_empty_list ',' arg {
642    $$ = $1;
643    $$->push_back(std::unique_ptr<AidlArgument>($3));
644  };
645
646arg_list
647 : /*empty*/
648   { $$ = new std::vector<std::unique_ptr<AidlArgument>>(); }
649 | arg_non_empty_list { $$ = $1; }
650 ;
651
652arg
653 : direction type identifier {
654    $$ = new AidlArgument(loc(@3), $1, $2, $3->GetText());
655    delete $3;
656  }
657 | type identifier {
658    $$ = new AidlArgument(loc(@2), $1, $2->GetText());
659    delete $2;
660  };
661
662non_array_type
663 : annotation_list qualified_name {
664    $$ = new AidlTypeSpecifier(loc(@2), $2->GetText(), false, nullptr, $2->GetComments());
665    ps->DeferResolution($$);
666    if (!$1->empty()) {
667      $$->SetComments($1->begin()->GetComments());
668      $$->Annotate(std::move(*$1));
669    }
670    delete $1;
671    delete $2;
672  }
673 | non_array_type '<' type_args '>' {
674    ps->SetTypeParameters($1, $3);
675    $$ = $1;
676  }
677 | non_array_type '<' non_array_type '<' type_args RSHIFT {
678    ps->SetTypeParameters($3, $5);
679    auto params = new std::vector<std::unique_ptr<AidlTypeSpecifier>>();
680    params->emplace_back($3);
681    ps->SetTypeParameters($1, params);
682    $$ = $1;
683  }
684 | non_array_type '<' type_args ',' non_array_type '<' type_args RSHIFT {
685    ps->SetTypeParameters($5, $7);
686    $3->emplace_back($5);
687    ps->SetTypeParameters($1, $3);
688    $$ = $1;
689  };
690
691type
692 : non_array_type
693 | type annotation_list '[' ']' {
694    if (!$2->empty()) {
695      AIDL_ERROR(loc(@2)) << "Annotations for arrays are not supported.";
696      ps->AddError();
697    }
698    if (!$1->SetArray()) {
699      AIDL_ERROR(loc(@1)) << "Can only have one dimensional arrays.";
700      ps->AddError();
701    }
702    $$ = $1;
703    delete $2;
704  }
705 ;
706
707type_args
708 : type {
709    if (!$1->GetAnnotations().empty()) {
710      AIDL_ERROR(loc(@1)) << "Annotations for type arguments are not supported.";
711      ps->AddError();
712    }
713    $$ = new std::vector<std::unique_ptr<AidlTypeSpecifier>>();
714    $$->emplace_back($1);
715  }
716 | type_args ',' type {
717    $1->emplace_back($3);
718    $$ = $1;
719  };
720
721annotation_list
722 :
723  { $$ = new std::vector<AidlAnnotation>(); }
724 | annotation_list annotation
725  {
726    if ($2 != nullptr) {
727      $1->emplace_back(std::move(*$2));
728      delete $2;
729    }
730    $$ = $1;
731  };
732
733parameter
734  : identifier '=' const_expr {
735    $$ = new AidlAnnotationParameter{$1->GetText(), std::unique_ptr<AidlConstantValue>($3)};
736    delete $1;
737  };
738
739parameter_list
740  : /*empty*/{
741    $$ = new std::map<std::string, std::shared_ptr<AidlConstantValue>>();
742  }
743  | parameter_non_empty_list  {
744    $$ = $1;
745  };
746
747parameter_non_empty_list
748  : parameter {
749    $$ = new std::map<std::string, std::shared_ptr<AidlConstantValue>>();
750    $$->emplace(std::move($1->name), $1->value.release());
751    delete $1;
752  }
753  | parameter_non_empty_list ',' parameter {
754    $$ = $1;
755    if ($$->find($3->name) != $$->end()) {
756      AIDL_ERROR(loc(@3)) << "Trying to redefine parameter " << $3->name << ".";
757      ps->AddError();
758    }
759    $$->emplace(std::move($3->name), std::move($3->value));
760    delete $3;
761  };
762
763annotation
764 : ANNOTATION {
765    $$ = AidlAnnotation::Parse(loc(@1), $1->GetText(), nullptr, $1->GetComments());
766    if (!$$) {
767      ps->AddError();
768    }
769    delete $1;
770  }
771 | ANNOTATION '(' parameter_list ')' {
772    $$ = AidlAnnotation::Parse(loc(@1, @4), $1->GetText(), $3, $1->GetComments());
773    if (!$$) {
774      ps->AddError();
775    }
776    delete $1;
777    delete $3;
778  }
779 ;
780
781direction
782 : IN
783  { $$ = AidlArgument::IN_DIR; }
784 | OUT
785  { $$ = AidlArgument::OUT_DIR; }
786 | INOUT
787  { $$ = AidlArgument::INOUT_DIR; };
788
789%%
790
791#include <ctype.h>
792#include <stdio.h>
793
794void yy::parser::error(const yy::parser::location_type& l, const std::string& errstr) {
795  AIDL_ERROR(loc(l)) << errstr;
796  // parser will return error value
797}
798