blob: 4548b68d33e8b92ae9af8b7ebf26c2fc9c49ebcc [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 Hongb16199d2016-12-09 14:49:46 -080055 "castFrom", "version", "getInterfaceVersion", "Proxy", "Stub",
56
57 // Inherited methods from IBase is detected in addMethod. Not added here
58 // because we need hidl-gen to compile IBase.
Yifan Hong27e85db2016-11-09 15:45:52 -080059
60 // Inherited names by interfaces from IInterface / IBinder
61 "onAsBinder", "asBinder", "queryLocalInterface", "getInterfaceDescriptor", "isBinderAlive",
Martijn Coenen115d4282016-12-19 05:14:04 +010062 "pingBinder", "dump", "transact", "checkSubclass", "attachObject", "findObject",
63 "detachObject", "localBinder", "remoteBinder", "mImpl",
Yifan Hong27e85db2016-11-09 15:45:52 -080064 });
65 std::string idstr(identifier);
66 if (std::find(reserved.begin(), reserved.end(), idstr) != reserved.end()) {
67 *errorMsg = idstr + " cannot be a name inside an interface";
68 return false;
69 }
70 return true;
71}
72
73bool isValidStructField(const char *identifier, std::string *errorMsg) {
74 static const std::vector<std::string> reserved({
75 // Injected names to structs and unions by auto-generated code
76 "readEmbeddedFromParcel", "writeEmbeddedToParcel", "readVectorFromParcel",
77 "writeVectorToParcel", "writeEmbeddedToBlob",
78 });
79 std::string idstr(identifier);
80 if (std::find(reserved.begin(), reserved.end(), idstr) != reserved.end()) {
81 *errorMsg = idstr + " cannot be a name inside an struct or union";
82 return false;
83 }
84 return true;
85}
86
87bool isValidIdentifier(const char *identifier, std::string *errorMsg) {
88 static const std::vector<std::string> keywords({
89 "uint8_t", "uint16_t", "uint32_t", "uint64_t",
90 "int8_t", "int16_t", "int32_t", "int64_t", "bool", "float", "double",
91 "interface", "struct", "union", "string", "vec", "enum", "ref", "handle",
92 "package", "import", "typedef", "generates", "oneway", "extends",
Hridya Valsarajua32bde82016-12-27 11:47:46 -080093 "fmq_sync", "fmq_unsync",
Yifan Hong27e85db2016-11-09 15:45:52 -080094 });
95 static const std::vector<std::string> cppKeywords({
96 "alignas", "alignof", "and", "and_eq", "asm", "atomic_cancel", "atomic_commit",
97 "atomic_noexcept", "auto", "bitand", "bitor", "bool", "break", "case", "catch",
98 "char", "char16_t", "char32_t", "class", "compl", "concept", "const", "constexpr",
99 "const_cast", "continue", "decltype", "default", "delete", "do", "double",
100 "dynamic_cast", "else", "enum", "explicit", "export", "extern", "false", "float",
101 "for", "friend", "goto", "if", "inline", "int", "import", "long", "module", "mutable",
102 "namespace", "new", "noexcept", "not", "not_eq", "nullptr", "operator", "or", "or_eq",
103 "private", "protected", "public", "register", "reinterpret_cast", "requires", "return",
104 "short", "signed", "sizeof", "static", "static_assert", "static_cast", "struct",
105 "switch", "synchronized", "template", "this", "thread_local", "throw", "true", "try",
106 "typedef", "typeid", "typename", "union", "unsigned", "using", "virtual", "void",
107 "volatile", "wchar_t", "while", "xor", "xor_eq",
108 });
109 static const std::vector<std::string> javaKeywords({
110 "abstract", "continue", "for", "new", "switch", "assert", "default", "goto", "package",
111 "synchronized", "boolean", "do", "if", "private", "this", "break", "double",
112 "implements", "protected", "throw", "byte", "else", "import", "public", "throws",
113 "case", "enum", "instanceof", "return", "transient", "catch", "extends", "int",
114 "short", "try", "char", "final", "interface", "static", "void", "class", "finally",
115 "long", "strictfp", "volatile", "const", "float", "native", "super", "while",
116 });
117 static const std::vector<std::string> cppCollide({
118 "size_t", "offsetof",
Yifan Hong1b023432016-12-11 18:45:06 -0800119 "DECLARE_SERVICE_MANAGER_INTERACTIONS", "IMPLEMENT_HWBINDER_META_INTERFACE",
120 "IMPLEMENT_SERVICE_MANAGER_INTERACTIONS"
Yifan Hong27e85db2016-11-09 15:45:52 -0800121 });
122 static const std::vector<std::string> hidlReserved({
123 // Part of HidlSupport
124 "hidl_string", "hidl_vec", "hidl_array", "hidl_version", "toBinder", "castInterface",
125 "make_hidl_version"
126 });
127
128 // errors
129 std::string idstr(identifier);
130 if (std::find(keywords.begin(), keywords.end(), idstr) != keywords.end()) {
131 *errorMsg = idstr + " is a HIDL keyword "
132 "and is therefore not a valid identifier";
133 return false;
134 }
135 if (std::find(cppKeywords.begin(), cppKeywords.end(), idstr) != cppKeywords.end()) {
136 *errorMsg = idstr + " is a C++ keyword "
137 "and is therefore not a valid identifier";
138 return false;
139 }
140 if (std::find(javaKeywords.begin(), javaKeywords.end(), idstr) != javaKeywords.end()) {
141 *errorMsg = idstr + " is a Java keyword "
142 "and is therefore not a valid identifier";
143 return false;
144 }
145 if (std::find(cppCollide.begin(), cppCollide.end(), idstr) != cppCollide.end()) {
146 *errorMsg = idstr + " collides with reserved names in C++ code "
147 "and is therefore not a valid identifier";
148 return false;
149 }
150 if (StringHelper::StartsWith(idstr, "_hidl_")) {
151 *errorMsg = idstr + " starts with _hidl_ "
152 "and is therefore not a valid identifier";
153 return false;
154 }
155 if (StringHelper::EndsWith(idstr, "_cb")) {
156 *errorMsg = idstr + " ends with _cb "
157 "and is therefore not a valid identifier";
158 return false;
159 }
160
161 // warnings
162 if (std::find(hidlReserved.begin(), hidlReserved.end(), idstr) != hidlReserved.end()) {
163 *errorMsg = idstr + " is a name reserved by HIDL and should be avoided";
164 }
165 return true;
166}
Yifan Honga4b53d02016-10-31 17:29:10 -0700167
Andreas Huberc9410c72016-07-28 12:18:40 -0700168%}
169
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700170%initial-action {
171 // Initialize the initial location.
172 @$.begin.filename = @$.end.filename =
173 const_cast<std::string *>(&ast->getFilename());
174}
175
Andreas Huberc9410c72016-07-28 12:18:40 -0700176%parse-param { android::AST *ast }
177%lex-param { void *scanner }
178%pure-parser
Steven Moreland4ab9b792016-09-26 14:14:07 -0700179%glr-parser
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700180%skeleton "glr.cc"
Andreas Huberc9410c72016-07-28 12:18:40 -0700181
Steven Moreland4ab9b792016-09-26 14:14:07 -0700182%expect-rr 0
183
Andreas Huberc9410c72016-07-28 12:18:40 -0700184%token<str> ENUM
185%token<str> EXTENDS
Andreas Huber84f89de2016-07-28 15:39:51 -0700186%token<str> FQNAME
Andreas Huberc9410c72016-07-28 12:18:40 -0700187%token<str> GENERATES
188%token<str> IDENTIFIER
189%token<str> IMPORT
190%token<str> INTEGER
Yifan Hong52165692016-08-12 18:06:40 -0700191%token<str> FLOAT
Andreas Huberc9410c72016-07-28 12:18:40 -0700192%token<str> INTERFACE
193%token<str> PACKAGE
Hridya Valsarajucd91bf62016-10-25 12:41:04 -0700194%token<type> TYPE
Andreas Huberc9410c72016-07-28 12:18:40 -0700195%token<str> STRUCT
196%token<str> STRING_LITERAL
197%token<str> TYPEDEF
198%token<str> UNION
Yifan Hongbf459bc2016-08-23 16:50:37 -0700199%token<templatedType> TEMPLATED
Iliyan Malchev639bff82016-08-13 14:24:11 -0700200%token<void> ONEWAY
Andreas Huberc9410c72016-07-28 12:18:40 -0700201
Yifan Hong52165692016-08-12 18:06:40 -0700202/* Operator precedence and associativity, as per
203 * http://en.cppreference.com/w/cpp/language/operator_precedence */
204/* Precedence level 15 ternary operator */
205%right '?' ':'
206/* Precedence level 13 - 14, LTR, logical operators*/
207%left LOGICAL_OR
208%left LOGICAL_AND
209/* Precedence level 10 - 12, LTR, bitwise operators*/
210%left '|'
211%left '^'
212%left '&'
213/* Precedence level 9, LTR */
214%left EQUALITY NEQ
215/* Precedence level 8, LTR */
216%left '<' '>' LEQ GEQ
217/* Precedence level 7, LTR */
218%left LSHIFT RSHIFT
219/* Precedence level 6, LTR */
220%left '+' '-'
221/* Precedence level 5, LTR */
222%left '*' '/' '%'
223/* Precedence level 3, RTL; but we have to use %left here */
224%left UNARY_MINUS UNARY_PLUS '!' '~'
225
Yifan Hongbe627b32016-10-28 18:38:56 -0700226%type<str> error_stmt opt_error_stmt error
Yifan Hong6a2fedf2016-10-11 13:44:07 -0700227%type<str> package
Yifan Hongae16eed2016-09-23 13:25:25 -0700228%type<fqName> fqname
229%type<type> fqtype
Yifan Hong27e85db2016-11-09 15:45:52 -0800230%type<str> valid_identifier
Andreas Huberc9410c72016-07-28 12:18:40 -0700231
Steven Moreland1c71fd52016-11-29 14:03:33 -0800232%type<type> type enum_storage_type
Yifan Hongbd33e382016-11-02 13:30:17 -0700233%type<type> array_type_base
234%type<arrayType> array_type
Andreas Huberc9410c72016-07-28 12:18:40 -0700235%type<type> opt_extends
Yifan Hong27e85db2016-11-09 15:45:52 -0800236%type<type> type_declaration type_declaration_body interface_declaration typedef_declaration
Andreas Huber7c5ddfb2016-09-29 13:45:22 -0700237%type<type> named_struct_or_union_declaration named_enum_declaration
238%type<type> compound_declaration annotated_compound_declaration
Andreas Huberc9410c72016-07-28 12:18:40 -0700239
240%type<field> field_declaration
241%type<fields> field_declarations struct_or_union_body
Yifan Hong52165692016-08-12 18:06:40 -0700242%type<constantExpression> const_expr
Andreas Huberc9410c72016-07-28 12:18:40 -0700243%type<enumValue> enum_value
Yifan Hongf24fa852016-09-23 11:03:15 -0700244%type<enumValues> enum_values enum_declaration_body
Andreas Huberc9410c72016-07-28 12:18:40 -0700245%type<typedVars> typed_vars
246%type<typedVar> typed_var
247%type<method> method_declaration
248%type<compoundStyle> struct_or_union_keyword
Yifan Hongf24fa852016-09-23 11:03:15 -0700249%type<stringVec> annotation_string_values annotation_string_value
250%type<constExprVec> annotation_const_expr_values annotation_const_expr_value
Andreas Huber3599d922016-08-09 10:42:57 -0700251%type<annotationParam> annotation_param
252%type<annotationParams> opt_annotation_params annotation_params
253%type<annotation> annotation
254%type<annotations> opt_annotations
Andreas Huberc9410c72016-07-28 12:18:40 -0700255
256%start program
257
258%union {
259 const char *str;
260 android::Type *type;
Yifan Hongbd33e382016-11-02 13:30:17 -0700261 android::ArrayType *arrayType;
Yifan Hongbf459bc2016-08-23 16:50:37 -0700262 android::TemplatedType *templatedType;
Yifan Hongae16eed2016-09-23 13:25:25 -0700263 android::FQName *fqName;
Andreas Huberc9410c72016-07-28 12:18:40 -0700264 android::CompoundType *compoundType;
265 android::CompoundField *field;
Andreas Huber881227d2016-08-02 14:20:21 -0700266 std::vector<android::CompoundField *> *fields;
Andreas Huberc9410c72016-07-28 12:18:40 -0700267 android::EnumValue *enumValue;
Yifan Hong52165692016-08-12 18:06:40 -0700268 android::ConstantExpression *constantExpression;
Andreas Huber881227d2016-08-02 14:20:21 -0700269 std::vector<android::EnumValue *> *enumValues;
Andreas Huberc9410c72016-07-28 12:18:40 -0700270 android::TypedVar *typedVar;
Yifan Hong7763ab32016-12-13 17:42:11 -0800271 android::TypedVarVector *typedVars;
Andreas Huberc9410c72016-07-28 12:18:40 -0700272 android::Method *method;
273 android::CompoundType::Style compoundStyle;
Andreas Huber3599d922016-08-09 10:42:57 -0700274 std::vector<std::string> *stringVec;
Yifan Hongf24fa852016-09-23 11:03:15 -0700275 std::vector<android::ConstantExpression *> *constExprVec;
Steven Morelandd537ab02016-09-12 10:32:01 -0700276 android::AnnotationParam *annotationParam;
277 android::AnnotationParamVector *annotationParams;
Andreas Huber3599d922016-08-09 10:42:57 -0700278 android::Annotation *annotation;
Steven Morelandd537ab02016-09-12 10:32:01 -0700279 std::vector<android::Annotation *> *annotations;
Andreas Huberc9410c72016-07-28 12:18:40 -0700280}
281
282%%
283
Yifan Hong27e85db2016-11-09 15:45:52 -0800284valid_identifier
285 : IDENTIFIER
286 {
287 std::string errorMsg;
288 if (!isValidIdentifier($1, &errorMsg)) {
289 std::cerr << "ERROR: " << errorMsg << " at " << @1 << "\n";
290 YYERROR;
291 }
292 if (!errorMsg.empty()) {
293 std::cerr << "WARNING: " << errorMsg << " at " << @1 << "\n";
294 }
295 $$ = $1;
296 }
297 ;
298
Andreas Huber3599d922016-08-09 10:42:57 -0700299opt_annotations
300 : /* empty */
301 {
Steven Morelandd537ab02016-09-12 10:32:01 -0700302 $$ = new std::vector<Annotation *>;
Andreas Huber3599d922016-08-09 10:42:57 -0700303 }
304 | opt_annotations annotation
305 {
306 $$ = $1;
Steven Morelandd537ab02016-09-12 10:32:01 -0700307 $$->push_back($2);
Andreas Huber3599d922016-08-09 10:42:57 -0700308 }
309 ;
310
311annotation
312 : '@' IDENTIFIER opt_annotation_params
313 {
314 $$ = new Annotation($2, $3);
315 }
316 ;
317
318opt_annotation_params
319 : /* empty */
320 {
Steven Morelandd537ab02016-09-12 10:32:01 -0700321 $$ = new AnnotationParamVector;
Andreas Huber3599d922016-08-09 10:42:57 -0700322 }
323 | '(' annotation_params ')'
324 {
325 $$ = $2;
326 }
327 ;
328
329annotation_params
330 : annotation_param
331 {
Steven Morelandd537ab02016-09-12 10:32:01 -0700332 $$ = new AnnotationParamVector;
333 $$->push_back($1);
Andreas Huber3599d922016-08-09 10:42:57 -0700334 }
335 | annotation_params ',' annotation_param
336 {
337 $$ = $1;
Steven Morelandd537ab02016-09-12 10:32:01 -0700338 $$->push_back($3);
Andreas Huber3599d922016-08-09 10:42:57 -0700339 }
340 ;
341
342annotation_param
Yifan Hongf24fa852016-09-23 11:03:15 -0700343 : IDENTIFIER '=' annotation_string_value
344 {
345 $$ = new AnnotationParam($1, $3);
346 }
347 | IDENTIFIER '=' annotation_const_expr_value
Andreas Huber3599d922016-08-09 10:42:57 -0700348 {
Steven Morelandd537ab02016-09-12 10:32:01 -0700349 $$ = new AnnotationParam($1, $3);
Andreas Huber3599d922016-08-09 10:42:57 -0700350 }
351 ;
352
Yifan Hongf24fa852016-09-23 11:03:15 -0700353annotation_string_value
Andreas Huber3599d922016-08-09 10:42:57 -0700354 : STRING_LITERAL
355 {
356 $$ = new std::vector<std::string>;
357 $$->push_back($1);
358 }
359 | '{' annotation_string_values '}' { $$ = $2; }
360 ;
361
362annotation_string_values
363 : STRING_LITERAL
364 {
365 $$ = new std::vector<std::string>;
366 $$->push_back($1);
367 }
368 | annotation_string_values ',' STRING_LITERAL
369 {
370 $$ = $1;
371 $$->push_back($3);
372 }
373 ;
374
Yifan Hongf24fa852016-09-23 11:03:15 -0700375annotation_const_expr_value
376 : const_expr
377 {
378 $$ = new std::vector<ConstantExpression *>;
379 $$->push_back($1);
380 }
381 | '{' annotation_const_expr_values '}' { $$ = $2; }
382 ;
383
384annotation_const_expr_values
385 : const_expr
386 {
387 $$ = new std::vector<ConstantExpression *>;
388 $$->push_back($1);
389 }
390 | annotation_const_expr_values ',' const_expr
391 {
392 $$ = $1;
393 $$->push_back($3);
394 }
395 ;
396
Yifan Hongbe627b32016-10-28 18:38:56 -0700397error_stmt
398 : error ';'
399 {
400 $$ = $1;
401 ast->addSyntaxError();
402 // std::cerr << "WARNING: skipping errors until " << @2 << ".\n";
403 }
404 ;
405
406opt_error_stmt
407 : /* empty */ { $$ = NULL; }
408 | error_stmt { $$ = $1; }
409 ;
410
411require_semicolon
412 : ';'
413 | /* empty */
414 {
415 std::cerr << "ERROR: missing ; at " << @$ << "\n";
416 ast->addSyntaxError();
417 }
418 ;
419
Andreas Huberc9410c72016-07-28 12:18:40 -0700420program
Yifan Hongbe627b32016-10-28 18:38:56 -0700421 : opt_error_stmt
422 package
423 imports
424 body
Andreas Huber84f89de2016-07-28 15:39:51 -0700425 ;
426
427fqname
428 : FQNAME
429 {
Yifan Hongae16eed2016-09-23 13:25:25 -0700430 $$ = new FQName($1);
431 if(!$$->isValid()) {
432 std::cerr << "ERROR: FQName '" << $1 << "' is not valid at "
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700433 << @1
Yifan Hongae16eed2016-09-23 13:25:25 -0700434 << ".\n";
Andreas Huber84f89de2016-07-28 15:39:51 -0700435 YYERROR;
436 }
437 }
Yifan Hong27e85db2016-11-09 15:45:52 -0800438 | valid_identifier
Andreas Huber84f89de2016-07-28 15:39:51 -0700439 {
Yifan Hongae16eed2016-09-23 13:25:25 -0700440 $$ = new FQName($1);
441 if(!$$->isValid()) {
442 std::cerr << "ERROR: FQName '" << $1 << "' is not valid at "
443 << @1
444 << ".\n";
445 YYERROR;
446 }
447 }
448 ;
449
450fqtype
451 : fqname
452 {
453 $$ = ast->lookupType(*($1));
Andreas Huber84f89de2016-07-28 15:39:51 -0700454 if ($$ == NULL) {
Yifan Hongae16eed2016-09-23 13:25:25 -0700455 std::cerr << "ERROR: Failed to lookup type '" << $1->string() << "' at "
456 << @1
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700457 << "\n";
458
Andreas Huber84f89de2016-07-28 15:39:51 -0700459 YYERROR;
460 }
461 }
Hridya Valsarajucd91bf62016-10-25 12:41:04 -0700462 | TYPE
Andreas Huber84f89de2016-07-28 15:39:51 -0700463 ;
Andreas Huberc9410c72016-07-28 12:18:40 -0700464
465package
Yifan Hongbe627b32016-10-28 18:38:56 -0700466 : PACKAGE FQNAME require_semicolon
Andreas Hubereb1081f2016-07-28 13:13:24 -0700467 {
Andreas Huber84f89de2016-07-28 15:39:51 -0700468 if (!ast->setPackage($2)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700469 std::cerr << "ERROR: Malformed package identifier '"
470 << $2
471 << "' at "
472 << @2
473 << "\n";
474
Andreas Huber84f89de2016-07-28 15:39:51 -0700475 YYERROR;
476 }
Andreas Hubereb1081f2016-07-28 13:13:24 -0700477 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700478
Yifan Hongbe627b32016-10-28 18:38:56 -0700479import_stmt
480 : IMPORT FQNAME require_semicolon
481 {
482 if (!ast->addImport($2)) {
483 std::cerr << "ERROR: Unable to import '" << $2 << "' at " << @2
484 << "\n";
485 ast->addSyntaxError();
486 }
487 }
Yifan Hong27e85db2016-11-09 15:45:52 -0800488 | IMPORT valid_identifier require_semicolon
Yifan Hongbe627b32016-10-28 18:38:56 -0700489 {
490 if (!ast->addImport($2)) {
491 std::cerr << "ERROR: Unable to import '" << $2 << "' at " << @2
492 << "\n";
493 ast->addSyntaxError();
494 }
495 }
496 | IMPORT error_stmt
497 ;
498
499
Andreas Huberc9410c72016-07-28 12:18:40 -0700500imports
501 : /* empty */
Yifan Hongbe627b32016-10-28 18:38:56 -0700502 | imports import_stmt
Andreas Huberc9410c72016-07-28 12:18:40 -0700503 ;
504
505opt_extends
506 : /* empty */ { $$ = NULL; }
Yifan Hongae16eed2016-09-23 13:25:25 -0700507 | EXTENDS fqtype { $$ = $2; }
Andreas Huberc9410c72016-07-28 12:18:40 -0700508
509body
Andreas Huber7c5ddfb2016-09-29 13:45:22 -0700510 : type_declarations
Andreas Huberc9410c72016-07-28 12:18:40 -0700511 ;
512
513interface_declarations
514 : /* empty */
515 | interface_declarations type_declaration
Yifan Hong27e85db2016-11-09 15:45:52 -0800516 {
517 std::string errorMsg;
518 if ($2 != nullptr &&
519 $2->isNamedType() &&
520 !isValidInterfaceField(static_cast<NamedType *>($2)->localName().c_str(),
521 &errorMsg)) {
522 std::cerr << "ERROR: " << errorMsg << " at "
523 << @2 << "\n";
524 YYERROR;
525 }
526 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700527 | interface_declarations method_declaration
528 {
Yifan Hong27e85db2016-11-09 15:45:52 -0800529 std::string errorMsg;
530 if ($2 != nullptr &&
531 !isValidInterfaceField($2->name().c_str(), &errorMsg)) {
532 std::cerr << "ERROR: " << errorMsg << " at "
533 << @2 << "\n";
534 YYERROR;
535 }
536
Yifan Hongbe627b32016-10-28 18:38:56 -0700537 if ($2 != nullptr) {
538 if (!ast->scope()->isInterface()) {
539 std::cerr << "ERROR: unknown error in interface declaration at "
540 << @2 << "\n";
541 YYERROR;
542 }
Steven Moreland14ee6742016-10-18 12:58:28 -0700543
Yifan Hongbe627b32016-10-28 18:38:56 -0700544 Interface *iface = static_cast<Interface *>(ast->scope());
545 if (!iface->addMethod($2)) {
546 std::cerr << "ERROR: Unable to add method '" << $2->name()
547 << "' at " << @2 << "\n";
548
549 YYERROR;
550 }
Steven Moreland14ee6742016-10-18 12:58:28 -0700551 }
Yifan Hongbe627b32016-10-28 18:38:56 -0700552 // ignore if $2 is nullptr (from error recovery)
Andreas Huberc9410c72016-07-28 12:18:40 -0700553 }
554 ;
555
556type_declarations
Andreas Hubera2723d22016-07-29 15:36:07 -0700557 : /* empty */
Yifan Hongbe627b32016-10-28 18:38:56 -0700558 | error_stmt
Andreas Huberc9410c72016-07-28 12:18:40 -0700559 | type_declarations type_declaration
560 ;
561
562type_declaration
Andreas Huber7c5ddfb2016-09-29 13:45:22 -0700563 : opt_annotations type_declaration_body
564 {
565 if ($2 != nullptr) {
566 $2->setAnnotations($1);
567 } else if (!$1->empty()) {
568 // Since typedefs are always resolved to their target it makes
569 // little sense to annotate them and have their annotations
570 // impose semantics other than their target type.
571 std::cerr << "ERROR: typedefs cannot be annotated. at " << @2
572 << "\n";
573
574 YYERROR;
575 }
Yifan Hong27e85db2016-11-09 15:45:52 -0800576 $$ = $2;
Andreas Huber7c5ddfb2016-09-29 13:45:22 -0700577 }
578 ;
579
580type_declaration_body
Yifan Hongbe627b32016-10-28 18:38:56 -0700581 : named_struct_or_union_declaration require_semicolon
582 | named_enum_declaration require_semicolon
583 | typedef_declaration require_semicolon
584 | interface_declaration require_semicolon
Andreas Huber7c5ddfb2016-09-29 13:45:22 -0700585 ;
586
587interface_declaration
Yifan Hong27e85db2016-11-09 15:45:52 -0800588 : INTERFACE valid_identifier opt_extends
Andreas Huber7c5ddfb2016-09-29 13:45:22 -0700589 {
Yifan Hongc8934042016-11-17 17:10:52 -0800590 Type *parent = $3;
591
592 if (ast->package() != gIBasePackageFqName) {
593 if (!ast->addImport(gIBaseFqName.string().c_str())) {
594 std::cerr << "ERROR: Unable to automatically import '"
595 << gIBaseFqName.string()
596 << "' at " << @$
597 << "\n";
598 YYERROR;
599 }
600 if (parent == nullptr) {
601 parent = ast->lookupType(gIBaseFqName);
602 }
603 }
604
605 if (parent != NULL && !parent->isInterface()) {
Yifan Hongbe627b32016-10-28 18:38:56 -0700606 std::cerr << "ERROR: You can only extend interfaces. at " << @3
Andreas Huber7c5ddfb2016-09-29 13:45:22 -0700607 << "\n";
608
609 YYERROR;
610 }
611
612 if ($2[0] != 'I') {
613 std::cerr << "ERROR: All interface names must start with an 'I' "
614 << "prefix. at " << @2 << "\n";
615
616 YYERROR;
617 }
618
Yifan Hongc8934042016-11-17 17:10:52 -0800619 Interface *iface = new Interface($2, convertYYLoc(@2), static_cast<Interface *>(parent));
Andreas Huber7c5ddfb2016-09-29 13:45:22 -0700620
621 // Register interface immediately so it can be referenced inside
622 // definition.
623 std::string errorMsg;
624 if (!ast->addScopedType(iface, &errorMsg)) {
625 std::cerr << "ERROR: " << errorMsg << " at " << @2 << "\n";
626 YYERROR;
627 }
628
629 ast->enterScope(iface);
630 }
631 '{' interface_declarations '}'
632 {
Yifan Hongbe627b32016-10-28 18:38:56 -0700633 if (!ast->scope()->isInterface()) {
634 std::cerr << "ERROR: unknown error in interface declaration at "
635 << @5 << "\n";
636 YYERROR;
637 }
638
Andreas Huber7c5ddfb2016-09-29 13:45:22 -0700639 Interface *iface = static_cast<Interface *>(ast->scope());
640
641 ast->leaveScope();
642
643 $$ = iface;
644 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700645 ;
646
647typedef_declaration
Yifan Hong27e85db2016-11-09 15:45:52 -0800648 : TYPEDEF type valid_identifier
Andreas Huberc9410c72016-07-28 12:18:40 -0700649 {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700650 std::string errorMsg;
Yifan Honga4b53d02016-10-31 17:29:10 -0700651 if (!ast->addTypeDef($3, $2, convertYYLoc(@3), &errorMsg)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700652 std::cerr << "ERROR: " << errorMsg << " at " << @3 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700653 YYERROR;
654 }
Andreas Huber7c5ddfb2016-09-29 13:45:22 -0700655
656 $$ = nullptr;
Andreas Huberc9410c72016-07-28 12:18:40 -0700657 }
658 ;
659
Yifan Hong52165692016-08-12 18:06:40 -0700660const_expr
Yifan Hongf24fa852016-09-23 11:03:15 -0700661 : INTEGER { $$ = new ConstantExpression($1); }
Yifan Hongb44a6c82016-09-22 15:50:18 -0700662 | fqname
663 {
Yifan Hongf24fa852016-09-23 11:03:15 -0700664 if(!$1->isValidValueName()) {
665 std::cerr << "ERROR: '" << $1->string()
666 << "' does not refer to an enum value at "
667 << @1 << ".\n";
668 YYERROR;
669 }
670 if($1->isIdentifier()) {
671 std::string identifier = $1->name();
672 LocalIdentifier *iden = ast->scope()->lookupIdentifier(identifier);
673 if(!iden) {
Yifan Hongbe627b32016-10-28 18:38:56 -0700674 std::cerr << "ERROR: identifier " << $1->string()
675 << " could not be found at " << @1 << ".\n";
Yifan Hongf24fa852016-09-23 11:03:15 -0700676 YYERROR;
677 }
678 if(!iden->isEnumValue()) {
Yifan Hongbe627b32016-10-28 18:38:56 -0700679 std::cerr << "ERROR: identifier " << $1->string()
680 << " is not an enum value at " << @1 << ".\n";
Yifan Hongf24fa852016-09-23 11:03:15 -0700681 YYERROR;
682 }
683 $$ = new ConstantExpression(
684 *(static_cast<EnumValue *>(iden)->constExpr()), $1->string());
685 } else {
686 std::string errorMsg;
687 EnumValue *v = ast->lookupEnumValue(*($1), &errorMsg);
688 if(v == nullptr) {
689 std::cerr << "ERROR: " << errorMsg << " at " << @1 << ".\n";
690 YYERROR;
691 }
692 $$ = new ConstantExpression(*(v->constExpr()), $1->string());
693 }
Yifan Hongb44a6c82016-09-22 15:50:18 -0700694 }
Yifan Hong52165692016-08-12 18:06:40 -0700695 | const_expr '?' const_expr ':' const_expr
696 {
Yifan Hongb44a6c82016-09-22 15:50:18 -0700697 $$ = new ConstantExpression($1, $3, $5);
Yifan Hong52165692016-08-12 18:06:40 -0700698 }
699 | const_expr LOGICAL_OR const_expr { $$ = new ConstantExpression($1, "||", $3); }
700 | const_expr LOGICAL_AND const_expr { $$ = new ConstantExpression($1, "&&", $3); }
701 | const_expr '|' const_expr { $$ = new ConstantExpression($1, "|" , $3); }
702 | const_expr '^' const_expr { $$ = new ConstantExpression($1, "^" , $3); }
703 | const_expr '&' const_expr { $$ = new ConstantExpression($1, "&" , $3); }
704 | const_expr EQUALITY const_expr { $$ = new ConstantExpression($1, "==", $3); }
705 | const_expr NEQ const_expr { $$ = new ConstantExpression($1, "!=", $3); }
706 | const_expr '<' const_expr { $$ = new ConstantExpression($1, "<" , $3); }
707 | const_expr '>' const_expr { $$ = new ConstantExpression($1, ">" , $3); }
708 | const_expr LEQ const_expr { $$ = new ConstantExpression($1, "<=", $3); }
709 | const_expr GEQ const_expr { $$ = new ConstantExpression($1, ">=", $3); }
710 | const_expr LSHIFT const_expr { $$ = new ConstantExpression($1, "<<", $3); }
711 | const_expr RSHIFT 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 '*' const_expr { $$ = new ConstantExpression($1, "*" , $3); }
715 | const_expr '/' const_expr { $$ = new ConstantExpression($1, "/" , $3); }
716 | const_expr '%' const_expr { $$ = new ConstantExpression($1, "%" , $3); }
717 | '+' const_expr %prec UNARY_PLUS { $$ = new ConstantExpression("+", $2); }
718 | '-' const_expr %prec UNARY_MINUS { $$ = new ConstantExpression("-", $2); }
719 | '!' const_expr { $$ = new ConstantExpression("!", $2); }
720 | '~' const_expr { $$ = new ConstantExpression("~", $2); }
721 | '(' const_expr ')' { $$ = $2; }
Yifan Hongbe627b32016-10-28 18:38:56 -0700722 | '(' error ')'
723 {
724 ast->addSyntaxError();
725 // to avoid segfaults
726 $$ = new ConstantExpression(ConstantExpression::Zero(ScalarType::KIND_INT32));
727 }
Yifan Hong52165692016-08-12 18:06:40 -0700728 ;
729
Andreas Huberc9410c72016-07-28 12:18:40 -0700730method_declaration
Yifan Hongbe627b32016-10-28 18:38:56 -0700731 : error_stmt { $$ = nullptr; }
Yifan Hong27e85db2016-11-09 15:45:52 -0800732 | opt_annotations valid_identifier '(' typed_vars ')' require_semicolon
Andreas Huberc9410c72016-07-28 12:18:40 -0700733 {
Iliyan Malchev639bff82016-08-13 14:24:11 -0700734 $$ = new Method($2, $4, new std::vector<TypedVar *>, false, $1);
735 }
Yifan Hong27e85db2016-11-09 15:45:52 -0800736 | opt_annotations ONEWAY valid_identifier '(' typed_vars ')' require_semicolon
Iliyan Malchev639bff82016-08-13 14:24:11 -0700737 {
738 $$ = new Method($3, $5, new std::vector<TypedVar *>, true, $1);
Andreas Huberc9410c72016-07-28 12:18:40 -0700739 }
Yifan Hong27e85db2016-11-09 15:45:52 -0800740 | opt_annotations valid_identifier '(' typed_vars ')' GENERATES '(' typed_vars ')' require_semicolon
Andreas Huberc9410c72016-07-28 12:18:40 -0700741 {
Iliyan Malchev639bff82016-08-13 14:24:11 -0700742 $$ = new Method($2, $4, $8, false, $1);
Andreas Huberc9410c72016-07-28 12:18:40 -0700743 }
744 ;
745
746typed_vars
747 : /* empty */
748 {
Yifan Hong7763ab32016-12-13 17:42:11 -0800749 $$ = new TypedVarVector();
Andreas Huberc9410c72016-07-28 12:18:40 -0700750 }
751 | typed_var
752 {
Yifan Hong7763ab32016-12-13 17:42:11 -0800753 $$ = new TypedVarVector();
754 if (!$$->add($1)) {
755 std::cerr << "ERROR: duplicated argument or result name "
756 << $1->name() << " at " << @1 << "\n";
757 ast->addSyntaxError();
758 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700759 }
760 | typed_vars ',' typed_var
761 {
762 $$ = $1;
Yifan Hong7763ab32016-12-13 17:42:11 -0800763 if (!$$->add($3)) {
764 std::cerr << "ERROR: duplicated argument or result name "
765 << $3->name() << " at " << @3 << "\n";
766 ast->addSyntaxError();
767 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700768 }
769 ;
770
Yifan Hong27e85db2016-11-09 15:45:52 -0800771typed_var : type valid_identifier { $$ = new TypedVar($2, $1); }
Andreas Huberc9410c72016-07-28 12:18:40 -0700772 ;
773
774
775struct_or_union_keyword
776 : STRUCT { $$ = CompoundType::STYLE_STRUCT; }
777 | UNION { $$ = CompoundType::STYLE_UNION; }
778 ;
779
780named_struct_or_union_declaration
Yifan Hong27e85db2016-11-09 15:45:52 -0800781 : struct_or_union_keyword valid_identifier
Andreas Huberc9410c72016-07-28 12:18:40 -0700782 {
Yifan Honga4b53d02016-10-31 17:29:10 -0700783 CompoundType *container = new CompoundType($1, $2, convertYYLoc(@2));
Andreas Huberc9410c72016-07-28 12:18:40 -0700784 ast->enterScope(container);
785 }
786 struct_or_union_body
787 {
Yifan Hongbe627b32016-10-28 18:38:56 -0700788 if (!ast->scope()->isCompoundType()) {
789 std::cerr << "ERROR: unknown error in struct or union declaration at "
790 << @4 << "\n";
791 YYERROR;
792 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700793 CompoundType *container = static_cast<CompoundType *>(ast->scope());
794
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700795 std::string errorMsg;
796 if (!container->setFields($4, &errorMsg)) {
797 std::cerr << "ERROR: " << errorMsg << " at " << @4 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700798 YYERROR;
799 }
800
Andreas Huberc9410c72016-07-28 12:18:40 -0700801 ast->leaveScope();
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700802
Andreas Huber9ed827c2016-08-22 12:31:13 -0700803 if (!ast->addScopedType(container, &errorMsg)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700804 std::cerr << "ERROR: " << errorMsg << " at " << @2 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700805 YYERROR;
806 }
Andreas Huber7c5ddfb2016-09-29 13:45:22 -0700807
808 $$ = container;
Andreas Huberc9410c72016-07-28 12:18:40 -0700809 }
810 ;
811
Andreas Huberc9410c72016-07-28 12:18:40 -0700812struct_or_union_body
813 : '{' field_declarations '}' { $$ = $2; }
814 ;
815
816field_declarations
Andreas Huber881227d2016-08-02 14:20:21 -0700817 : /* empty */ { $$ = new std::vector<CompoundField *>; }
Andreas Huberc9410c72016-07-28 12:18:40 -0700818 | field_declarations field_declaration
819 {
820 $$ = $1;
821
822 if ($2 != NULL) {
823 $$->push_back($2);
824 }
825 }
826 ;
827
828field_declaration
Yifan Hongbe627b32016-10-28 18:38:56 -0700829 : error_stmt { $$ = nullptr; }
Yifan Hong27e85db2016-11-09 15:45:52 -0800830 | type valid_identifier require_semicolon
831 {
832 std::string errorMsg;
833 if (ast->scope()->isCompoundType() &&
834 static_cast<CompoundType *>(ast->scope())->style() == CompoundType::STYLE_STRUCT &&
835 !isValidStructField($2, &errorMsg)) {
836 std::cerr << "ERROR: " << errorMsg << " at "
837 << @2 << "\n";
838 YYERROR;
839 }
840 $$ = new CompoundField($2, $1);
841 }
842 | annotated_compound_declaration ';'
843 {
844 std::string errorMsg;
845 if (ast->scope()->isCompoundType() &&
846 static_cast<CompoundType *>(ast->scope())->style() == CompoundType::STYLE_STRUCT &&
847 $1 != nullptr &&
848 $1->isNamedType() &&
849 !isValidStructField(static_cast<NamedType *>($1)->localName().c_str(), &errorMsg)) {
850 std::cerr << "ERROR: " << errorMsg << " at "
851 << @2 << "\n";
852 YYERROR;
853 }
854 $$ = NULL;
855 }
Andreas Huber7c5ddfb2016-09-29 13:45:22 -0700856 ;
857
858annotated_compound_declaration
859 : opt_annotations compound_declaration
860 {
861 $2->setAnnotations($1);
862 $$ = $2;
863 }
864 ;
865
866compound_declaration
Yifan Honga2855012016-10-11 13:36:54 -0700867 : named_struct_or_union_declaration { $$ = $1; }
Yifan Hong6a2fedf2016-10-11 13:44:07 -0700868 | named_enum_declaration { $$ = $1; }
Andreas Huberc9410c72016-07-28 12:18:40 -0700869 ;
870
Steven Moreland1c71fd52016-11-29 14:03:33 -0800871enum_storage_type
872 : ':' fqtype
Andreas Huber8d3ac0c2016-08-04 14:49:23 -0700873 {
874 $$ = $2;
875
876 if ($$ != NULL && !$$->isValidEnumStorageType()) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700877 std::cerr << "ERROR: Invalid enum storage type specified. at "
878 << @2 << "\n";
879
Yifan Hongbe627b32016-10-28 18:38:56 -0700880 YYERROR;
Andreas Huber8d3ac0c2016-08-04 14:49:23 -0700881 }
882 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700883 ;
884
885opt_comma
886 : /* empty */
887 | ','
888 ;
889
890named_enum_declaration
Steven Moreland1c71fd52016-11-29 14:03:33 -0800891 : ENUM valid_identifier enum_storage_type
Andreas Huberc9410c72016-07-28 12:18:40 -0700892 {
Yifan Honga4b53d02016-10-31 17:29:10 -0700893 ast->enterScope(new EnumType($2, convertYYLoc(@2), $3));
Yifan Hongf24fa852016-09-23 11:03:15 -0700894 }
895 enum_declaration_body
896 {
Yifan Hongbe627b32016-10-28 18:38:56 -0700897 if (!ast->scope()->isEnum()) {
898 std::cerr << "ERROR: unknown error in enum declaration at "
899 << @5 << "\n";
900 YYERROR;
901 }
902
Yifan Hongf24fa852016-09-23 11:03:15 -0700903 EnumType *enumType = static_cast<EnumType *>(ast->scope());
904 ast->leaveScope();
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700905
906 std::string errorMsg;
Andreas Huber9ed827c2016-08-22 12:31:13 -0700907 if (!ast->addScopedType(enumType, &errorMsg)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700908 std::cerr << "ERROR: " << errorMsg << " at " << @2 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700909 YYERROR;
910 }
Andreas Huber7c5ddfb2016-09-29 13:45:22 -0700911
912 $$ = enumType;
Andreas Huberc9410c72016-07-28 12:18:40 -0700913 }
914 ;
915
Yifan Hongf24fa852016-09-23 11:03:15 -0700916enum_declaration_body
917 : '{' enum_values opt_comma '}' { $$ = $2; }
918 ;
919
Andreas Huberc9410c72016-07-28 12:18:40 -0700920enum_value
Yifan Hong27e85db2016-11-09 15:45:52 -0800921 : valid_identifier { $$ = new EnumValue($1); }
922 | valid_identifier '=' const_expr { $$ = new EnumValue($1, $3); }
Andreas Huberc9410c72016-07-28 12:18:40 -0700923 ;
924
925enum_values
926 : /* empty */
Yifan Hongf24fa852016-09-23 11:03:15 -0700927 { /* do nothing */ }
Andreas Huberc9410c72016-07-28 12:18:40 -0700928 | enum_value
929 {
Yifan Hongbe627b32016-10-28 18:38:56 -0700930 if (!ast->scope()->isEnum()) {
931 std::cerr << "ERROR: unknown error in enum declaration at "
932 << @1 << "\n";
933 YYERROR;
934 }
935
Yifan Hongf24fa852016-09-23 11:03:15 -0700936 static_cast<EnumType *>(ast->scope())->addValue($1);
Andreas Huberc9410c72016-07-28 12:18:40 -0700937 }
938 | enum_values ',' enum_value
939 {
Yifan Hongbe627b32016-10-28 18:38:56 -0700940 if (!ast->scope()->isEnum()) {
941 std::cerr << "ERROR: unknown error in enum declaration at "
942 << @3 << "\n";
943 YYERROR;
944 }
945
Yifan Hongf24fa852016-09-23 11:03:15 -0700946 static_cast<EnumType *>(ast->scope())->addValue($3);
Andreas Huberc9410c72016-07-28 12:18:40 -0700947 }
948 ;
949
Yifan Hongbd33e382016-11-02 13:30:17 -0700950array_type_base
Yifan Hongae16eed2016-09-23 13:25:25 -0700951 : fqtype { $$ = $1; }
Yifan Hongbf459bc2016-08-23 16:50:37 -0700952 | TEMPLATED '<' type '>'
Andreas Huberb95ea8a2016-08-15 15:35:42 -0700953 {
Steven Moreland30bb6a82016-11-30 09:18:34 -0800954 if (!$1->isCompatibleElementType($3)) {
955 std::cerr << "ERROR: " << $1->typeName() << " of " << $3->typeName()
956 << " is not supported. at " << @3 << "\n";
Andreas Huber70a59e12016-08-16 12:57:01 -0700957
Andreas Huberb95ea8a2016-08-15 15:35:42 -0700958 YYERROR;
959 }
Yifan Hongbf459bc2016-08-23 16:50:37 -0700960 $1->setElementType($3);
961 $$ = $1;
962 }
963 | TEMPLATED '<' TEMPLATED '<' type RSHIFT
964 {
Steven Moreland30bb6a82016-11-30 09:18:34 -0800965 if (!$3->isCompatibleElementType($5)) {
966 std::cerr << "ERROR: " << $3->typeName() << " of " << $5->typeName()
967 << " is not supported. at " << @3 << "\n";
Andreas Huberb95ea8a2016-08-15 15:35:42 -0700968
Yifan Hongbf459bc2016-08-23 16:50:37 -0700969 YYERROR;
970 }
971 $3->setElementType($5);
Steven Moreland30bb6a82016-11-30 09:18:34 -0800972 if (!$1->isCompatibleElementType($3)) {
973 std::cerr << "ERROR: " << $1->typeName() << " of " << $3->typeName()
974 << " is not supported. at " << @3 << "\n";
975
976 YYERROR;
977 }
Yifan Hongbf459bc2016-08-23 16:50:37 -0700978 $1->setElementType($3);
979 $$ = $1;
Andreas Huberb95ea8a2016-08-15 15:35:42 -0700980 }
Yifan Hongbd33e382016-11-02 13:30:17 -0700981 ;
982
983array_type
984 : array_type_base '[' const_expr ']'
985 {
986 if ($1->isBinder()) {
987 std::cerr << "ERROR: Arrays of interface types are not supported."
988 << " at " << @1 << "\n";
989
990 YYERROR;
991 }
992 if ($1->isArray()) {
993 $$ = new ArrayType(static_cast<ArrayType *>($1), $3);
994 } else {
995 $$ = new ArrayType($1, $3);
996 }
997 }
998 | array_type '[' const_expr ']'
999 {
1000 $$ = $1;
1001 $$->appendDimension($3);
1002 }
1003 ;
1004
1005type
1006 : array_type_base { $$ = $1; }
1007 | array_type { $$ = $1; }
Andreas Huber7c5ddfb2016-09-29 13:45:22 -07001008 | annotated_compound_declaration { $$ = $1; }
Yifan Hongc8934042016-11-17 17:10:52 -08001009 | INTERFACE
1010 {
1011 // "interface" is a synonym of android.hidl.base@1.0::IBase
1012 $$ = ast->lookupType(gIBaseFqName);
1013 if ($$ == nullptr) {
1014 std::cerr << "FATAL: Cannot find "
1015 << gIBaseFqName.string()
1016 << " at " << @1 << "\n";
1017
1018 YYERROR;
1019 }
1020 }
Andreas Huberc9410c72016-07-28 12:18:40 -07001021 ;
1022
Andreas Huberc9410c72016-07-28 12:18:40 -07001023%%
Andreas Huber0d0f9a22016-08-17 10:26:11 -07001024
1025#include <android-base/logging.h>
1026
1027void yy::parser::error(
1028 const yy::parser::location_type &where,
1029 const std::string &errstr) {
1030 std::cerr << "ERROR: " << errstr << " at " << where << "\n";
1031}
1032