blob: e44e48873039b4d0031fbaf8378138f724343925 [file] [log] [blame]
Andreas Huber1aec3972016-08-26 09:26:32 -07001/*
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
Andreas Huberc9410c72016-07-28 12:18:40 -070017%{
18
Andreas Huber3599d922016-08-09 10:42:57 -070019#include "Annotation.h"
Andreas Huberc9410c72016-07-28 12:18:40 -070020#include "AST.h"
21#include "ArrayType.h"
22#include "CompoundType.h"
Yifan Hong52165692016-08-12 18:06:40 -070023#include "ConstantExpression.h"
Andreas Huberc9410c72016-07-28 12:18:40 -070024#include "EnumType.h"
Yifan Hongf24fa852016-09-23 11:03:15 -070025#include "FQName.h"
Andreas Huberc9410c72016-07-28 12:18:40 -070026#include "Interface.h"
Yifan Honga4b53d02016-10-31 17:29:10 -070027#include "Location.h"
Andreas Huberc9410c72016-07-28 12:18:40 -070028#include "Method.h"
Andreas Huberc9410c72016-07-28 12:18:40 -070029#include "VectorType.h"
Yifan Hongbf459bc2016-08-23 16:50:37 -070030#include "RefType.h"
Andreas Huberc9410c72016-07-28 12:18:40 -070031
32#include "hidl-gen_y.h"
33
Andreas Huber709b62d2016-09-19 11:21:18 -070034#include <android-base/logging.h>
Yifan Hong27e85db2016-11-09 15:45:52 -080035#include <hidl-util/StringHelper.h>
Andreas Huberc9410c72016-07-28 12:18:40 -070036#include <stdio.h>
37
38using namespace android;
39
Andreas Huber0d0f9a22016-08-17 10:26:11 -070040extern int yylex(yy::parser::semantic_type *, yy::parser::location_type *, void *);
Andreas Huberc9410c72016-07-28 12:18:40 -070041
42#define scanner ast->scanner()
43
Yifan Honga4b53d02016-10-31 17:29:10 -070044::android::Location convertYYLoc(const yy::parser::location_type &loc) {
45 return ::android::Location(
46 ::android::Position(*(loc.begin.filename), loc.begin.line, loc.begin.column),
47 ::android::Position(*(loc.end.filename), loc.end.line, loc.end.column)
48 );
49}
50
Yifan Hong27e85db2016-11-09 15:45:52 -080051bool isValidInterfaceField(const char *identifier, std::string *errorMsg) {
52 static const std::vector<std::string> reserved({
53 // Injected names to interfaces by auto-generated code
Yifan Hongc8934042016-11-17 17:10:52 -080054 "isRemote", "descriptor", "hidlStaticBlock", "onTransact",
Yifan Hong27e85db2016-11-09 15:45:52 -080055 "castFrom", "version", "getInterfaceVersion",
56
57 // Inherited names by interfaces from IInterface / IBinder
58 "onAsBinder", "asBinder", "queryLocalInterface", "getInterfaceDescriptor", "isBinderAlive",
59 "pingBinder", "dump", "transact", "linkToDeath", "unlinkToDeath", "checkSubclass",
60 "attachObject", "findObject", "detachObject", "localBinder", "remoteBinder", "mImpl",
61 });
62 std::string idstr(identifier);
63 if (std::find(reserved.begin(), reserved.end(), idstr) != reserved.end()) {
64 *errorMsg = idstr + " cannot be a name inside an interface";
65 return false;
66 }
67 return true;
68}
69
70bool isValidStructField(const char *identifier, std::string *errorMsg) {
71 static const std::vector<std::string> reserved({
72 // Injected names to structs and unions by auto-generated code
73 "readEmbeddedFromParcel", "writeEmbeddedToParcel", "readVectorFromParcel",
74 "writeVectorToParcel", "writeEmbeddedToBlob",
75 });
76 std::string idstr(identifier);
77 if (std::find(reserved.begin(), reserved.end(), idstr) != reserved.end()) {
78 *errorMsg = idstr + " cannot be a name inside an struct or union";
79 return false;
80 }
81 return true;
82}
83
84bool isValidIdentifier(const char *identifier, std::string *errorMsg) {
85 static const std::vector<std::string> keywords({
86 "uint8_t", "uint16_t", "uint32_t", "uint64_t",
87 "int8_t", "int16_t", "int32_t", "int64_t", "bool", "float", "double",
88 "interface", "struct", "union", "string", "vec", "enum", "ref", "handle",
89 "package", "import", "typedef", "generates", "oneway", "extends",
90 "MQDescriptorSync", "MQDescriptorUnsync",
91 });
92 static const std::vector<std::string> cppKeywords({
93 "alignas", "alignof", "and", "and_eq", "asm", "atomic_cancel", "atomic_commit",
94 "atomic_noexcept", "auto", "bitand", "bitor", "bool", "break", "case", "catch",
95 "char", "char16_t", "char32_t", "class", "compl", "concept", "const", "constexpr",
96 "const_cast", "continue", "decltype", "default", "delete", "do", "double",
97 "dynamic_cast", "else", "enum", "explicit", "export", "extern", "false", "float",
98 "for", "friend", "goto", "if", "inline", "int", "import", "long", "module", "mutable",
99 "namespace", "new", "noexcept", "not", "not_eq", "nullptr", "operator", "or", "or_eq",
100 "private", "protected", "public", "register", "reinterpret_cast", "requires", "return",
101 "short", "signed", "sizeof", "static", "static_assert", "static_cast", "struct",
102 "switch", "synchronized", "template", "this", "thread_local", "throw", "true", "try",
103 "typedef", "typeid", "typename", "union", "unsigned", "using", "virtual", "void",
104 "volatile", "wchar_t", "while", "xor", "xor_eq",
105 });
106 static const std::vector<std::string> javaKeywords({
107 "abstract", "continue", "for", "new", "switch", "assert", "default", "goto", "package",
108 "synchronized", "boolean", "do", "if", "private", "this", "break", "double",
109 "implements", "protected", "throw", "byte", "else", "import", "public", "throws",
110 "case", "enum", "instanceof", "return", "transient", "catch", "extends", "int",
111 "short", "try", "char", "final", "interface", "static", "void", "class", "finally",
112 "long", "strictfp", "volatile", "const", "float", "native", "super", "while",
113 });
114 static const std::vector<std::string> cppCollide({
115 "size_t", "offsetof",
116 "DECLARE_REGISTER_AND_GET_SERVICE", "IMPLEMENT_HWBINDER_META_INTERFACE",
117 "IMPLEMENT_REGISTER_AND_GET_SERVICE"
118 });
119 static const std::vector<std::string> hidlReserved({
120 // Part of HidlSupport
121 "hidl_string", "hidl_vec", "hidl_array", "hidl_version", "toBinder", "castInterface",
122 "make_hidl_version"
123 });
124
125 // errors
126 std::string idstr(identifier);
127 if (std::find(keywords.begin(), keywords.end(), idstr) != keywords.end()) {
128 *errorMsg = idstr + " is a HIDL keyword "
129 "and is therefore not a valid identifier";
130 return false;
131 }
132 if (std::find(cppKeywords.begin(), cppKeywords.end(), idstr) != cppKeywords.end()) {
133 *errorMsg = idstr + " is a C++ keyword "
134 "and is therefore not a valid identifier";
135 return false;
136 }
137 if (std::find(javaKeywords.begin(), javaKeywords.end(), idstr) != javaKeywords.end()) {
138 *errorMsg = idstr + " is a Java keyword "
139 "and is therefore not a valid identifier";
140 return false;
141 }
142 if (std::find(cppCollide.begin(), cppCollide.end(), idstr) != cppCollide.end()) {
143 *errorMsg = idstr + " collides with reserved names in C++ code "
144 "and is therefore not a valid identifier";
145 return false;
146 }
147 if (StringHelper::StartsWith(idstr, "_hidl_")) {
148 *errorMsg = idstr + " starts with _hidl_ "
149 "and is therefore not a valid identifier";
150 return false;
151 }
152 if (StringHelper::EndsWith(idstr, "_cb")) {
153 *errorMsg = idstr + " ends with _cb "
154 "and is therefore not a valid identifier";
155 return false;
156 }
157
158 // warnings
159 if (std::find(hidlReserved.begin(), hidlReserved.end(), idstr) != hidlReserved.end()) {
160 *errorMsg = idstr + " is a name reserved by HIDL and should be avoided";
161 }
162 return true;
163}
Yifan Honga4b53d02016-10-31 17:29:10 -0700164
Andreas Huberc9410c72016-07-28 12:18:40 -0700165%}
166
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700167%initial-action {
168 // Initialize the initial location.
169 @$.begin.filename = @$.end.filename =
170 const_cast<std::string *>(&ast->getFilename());
171}
172
Andreas Huberc9410c72016-07-28 12:18:40 -0700173%parse-param { android::AST *ast }
174%lex-param { void *scanner }
175%pure-parser
Steven Moreland4ab9b792016-09-26 14:14:07 -0700176%glr-parser
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700177%skeleton "glr.cc"
Andreas Huberc9410c72016-07-28 12:18:40 -0700178
Steven Moreland4ab9b792016-09-26 14:14:07 -0700179%expect-rr 0
180
Andreas Huberc9410c72016-07-28 12:18:40 -0700181%token<str> ENUM
182%token<str> EXTENDS
Andreas Huber84f89de2016-07-28 15:39:51 -0700183%token<str> FQNAME
Andreas Huberc9410c72016-07-28 12:18:40 -0700184%token<str> GENERATES
185%token<str> IDENTIFIER
186%token<str> IMPORT
187%token<str> INTEGER
Yifan Hong52165692016-08-12 18:06:40 -0700188%token<str> FLOAT
Andreas Huberc9410c72016-07-28 12:18:40 -0700189%token<str> INTERFACE
190%token<str> PACKAGE
Hridya Valsarajucd91bf62016-10-25 12:41:04 -0700191%token<type> TYPE
Andreas Huberc9410c72016-07-28 12:18:40 -0700192%token<str> STRUCT
193%token<str> STRING_LITERAL
194%token<str> TYPEDEF
195%token<str> UNION
Yifan Hongbf459bc2016-08-23 16:50:37 -0700196%token<templatedType> TEMPLATED
Iliyan Malchev639bff82016-08-13 14:24:11 -0700197%token<void> ONEWAY
Andreas Huberc9410c72016-07-28 12:18:40 -0700198
Yifan Hong52165692016-08-12 18:06:40 -0700199/* Operator precedence and associativity, as per
200 * http://en.cppreference.com/w/cpp/language/operator_precedence */
201/* Precedence level 15 ternary operator */
202%right '?' ':'
203/* Precedence level 13 - 14, LTR, logical operators*/
204%left LOGICAL_OR
205%left LOGICAL_AND
206/* Precedence level 10 - 12, LTR, bitwise operators*/
207%left '|'
208%left '^'
209%left '&'
210/* Precedence level 9, LTR */
211%left EQUALITY NEQ
212/* Precedence level 8, LTR */
213%left '<' '>' LEQ GEQ
214/* Precedence level 7, LTR */
215%left LSHIFT RSHIFT
216/* Precedence level 6, LTR */
217%left '+' '-'
218/* Precedence level 5, LTR */
219%left '*' '/' '%'
220/* Precedence level 3, RTL; but we have to use %left here */
221%left UNARY_MINUS UNARY_PLUS '!' '~'
222
Yifan Hongbe627b32016-10-28 18:38:56 -0700223%type<str> error_stmt opt_error_stmt error
Yifan Hong6a2fedf2016-10-11 13:44:07 -0700224%type<str> package
Yifan Hongae16eed2016-09-23 13:25:25 -0700225%type<fqName> fqname
226%type<type> fqtype
Yifan Hong27e85db2016-11-09 15:45:52 -0800227%type<str> valid_identifier
Andreas Huberc9410c72016-07-28 12:18:40 -0700228
Steven Moreland1c71fd52016-11-29 14:03:33 -0800229%type<type> type enum_storage_type
Yifan Hongbd33e382016-11-02 13:30:17 -0700230%type<type> array_type_base
231%type<arrayType> array_type
Andreas Huberc9410c72016-07-28 12:18:40 -0700232%type<type> opt_extends
Yifan Hong27e85db2016-11-09 15:45:52 -0800233%type<type> type_declaration type_declaration_body interface_declaration typedef_declaration
Andreas Huber7c5ddfb2016-09-29 13:45:22 -0700234%type<type> named_struct_or_union_declaration named_enum_declaration
235%type<type> compound_declaration annotated_compound_declaration
Andreas Huberc9410c72016-07-28 12:18:40 -0700236
237%type<field> field_declaration
238%type<fields> field_declarations struct_or_union_body
Yifan Hong52165692016-08-12 18:06:40 -0700239%type<constantExpression> const_expr
Andreas Huberc9410c72016-07-28 12:18:40 -0700240%type<enumValue> enum_value
Yifan Hongf24fa852016-09-23 11:03:15 -0700241%type<enumValues> enum_values enum_declaration_body
Andreas Huberc9410c72016-07-28 12:18:40 -0700242%type<typedVars> typed_vars
243%type<typedVar> typed_var
244%type<method> method_declaration
245%type<compoundStyle> struct_or_union_keyword
Yifan Hongf24fa852016-09-23 11:03:15 -0700246%type<stringVec> annotation_string_values annotation_string_value
247%type<constExprVec> annotation_const_expr_values annotation_const_expr_value
Andreas Huber3599d922016-08-09 10:42:57 -0700248%type<annotationParam> annotation_param
249%type<annotationParams> opt_annotation_params annotation_params
250%type<annotation> annotation
251%type<annotations> opt_annotations
Andreas Huberc9410c72016-07-28 12:18:40 -0700252
253%start program
254
255%union {
256 const char *str;
257 android::Type *type;
Yifan Hongbd33e382016-11-02 13:30:17 -0700258 android::ArrayType *arrayType;
Yifan Hongbf459bc2016-08-23 16:50:37 -0700259 android::TemplatedType *templatedType;
Yifan Hongae16eed2016-09-23 13:25:25 -0700260 android::FQName *fqName;
Andreas Huberc9410c72016-07-28 12:18:40 -0700261 android::CompoundType *compoundType;
262 android::CompoundField *field;
Andreas Huber881227d2016-08-02 14:20:21 -0700263 std::vector<android::CompoundField *> *fields;
Andreas Huberc9410c72016-07-28 12:18:40 -0700264 android::EnumValue *enumValue;
Yifan Hong52165692016-08-12 18:06:40 -0700265 android::ConstantExpression *constantExpression;
Andreas Huber881227d2016-08-02 14:20:21 -0700266 std::vector<android::EnumValue *> *enumValues;
Andreas Huberc9410c72016-07-28 12:18:40 -0700267 android::TypedVar *typedVar;
Andreas Huber881227d2016-08-02 14:20:21 -0700268 std::vector<android::TypedVar *> *typedVars;
Andreas Huberc9410c72016-07-28 12:18:40 -0700269 android::Method *method;
270 android::CompoundType::Style compoundStyle;
Andreas Huber3599d922016-08-09 10:42:57 -0700271 std::vector<std::string> *stringVec;
Yifan Hongf24fa852016-09-23 11:03:15 -0700272 std::vector<android::ConstantExpression *> *constExprVec;
Steven Morelandd537ab02016-09-12 10:32:01 -0700273 android::AnnotationParam *annotationParam;
274 android::AnnotationParamVector *annotationParams;
Andreas Huber3599d922016-08-09 10:42:57 -0700275 android::Annotation *annotation;
Steven Morelandd537ab02016-09-12 10:32:01 -0700276 std::vector<android::Annotation *> *annotations;
Andreas Huberc9410c72016-07-28 12:18:40 -0700277}
278
279%%
280
Yifan Hong27e85db2016-11-09 15:45:52 -0800281valid_identifier
282 : IDENTIFIER
283 {
284 std::string errorMsg;
285 if (!isValidIdentifier($1, &errorMsg)) {
286 std::cerr << "ERROR: " << errorMsg << " at " << @1 << "\n";
287 YYERROR;
288 }
289 if (!errorMsg.empty()) {
290 std::cerr << "WARNING: " << errorMsg << " at " << @1 << "\n";
291 }
292 $$ = $1;
293 }
294 ;
295
Andreas Huber3599d922016-08-09 10:42:57 -0700296opt_annotations
297 : /* empty */
298 {
Steven Morelandd537ab02016-09-12 10:32:01 -0700299 $$ = new std::vector<Annotation *>;
Andreas Huber3599d922016-08-09 10:42:57 -0700300 }
301 | opt_annotations annotation
302 {
303 $$ = $1;
Steven Morelandd537ab02016-09-12 10:32:01 -0700304 $$->push_back($2);
Andreas Huber3599d922016-08-09 10:42:57 -0700305 }
306 ;
307
308annotation
309 : '@' IDENTIFIER opt_annotation_params
310 {
311 $$ = new Annotation($2, $3);
312 }
313 ;
314
315opt_annotation_params
316 : /* empty */
317 {
Steven Morelandd537ab02016-09-12 10:32:01 -0700318 $$ = new AnnotationParamVector;
Andreas Huber3599d922016-08-09 10:42:57 -0700319 }
320 | '(' annotation_params ')'
321 {
322 $$ = $2;
323 }
324 ;
325
326annotation_params
327 : annotation_param
328 {
Steven Morelandd537ab02016-09-12 10:32:01 -0700329 $$ = new AnnotationParamVector;
330 $$->push_back($1);
Andreas Huber3599d922016-08-09 10:42:57 -0700331 }
332 | annotation_params ',' annotation_param
333 {
334 $$ = $1;
Steven Morelandd537ab02016-09-12 10:32:01 -0700335 $$->push_back($3);
Andreas Huber3599d922016-08-09 10:42:57 -0700336 }
337 ;
338
339annotation_param
Yifan Hongf24fa852016-09-23 11:03:15 -0700340 : IDENTIFIER '=' annotation_string_value
341 {
342 $$ = new AnnotationParam($1, $3);
343 }
344 | IDENTIFIER '=' annotation_const_expr_value
Andreas Huber3599d922016-08-09 10:42:57 -0700345 {
Steven Morelandd537ab02016-09-12 10:32:01 -0700346 $$ = new AnnotationParam($1, $3);
Andreas Huber3599d922016-08-09 10:42:57 -0700347 }
348 ;
349
Yifan Hongf24fa852016-09-23 11:03:15 -0700350annotation_string_value
Andreas Huber3599d922016-08-09 10:42:57 -0700351 : STRING_LITERAL
352 {
353 $$ = new std::vector<std::string>;
354 $$->push_back($1);
355 }
356 | '{' annotation_string_values '}' { $$ = $2; }
357 ;
358
359annotation_string_values
360 : STRING_LITERAL
361 {
362 $$ = new std::vector<std::string>;
363 $$->push_back($1);
364 }
365 | annotation_string_values ',' STRING_LITERAL
366 {
367 $$ = $1;
368 $$->push_back($3);
369 }
370 ;
371
Yifan Hongf24fa852016-09-23 11:03:15 -0700372annotation_const_expr_value
373 : const_expr
374 {
375 $$ = new std::vector<ConstantExpression *>;
376 $$->push_back($1);
377 }
378 | '{' annotation_const_expr_values '}' { $$ = $2; }
379 ;
380
381annotation_const_expr_values
382 : const_expr
383 {
384 $$ = new std::vector<ConstantExpression *>;
385 $$->push_back($1);
386 }
387 | annotation_const_expr_values ',' const_expr
388 {
389 $$ = $1;
390 $$->push_back($3);
391 }
392 ;
393
Yifan Hongbe627b32016-10-28 18:38:56 -0700394error_stmt
395 : error ';'
396 {
397 $$ = $1;
398 ast->addSyntaxError();
399 // std::cerr << "WARNING: skipping errors until " << @2 << ".\n";
400 }
401 ;
402
403opt_error_stmt
404 : /* empty */ { $$ = NULL; }
405 | error_stmt { $$ = $1; }
406 ;
407
408require_semicolon
409 : ';'
410 | /* empty */
411 {
412 std::cerr << "ERROR: missing ; at " << @$ << "\n";
413 ast->addSyntaxError();
414 }
415 ;
416
Andreas Huberc9410c72016-07-28 12:18:40 -0700417program
Yifan Hongbe627b32016-10-28 18:38:56 -0700418 : opt_error_stmt
419 package
420 imports
421 body
Andreas Huber84f89de2016-07-28 15:39:51 -0700422 ;
423
424fqname
425 : FQNAME
426 {
Yifan Hongae16eed2016-09-23 13:25:25 -0700427 $$ = new FQName($1);
428 if(!$$->isValid()) {
429 std::cerr << "ERROR: FQName '" << $1 << "' is not valid at "
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700430 << @1
Yifan Hongae16eed2016-09-23 13:25:25 -0700431 << ".\n";
Andreas Huber84f89de2016-07-28 15:39:51 -0700432 YYERROR;
433 }
434 }
Yifan Hong27e85db2016-11-09 15:45:52 -0800435 | valid_identifier
Andreas Huber84f89de2016-07-28 15:39:51 -0700436 {
Yifan Hongae16eed2016-09-23 13:25:25 -0700437 $$ = new FQName($1);
438 if(!$$->isValid()) {
439 std::cerr << "ERROR: FQName '" << $1 << "' is not valid at "
440 << @1
441 << ".\n";
442 YYERROR;
443 }
444 }
445 ;
446
447fqtype
448 : fqname
449 {
450 $$ = ast->lookupType(*($1));
Andreas Huber84f89de2016-07-28 15:39:51 -0700451 if ($$ == NULL) {
Yifan Hongae16eed2016-09-23 13:25:25 -0700452 std::cerr << "ERROR: Failed to lookup type '" << $1->string() << "' at "
453 << @1
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700454 << "\n";
455
Andreas Huber84f89de2016-07-28 15:39:51 -0700456 YYERROR;
457 }
458 }
Hridya Valsarajucd91bf62016-10-25 12:41:04 -0700459 | TYPE
Andreas Huber84f89de2016-07-28 15:39:51 -0700460 ;
Andreas Huberc9410c72016-07-28 12:18:40 -0700461
462package
Yifan Hongbe627b32016-10-28 18:38:56 -0700463 : PACKAGE FQNAME require_semicolon
Andreas Hubereb1081f2016-07-28 13:13:24 -0700464 {
Andreas Huber84f89de2016-07-28 15:39:51 -0700465 if (!ast->setPackage($2)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700466 std::cerr << "ERROR: Malformed package identifier '"
467 << $2
468 << "' at "
469 << @2
470 << "\n";
471
Andreas Huber84f89de2016-07-28 15:39:51 -0700472 YYERROR;
473 }
Andreas Hubereb1081f2016-07-28 13:13:24 -0700474 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700475
Yifan Hongbe627b32016-10-28 18:38:56 -0700476import_stmt
477 : IMPORT FQNAME require_semicolon
478 {
479 if (!ast->addImport($2)) {
480 std::cerr << "ERROR: Unable to import '" << $2 << "' at " << @2
481 << "\n";
482 ast->addSyntaxError();
483 }
484 }
Yifan Hong27e85db2016-11-09 15:45:52 -0800485 | IMPORT valid_identifier require_semicolon
Yifan Hongbe627b32016-10-28 18:38:56 -0700486 {
487 if (!ast->addImport($2)) {
488 std::cerr << "ERROR: Unable to import '" << $2 << "' at " << @2
489 << "\n";
490 ast->addSyntaxError();
491 }
492 }
493 | IMPORT error_stmt
494 ;
495
496
Andreas Huberc9410c72016-07-28 12:18:40 -0700497imports
498 : /* empty */
Yifan Hongbe627b32016-10-28 18:38:56 -0700499 | imports import_stmt
Andreas Huberc9410c72016-07-28 12:18:40 -0700500 ;
501
502opt_extends
503 : /* empty */ { $$ = NULL; }
Yifan Hongae16eed2016-09-23 13:25:25 -0700504 | EXTENDS fqtype { $$ = $2; }
Andreas Huberc9410c72016-07-28 12:18:40 -0700505
506body
Andreas Huber7c5ddfb2016-09-29 13:45:22 -0700507 : type_declarations
Andreas Huberc9410c72016-07-28 12:18:40 -0700508 ;
509
510interface_declarations
511 : /* empty */
512 | interface_declarations type_declaration
Yifan Hong27e85db2016-11-09 15:45:52 -0800513 {
514 std::string errorMsg;
515 if ($2 != nullptr &&
516 $2->isNamedType() &&
517 !isValidInterfaceField(static_cast<NamedType *>($2)->localName().c_str(),
518 &errorMsg)) {
519 std::cerr << "ERROR: " << errorMsg << " at "
520 << @2 << "\n";
521 YYERROR;
522 }
523 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700524 | interface_declarations method_declaration
525 {
Yifan Hong27e85db2016-11-09 15:45:52 -0800526 std::string errorMsg;
527 if ($2 != nullptr &&
528 !isValidInterfaceField($2->name().c_str(), &errorMsg)) {
529 std::cerr << "ERROR: " << errorMsg << " at "
530 << @2 << "\n";
531 YYERROR;
532 }
533
Yifan Hongbe627b32016-10-28 18:38:56 -0700534 if ($2 != nullptr) {
535 if (!ast->scope()->isInterface()) {
536 std::cerr << "ERROR: unknown error in interface declaration at "
537 << @2 << "\n";
538 YYERROR;
539 }
Steven Moreland14ee6742016-10-18 12:58:28 -0700540
Yifan Hongbe627b32016-10-28 18:38:56 -0700541 Interface *iface = static_cast<Interface *>(ast->scope());
542 if (!iface->addMethod($2)) {
543 std::cerr << "ERROR: Unable to add method '" << $2->name()
544 << "' at " << @2 << "\n";
545
546 YYERROR;
547 }
Steven Moreland14ee6742016-10-18 12:58:28 -0700548 }
Yifan Hongbe627b32016-10-28 18:38:56 -0700549 // ignore if $2 is nullptr (from error recovery)
Andreas Huberc9410c72016-07-28 12:18:40 -0700550 }
551 ;
552
553type_declarations
Andreas Hubera2723d22016-07-29 15:36:07 -0700554 : /* empty */
Yifan Hongbe627b32016-10-28 18:38:56 -0700555 | error_stmt
Andreas Huberc9410c72016-07-28 12:18:40 -0700556 | type_declarations type_declaration
557 ;
558
559type_declaration
Andreas Huber7c5ddfb2016-09-29 13:45:22 -0700560 : opt_annotations type_declaration_body
561 {
562 if ($2 != nullptr) {
563 $2->setAnnotations($1);
564 } else if (!$1->empty()) {
565 // Since typedefs are always resolved to their target it makes
566 // little sense to annotate them and have their annotations
567 // impose semantics other than their target type.
568 std::cerr << "ERROR: typedefs cannot be annotated. at " << @2
569 << "\n";
570
571 YYERROR;
572 }
Yifan Hong27e85db2016-11-09 15:45:52 -0800573 $$ = $2;
Andreas Huber7c5ddfb2016-09-29 13:45:22 -0700574 }
575 ;
576
577type_declaration_body
Yifan Hongbe627b32016-10-28 18:38:56 -0700578 : named_struct_or_union_declaration require_semicolon
579 | named_enum_declaration require_semicolon
580 | typedef_declaration require_semicolon
581 | interface_declaration require_semicolon
Andreas Huber7c5ddfb2016-09-29 13:45:22 -0700582 ;
583
584interface_declaration
Yifan Hong27e85db2016-11-09 15:45:52 -0800585 : INTERFACE valid_identifier opt_extends
Andreas Huber7c5ddfb2016-09-29 13:45:22 -0700586 {
Yifan Hongc8934042016-11-17 17:10:52 -0800587 Type *parent = $3;
588
589 if (ast->package() != gIBasePackageFqName) {
590 if (!ast->addImport(gIBaseFqName.string().c_str())) {
591 std::cerr << "ERROR: Unable to automatically import '"
592 << gIBaseFqName.string()
593 << "' at " << @$
594 << "\n";
595 YYERROR;
596 }
597 if (parent == nullptr) {
598 parent = ast->lookupType(gIBaseFqName);
599 }
600 }
601
602 if (parent != NULL && !parent->isInterface()) {
Yifan Hongbe627b32016-10-28 18:38:56 -0700603 std::cerr << "ERROR: You can only extend interfaces. at " << @3
Andreas Huber7c5ddfb2016-09-29 13:45:22 -0700604 << "\n";
605
606 YYERROR;
607 }
608
609 if ($2[0] != 'I') {
610 std::cerr << "ERROR: All interface names must start with an 'I' "
611 << "prefix. at " << @2 << "\n";
612
613 YYERROR;
614 }
615
Yifan Hongc8934042016-11-17 17:10:52 -0800616 Interface *iface = new Interface($2, convertYYLoc(@2), static_cast<Interface *>(parent));
Andreas Huber7c5ddfb2016-09-29 13:45:22 -0700617
618 // Register interface immediately so it can be referenced inside
619 // definition.
620 std::string errorMsg;
621 if (!ast->addScopedType(iface, &errorMsg)) {
622 std::cerr << "ERROR: " << errorMsg << " at " << @2 << "\n";
623 YYERROR;
624 }
625
626 ast->enterScope(iface);
627 }
628 '{' interface_declarations '}'
629 {
Yifan Hongbe627b32016-10-28 18:38:56 -0700630 if (!ast->scope()->isInterface()) {
631 std::cerr << "ERROR: unknown error in interface declaration at "
632 << @5 << "\n";
633 YYERROR;
634 }
635
Andreas Huber7c5ddfb2016-09-29 13:45:22 -0700636 Interface *iface = static_cast<Interface *>(ast->scope());
637
638 ast->leaveScope();
639
640 $$ = iface;
641 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700642 ;
643
644typedef_declaration
Yifan Hong27e85db2016-11-09 15:45:52 -0800645 : TYPEDEF type valid_identifier
Andreas Huberc9410c72016-07-28 12:18:40 -0700646 {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700647 std::string errorMsg;
Yifan Honga4b53d02016-10-31 17:29:10 -0700648 if (!ast->addTypeDef($3, $2, convertYYLoc(@3), &errorMsg)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700649 std::cerr << "ERROR: " << errorMsg << " at " << @3 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700650 YYERROR;
651 }
Andreas Huber7c5ddfb2016-09-29 13:45:22 -0700652
653 $$ = nullptr;
Andreas Huberc9410c72016-07-28 12:18:40 -0700654 }
655 ;
656
Yifan Hong52165692016-08-12 18:06:40 -0700657const_expr
Yifan Hongf24fa852016-09-23 11:03:15 -0700658 : INTEGER { $$ = new ConstantExpression($1); }
Yifan Hongb44a6c82016-09-22 15:50:18 -0700659 | fqname
660 {
Yifan Hongf24fa852016-09-23 11:03:15 -0700661 if(!$1->isValidValueName()) {
662 std::cerr << "ERROR: '" << $1->string()
663 << "' does not refer to an enum value at "
664 << @1 << ".\n";
665 YYERROR;
666 }
667 if($1->isIdentifier()) {
668 std::string identifier = $1->name();
669 LocalIdentifier *iden = ast->scope()->lookupIdentifier(identifier);
670 if(!iden) {
Yifan Hongbe627b32016-10-28 18:38:56 -0700671 std::cerr << "ERROR: identifier " << $1->string()
672 << " could not be found at " << @1 << ".\n";
Yifan Hongf24fa852016-09-23 11:03:15 -0700673 YYERROR;
674 }
675 if(!iden->isEnumValue()) {
Yifan Hongbe627b32016-10-28 18:38:56 -0700676 std::cerr << "ERROR: identifier " << $1->string()
677 << " is not an enum value at " << @1 << ".\n";
Yifan Hongf24fa852016-09-23 11:03:15 -0700678 YYERROR;
679 }
680 $$ = new ConstantExpression(
681 *(static_cast<EnumValue *>(iden)->constExpr()), $1->string());
682 } else {
683 std::string errorMsg;
684 EnumValue *v = ast->lookupEnumValue(*($1), &errorMsg);
685 if(v == nullptr) {
686 std::cerr << "ERROR: " << errorMsg << " at " << @1 << ".\n";
687 YYERROR;
688 }
689 $$ = new ConstantExpression(*(v->constExpr()), $1->string());
690 }
Yifan Hongb44a6c82016-09-22 15:50:18 -0700691 }
Yifan Hong52165692016-08-12 18:06:40 -0700692 | const_expr '?' const_expr ':' const_expr
693 {
Yifan Hongb44a6c82016-09-22 15:50:18 -0700694 $$ = new ConstantExpression($1, $3, $5);
Yifan Hong52165692016-08-12 18:06:40 -0700695 }
696 | const_expr LOGICAL_OR const_expr { $$ = new ConstantExpression($1, "||", $3); }
697 | const_expr LOGICAL_AND const_expr { $$ = new ConstantExpression($1, "&&", $3); }
698 | const_expr '|' const_expr { $$ = new ConstantExpression($1, "|" , $3); }
699 | const_expr '^' const_expr { $$ = new ConstantExpression($1, "^" , $3); }
700 | const_expr '&' const_expr { $$ = new ConstantExpression($1, "&" , $3); }
701 | const_expr EQUALITY const_expr { $$ = new ConstantExpression($1, "==", $3); }
702 | const_expr NEQ const_expr { $$ = new ConstantExpression($1, "!=", $3); }
703 | const_expr '<' const_expr { $$ = new ConstantExpression($1, "<" , $3); }
704 | const_expr '>' const_expr { $$ = new ConstantExpression($1, ">" , $3); }
705 | const_expr LEQ const_expr { $$ = new ConstantExpression($1, "<=", $3); }
706 | const_expr GEQ const_expr { $$ = new ConstantExpression($1, ">=", $3); }
707 | const_expr LSHIFT const_expr { $$ = new ConstantExpression($1, "<<", $3); }
708 | const_expr RSHIFT const_expr { $$ = new ConstantExpression($1, ">>", $3); }
709 | const_expr '+' const_expr { $$ = new ConstantExpression($1, "+" , $3); }
710 | const_expr '-' const_expr { $$ = new ConstantExpression($1, "-" , $3); }
711 | const_expr '*' const_expr { $$ = new ConstantExpression($1, "*" , $3); }
712 | const_expr '/' const_expr { $$ = new ConstantExpression($1, "/" , $3); }
713 | const_expr '%' const_expr { $$ = new ConstantExpression($1, "%" , $3); }
714 | '+' const_expr %prec UNARY_PLUS { $$ = new ConstantExpression("+", $2); }
715 | '-' const_expr %prec UNARY_MINUS { $$ = new ConstantExpression("-", $2); }
716 | '!' const_expr { $$ = new ConstantExpression("!", $2); }
717 | '~' const_expr { $$ = new ConstantExpression("~", $2); }
718 | '(' const_expr ')' { $$ = $2; }
Yifan Hongbe627b32016-10-28 18:38:56 -0700719 | '(' error ')'
720 {
721 ast->addSyntaxError();
722 // to avoid segfaults
723 $$ = new ConstantExpression(ConstantExpression::Zero(ScalarType::KIND_INT32));
724 }
Yifan Hong52165692016-08-12 18:06:40 -0700725 ;
726
Andreas Huberc9410c72016-07-28 12:18:40 -0700727method_declaration
Yifan Hongbe627b32016-10-28 18:38:56 -0700728 : error_stmt { $$ = nullptr; }
Yifan Hong27e85db2016-11-09 15:45:52 -0800729 | opt_annotations valid_identifier '(' typed_vars ')' require_semicolon
Andreas Huberc9410c72016-07-28 12:18:40 -0700730 {
Iliyan Malchev639bff82016-08-13 14:24:11 -0700731 $$ = new Method($2, $4, new std::vector<TypedVar *>, false, $1);
732 }
Yifan Hong27e85db2016-11-09 15:45:52 -0800733 | opt_annotations ONEWAY valid_identifier '(' typed_vars ')' require_semicolon
Iliyan Malchev639bff82016-08-13 14:24:11 -0700734 {
735 $$ = new Method($3, $5, new std::vector<TypedVar *>, true, $1);
Andreas Huberc9410c72016-07-28 12:18:40 -0700736 }
Yifan Hong27e85db2016-11-09 15:45:52 -0800737 | opt_annotations valid_identifier '(' typed_vars ')' GENERATES '(' typed_vars ')' require_semicolon
Andreas Huberc9410c72016-07-28 12:18:40 -0700738 {
Iliyan Malchev639bff82016-08-13 14:24:11 -0700739 $$ = new Method($2, $4, $8, false, $1);
Andreas Huberc9410c72016-07-28 12:18:40 -0700740 }
741 ;
742
743typed_vars
744 : /* empty */
745 {
Andreas Huber881227d2016-08-02 14:20:21 -0700746 $$ = new std::vector<TypedVar *>;
Andreas Huberc9410c72016-07-28 12:18:40 -0700747 }
748 | typed_var
749 {
Andreas Huber881227d2016-08-02 14:20:21 -0700750 $$ = new std::vector<TypedVar *>;
Andreas Huberc9410c72016-07-28 12:18:40 -0700751 $$->push_back($1);
752 }
753 | typed_vars ',' typed_var
754 {
755 $$ = $1;
756 $$->push_back($3);
757 }
758 ;
759
Yifan Hong27e85db2016-11-09 15:45:52 -0800760typed_var : type valid_identifier { $$ = new TypedVar($2, $1); }
Andreas Huberc9410c72016-07-28 12:18:40 -0700761 ;
762
763
764struct_or_union_keyword
765 : STRUCT { $$ = CompoundType::STYLE_STRUCT; }
766 | UNION { $$ = CompoundType::STYLE_UNION; }
767 ;
768
769named_struct_or_union_declaration
Yifan Hong27e85db2016-11-09 15:45:52 -0800770 : struct_or_union_keyword valid_identifier
Andreas Huberc9410c72016-07-28 12:18:40 -0700771 {
Yifan Honga4b53d02016-10-31 17:29:10 -0700772 CompoundType *container = new CompoundType($1, $2, convertYYLoc(@2));
Andreas Huberc9410c72016-07-28 12:18:40 -0700773 ast->enterScope(container);
774 }
775 struct_or_union_body
776 {
Yifan Hongbe627b32016-10-28 18:38:56 -0700777 if (!ast->scope()->isCompoundType()) {
778 std::cerr << "ERROR: unknown error in struct or union declaration at "
779 << @4 << "\n";
780 YYERROR;
781 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700782 CompoundType *container = static_cast<CompoundType *>(ast->scope());
783
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700784 std::string errorMsg;
785 if (!container->setFields($4, &errorMsg)) {
786 std::cerr << "ERROR: " << errorMsg << " at " << @4 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700787 YYERROR;
788 }
789
Andreas Huberc9410c72016-07-28 12:18:40 -0700790 ast->leaveScope();
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700791
Andreas Huber9ed827c2016-08-22 12:31:13 -0700792 if (!ast->addScopedType(container, &errorMsg)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700793 std::cerr << "ERROR: " << errorMsg << " at " << @2 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700794 YYERROR;
795 }
Andreas Huber7c5ddfb2016-09-29 13:45:22 -0700796
797 $$ = container;
Andreas Huberc9410c72016-07-28 12:18:40 -0700798 }
799 ;
800
Andreas Huberc9410c72016-07-28 12:18:40 -0700801struct_or_union_body
802 : '{' field_declarations '}' { $$ = $2; }
803 ;
804
805field_declarations
Andreas Huber881227d2016-08-02 14:20:21 -0700806 : /* empty */ { $$ = new std::vector<CompoundField *>; }
Andreas Huberc9410c72016-07-28 12:18:40 -0700807 | field_declarations field_declaration
808 {
809 $$ = $1;
810
811 if ($2 != NULL) {
812 $$->push_back($2);
813 }
814 }
815 ;
816
817field_declaration
Yifan Hongbe627b32016-10-28 18:38:56 -0700818 : error_stmt { $$ = nullptr; }
Yifan Hong27e85db2016-11-09 15:45:52 -0800819 | type valid_identifier require_semicolon
820 {
821 std::string errorMsg;
822 if (ast->scope()->isCompoundType() &&
823 static_cast<CompoundType *>(ast->scope())->style() == CompoundType::STYLE_STRUCT &&
824 !isValidStructField($2, &errorMsg)) {
825 std::cerr << "ERROR: " << errorMsg << " at "
826 << @2 << "\n";
827 YYERROR;
828 }
829 $$ = new CompoundField($2, $1);
830 }
831 | annotated_compound_declaration ';'
832 {
833 std::string errorMsg;
834 if (ast->scope()->isCompoundType() &&
835 static_cast<CompoundType *>(ast->scope())->style() == CompoundType::STYLE_STRUCT &&
836 $1 != nullptr &&
837 $1->isNamedType() &&
838 !isValidStructField(static_cast<NamedType *>($1)->localName().c_str(), &errorMsg)) {
839 std::cerr << "ERROR: " << errorMsg << " at "
840 << @2 << "\n";
841 YYERROR;
842 }
843 $$ = NULL;
844 }
Andreas Huber7c5ddfb2016-09-29 13:45:22 -0700845 ;
846
847annotated_compound_declaration
848 : opt_annotations compound_declaration
849 {
850 $2->setAnnotations($1);
851 $$ = $2;
852 }
853 ;
854
855compound_declaration
Yifan Honga2855012016-10-11 13:36:54 -0700856 : named_struct_or_union_declaration { $$ = $1; }
Yifan Hong6a2fedf2016-10-11 13:44:07 -0700857 | named_enum_declaration { $$ = $1; }
Andreas Huberc9410c72016-07-28 12:18:40 -0700858 ;
859
Steven Moreland1c71fd52016-11-29 14:03:33 -0800860enum_storage_type
861 : ':' fqtype
Andreas Huber8d3ac0c2016-08-04 14:49:23 -0700862 {
863 $$ = $2;
864
865 if ($$ != NULL && !$$->isValidEnumStorageType()) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700866 std::cerr << "ERROR: Invalid enum storage type specified. at "
867 << @2 << "\n";
868
Yifan Hongbe627b32016-10-28 18:38:56 -0700869 YYERROR;
Andreas Huber8d3ac0c2016-08-04 14:49:23 -0700870 }
871 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700872 ;
873
874opt_comma
875 : /* empty */
876 | ','
877 ;
878
879named_enum_declaration
Steven Moreland1c71fd52016-11-29 14:03:33 -0800880 : ENUM valid_identifier enum_storage_type
Andreas Huberc9410c72016-07-28 12:18:40 -0700881 {
Yifan Honga4b53d02016-10-31 17:29:10 -0700882 ast->enterScope(new EnumType($2, convertYYLoc(@2), $3));
Yifan Hongf24fa852016-09-23 11:03:15 -0700883 }
884 enum_declaration_body
885 {
Yifan Hongbe627b32016-10-28 18:38:56 -0700886 if (!ast->scope()->isEnum()) {
887 std::cerr << "ERROR: unknown error in enum declaration at "
888 << @5 << "\n";
889 YYERROR;
890 }
891
Yifan Hongf24fa852016-09-23 11:03:15 -0700892 EnumType *enumType = static_cast<EnumType *>(ast->scope());
893 ast->leaveScope();
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700894
895 std::string errorMsg;
Andreas Huber9ed827c2016-08-22 12:31:13 -0700896 if (!ast->addScopedType(enumType, &errorMsg)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700897 std::cerr << "ERROR: " << errorMsg << " at " << @2 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700898 YYERROR;
899 }
Andreas Huber7c5ddfb2016-09-29 13:45:22 -0700900
901 $$ = enumType;
Andreas Huberc9410c72016-07-28 12:18:40 -0700902 }
903 ;
904
Yifan Hongf24fa852016-09-23 11:03:15 -0700905enum_declaration_body
906 : '{' enum_values opt_comma '}' { $$ = $2; }
907 ;
908
Andreas Huberc9410c72016-07-28 12:18:40 -0700909enum_value
Yifan Hong27e85db2016-11-09 15:45:52 -0800910 : valid_identifier { $$ = new EnumValue($1); }
911 | valid_identifier '=' const_expr { $$ = new EnumValue($1, $3); }
Andreas Huberc9410c72016-07-28 12:18:40 -0700912 ;
913
914enum_values
915 : /* empty */
Yifan Hongf24fa852016-09-23 11:03:15 -0700916 { /* do nothing */ }
Andreas Huberc9410c72016-07-28 12:18:40 -0700917 | enum_value
918 {
Yifan Hongbe627b32016-10-28 18:38:56 -0700919 if (!ast->scope()->isEnum()) {
920 std::cerr << "ERROR: unknown error in enum declaration at "
921 << @1 << "\n";
922 YYERROR;
923 }
924
Yifan Hongf24fa852016-09-23 11:03:15 -0700925 static_cast<EnumType *>(ast->scope())->addValue($1);
Andreas Huberc9410c72016-07-28 12:18:40 -0700926 }
927 | enum_values ',' enum_value
928 {
Yifan Hongbe627b32016-10-28 18:38:56 -0700929 if (!ast->scope()->isEnum()) {
930 std::cerr << "ERROR: unknown error in enum declaration at "
931 << @3 << "\n";
932 YYERROR;
933 }
934
Yifan Hongf24fa852016-09-23 11:03:15 -0700935 static_cast<EnumType *>(ast->scope())->addValue($3);
Andreas Huberc9410c72016-07-28 12:18:40 -0700936 }
937 ;
938
Yifan Hongbd33e382016-11-02 13:30:17 -0700939array_type_base
Yifan Hongae16eed2016-09-23 13:25:25 -0700940 : fqtype { $$ = $1; }
Yifan Hongbf459bc2016-08-23 16:50:37 -0700941 | TEMPLATED '<' type '>'
Andreas Huberb95ea8a2016-08-15 15:35:42 -0700942 {
Steven Moreland30bb6a82016-11-30 09:18:34 -0800943 if (!$1->isCompatibleElementType($3)) {
944 std::cerr << "ERROR: " << $1->typeName() << " of " << $3->typeName()
945 << " is not supported. at " << @3 << "\n";
Andreas Huber70a59e12016-08-16 12:57:01 -0700946
Andreas Huberb95ea8a2016-08-15 15:35:42 -0700947 YYERROR;
948 }
Yifan Hongbf459bc2016-08-23 16:50:37 -0700949 $1->setElementType($3);
950 $$ = $1;
951 }
952 | TEMPLATED '<' TEMPLATED '<' type RSHIFT
953 {
Steven Moreland30bb6a82016-11-30 09:18:34 -0800954 if (!$3->isCompatibleElementType($5)) {
955 std::cerr << "ERROR: " << $3->typeName() << " of " << $5->typeName()
956 << " is not supported. at " << @3 << "\n";
Andreas Huberb95ea8a2016-08-15 15:35:42 -0700957
Yifan Hongbf459bc2016-08-23 16:50:37 -0700958 YYERROR;
959 }
960 $3->setElementType($5);
Steven Moreland30bb6a82016-11-30 09:18:34 -0800961 if (!$1->isCompatibleElementType($3)) {
962 std::cerr << "ERROR: " << $1->typeName() << " of " << $3->typeName()
963 << " is not supported. at " << @3 << "\n";
964
965 YYERROR;
966 }
Yifan Hongbf459bc2016-08-23 16:50:37 -0700967 $1->setElementType($3);
968 $$ = $1;
Andreas Huberb95ea8a2016-08-15 15:35:42 -0700969 }
Yifan Hongbd33e382016-11-02 13:30:17 -0700970 ;
971
972array_type
973 : array_type_base '[' const_expr ']'
974 {
975 if ($1->isBinder()) {
976 std::cerr << "ERROR: Arrays of interface types are not supported."
977 << " at " << @1 << "\n";
978
979 YYERROR;
980 }
981 if ($1->isArray()) {
982 $$ = new ArrayType(static_cast<ArrayType *>($1), $3);
983 } else {
984 $$ = new ArrayType($1, $3);
985 }
986 }
987 | array_type '[' const_expr ']'
988 {
989 $$ = $1;
990 $$->appendDimension($3);
991 }
992 ;
993
994type
995 : array_type_base { $$ = $1; }
996 | array_type { $$ = $1; }
Andreas Huber7c5ddfb2016-09-29 13:45:22 -0700997 | annotated_compound_declaration { $$ = $1; }
Yifan Hongc8934042016-11-17 17:10:52 -0800998 | INTERFACE
999 {
1000 // "interface" is a synonym of android.hidl.base@1.0::IBase
1001 $$ = ast->lookupType(gIBaseFqName);
1002 if ($$ == nullptr) {
1003 std::cerr << "FATAL: Cannot find "
1004 << gIBaseFqName.string()
1005 << " at " << @1 << "\n";
1006
1007 YYERROR;
1008 }
1009 }
Andreas Huberc9410c72016-07-28 12:18:40 -07001010 ;
1011
Andreas Huberc9410c72016-07-28 12:18:40 -07001012%%
Andreas Huber0d0f9a22016-08-17 10:26:11 -07001013
1014#include <android-base/logging.h>
1015
1016void yy::parser::error(
1017 const yy::parser::location_type &where,
1018 const std::string &errstr) {
1019 std::cerr << "ERROR: " << errstr << " at " << where << "\n";
1020}
1021