blob: 9861914117d513447e90aa630e7b56b81412cb4c [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"
25#include "Interface.h"
Yifan Honga4b53d02016-10-31 17:29:10 -070026#include "Location.h"
Andreas Huberc9410c72016-07-28 12:18:40 -070027#include "Method.h"
Andreas Huberc9410c72016-07-28 12:18:40 -070028#include "VectorType.h"
Yifan Hongbf459bc2016-08-23 16:50:37 -070029#include "RefType.h"
Andreas Huberc9410c72016-07-28 12:18:40 -070030
31#include "hidl-gen_y.h"
32
Andreas Huber709b62d2016-09-19 11:21:18 -070033#include <android-base/logging.h>
Steven Moreland7ae3d542017-01-18 16:46:01 -080034#include <hidl-util/FQName.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",
Steven Morelandf8f2bf32017-01-04 11:58:28 -080055 "castFrom", "Proxy", "Stub",
Yifan Hongb16199d2016-12-09 14:49:46 -080056
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());
Yifan Hongffa91392017-01-31 13:41:23 -0800640 if (!iface->addAllReservedMethods()) {
641 std::cerr << "ERROR: unknown error in adding reserved methods at "
642 << @5 << "\n";
643 YYERROR;
644 }
Andreas Huber7c5ddfb2016-09-29 13:45:22 -0700645
646 ast->leaveScope();
647
648 $$ = iface;
649 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700650 ;
651
652typedef_declaration
Yifan Hong27e85db2016-11-09 15:45:52 -0800653 : TYPEDEF type valid_identifier
Andreas Huberc9410c72016-07-28 12:18:40 -0700654 {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700655 std::string errorMsg;
Yifan Honga4b53d02016-10-31 17:29:10 -0700656 if (!ast->addTypeDef($3, $2, convertYYLoc(@3), &errorMsg)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700657 std::cerr << "ERROR: " << errorMsg << " at " << @3 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700658 YYERROR;
659 }
Andreas Huber7c5ddfb2016-09-29 13:45:22 -0700660
661 $$ = nullptr;
Andreas Huberc9410c72016-07-28 12:18:40 -0700662 }
663 ;
664
Yifan Hong52165692016-08-12 18:06:40 -0700665const_expr
Yifan Hongf24fa852016-09-23 11:03:15 -0700666 : INTEGER { $$ = new ConstantExpression($1); }
Yifan Hongb44a6c82016-09-22 15:50:18 -0700667 | fqname
668 {
Yifan Hongf24fa852016-09-23 11:03:15 -0700669 if(!$1->isValidValueName()) {
670 std::cerr << "ERROR: '" << $1->string()
671 << "' does not refer to an enum value at "
672 << @1 << ".\n";
673 YYERROR;
674 }
675 if($1->isIdentifier()) {
676 std::string identifier = $1->name();
677 LocalIdentifier *iden = ast->scope()->lookupIdentifier(identifier);
678 if(!iden) {
Yifan Hongbe627b32016-10-28 18:38:56 -0700679 std::cerr << "ERROR: identifier " << $1->string()
680 << " could not be found at " << @1 << ".\n";
Yifan Hongf24fa852016-09-23 11:03:15 -0700681 YYERROR;
682 }
683 if(!iden->isEnumValue()) {
Yifan Hongbe627b32016-10-28 18:38:56 -0700684 std::cerr << "ERROR: identifier " << $1->string()
685 << " is not an enum value at " << @1 << ".\n";
Yifan Hongf24fa852016-09-23 11:03:15 -0700686 YYERROR;
687 }
688 $$ = new ConstantExpression(
689 *(static_cast<EnumValue *>(iden)->constExpr()), $1->string());
690 } else {
691 std::string errorMsg;
692 EnumValue *v = ast->lookupEnumValue(*($1), &errorMsg);
693 if(v == nullptr) {
694 std::cerr << "ERROR: " << errorMsg << " at " << @1 << ".\n";
695 YYERROR;
696 }
697 $$ = new ConstantExpression(*(v->constExpr()), $1->string());
698 }
Yifan Hongb44a6c82016-09-22 15:50:18 -0700699 }
Yifan Hong52165692016-08-12 18:06:40 -0700700 | const_expr '?' const_expr ':' const_expr
701 {
Yifan Hongb44a6c82016-09-22 15:50:18 -0700702 $$ = new ConstantExpression($1, $3, $5);
Yifan Hong52165692016-08-12 18:06:40 -0700703 }
704 | const_expr LOGICAL_OR const_expr { $$ = new ConstantExpression($1, "||", $3); }
705 | const_expr LOGICAL_AND 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 '&' const_expr { $$ = new ConstantExpression($1, "&" , $3); }
709 | const_expr EQUALITY const_expr { $$ = new ConstantExpression($1, "==", $3); }
710 | const_expr NEQ 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 LEQ const_expr { $$ = new ConstantExpression($1, "<=", $3); }
714 | const_expr GEQ const_expr { $$ = new ConstantExpression($1, ">=", $3); }
715 | const_expr LSHIFT const_expr { $$ = new ConstantExpression($1, "<<", $3); }
716 | const_expr RSHIFT const_expr { $$ = new ConstantExpression($1, ">>", $3); }
717 | const_expr '+' const_expr { $$ = new ConstantExpression($1, "+" , $3); }
718 | const_expr '-' const_expr { $$ = new ConstantExpression($1, "-" , $3); }
719 | const_expr '*' const_expr { $$ = new ConstantExpression($1, "*" , $3); }
720 | const_expr '/' const_expr { $$ = new ConstantExpression($1, "/" , $3); }
721 | const_expr '%' const_expr { $$ = new ConstantExpression($1, "%" , $3); }
722 | '+' const_expr %prec UNARY_PLUS { $$ = new ConstantExpression("+", $2); }
723 | '-' const_expr %prec UNARY_MINUS { $$ = new ConstantExpression("-", $2); }
724 | '!' const_expr { $$ = new ConstantExpression("!", $2); }
725 | '~' const_expr { $$ = new ConstantExpression("~", $2); }
726 | '(' const_expr ')' { $$ = $2; }
Yifan Hongbe627b32016-10-28 18:38:56 -0700727 | '(' error ')'
728 {
729 ast->addSyntaxError();
730 // to avoid segfaults
731 $$ = new ConstantExpression(ConstantExpression::Zero(ScalarType::KIND_INT32));
732 }
Yifan Hong52165692016-08-12 18:06:40 -0700733 ;
734
Andreas Huberc9410c72016-07-28 12:18:40 -0700735method_declaration
Yifan Hongbe627b32016-10-28 18:38:56 -0700736 : error_stmt { $$ = nullptr; }
Yifan Hong27e85db2016-11-09 15:45:52 -0800737 | opt_annotations valid_identifier '(' typed_vars ')' require_semicolon
Andreas Huberc9410c72016-07-28 12:18:40 -0700738 {
Iliyan Malchev639bff82016-08-13 14:24:11 -0700739 $$ = new Method($2, $4, new std::vector<TypedVar *>, false, $1);
740 }
Yifan Hong27e85db2016-11-09 15:45:52 -0800741 | opt_annotations ONEWAY valid_identifier '(' typed_vars ')' require_semicolon
Iliyan Malchev639bff82016-08-13 14:24:11 -0700742 {
743 $$ = new Method($3, $5, new std::vector<TypedVar *>, true, $1);
Andreas Huberc9410c72016-07-28 12:18:40 -0700744 }
Yifan Hong27e85db2016-11-09 15:45:52 -0800745 | opt_annotations valid_identifier '(' typed_vars ')' GENERATES '(' typed_vars ')' require_semicolon
Andreas Huberc9410c72016-07-28 12:18:40 -0700746 {
Iliyan Malchev639bff82016-08-13 14:24:11 -0700747 $$ = new Method($2, $4, $8, false, $1);
Andreas Huberc9410c72016-07-28 12:18:40 -0700748 }
749 ;
750
751typed_vars
752 : /* empty */
753 {
Yifan Hong7763ab32016-12-13 17:42:11 -0800754 $$ = new TypedVarVector();
Andreas Huberc9410c72016-07-28 12:18:40 -0700755 }
756 | typed_var
757 {
Yifan Hong7763ab32016-12-13 17:42:11 -0800758 $$ = new TypedVarVector();
759 if (!$$->add($1)) {
760 std::cerr << "ERROR: duplicated argument or result name "
761 << $1->name() << " at " << @1 << "\n";
762 ast->addSyntaxError();
763 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700764 }
765 | typed_vars ',' typed_var
766 {
767 $$ = $1;
Yifan Hong7763ab32016-12-13 17:42:11 -0800768 if (!$$->add($3)) {
769 std::cerr << "ERROR: duplicated argument or result name "
770 << $3->name() << " at " << @3 << "\n";
771 ast->addSyntaxError();
772 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700773 }
774 ;
775
Yifan Hong27e85db2016-11-09 15:45:52 -0800776typed_var : type valid_identifier { $$ = new TypedVar($2, $1); }
Andreas Huberc9410c72016-07-28 12:18:40 -0700777 ;
778
779
780struct_or_union_keyword
781 : STRUCT { $$ = CompoundType::STYLE_STRUCT; }
782 | UNION { $$ = CompoundType::STYLE_UNION; }
783 ;
784
785named_struct_or_union_declaration
Yifan Hong27e85db2016-11-09 15:45:52 -0800786 : struct_or_union_keyword valid_identifier
Andreas Huberc9410c72016-07-28 12:18:40 -0700787 {
Yifan Honga4b53d02016-10-31 17:29:10 -0700788 CompoundType *container = new CompoundType($1, $2, convertYYLoc(@2));
Andreas Huberc9410c72016-07-28 12:18:40 -0700789 ast->enterScope(container);
790 }
791 struct_or_union_body
792 {
Yifan Hongbe627b32016-10-28 18:38:56 -0700793 if (!ast->scope()->isCompoundType()) {
794 std::cerr << "ERROR: unknown error in struct or union declaration at "
795 << @4 << "\n";
796 YYERROR;
797 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700798 CompoundType *container = static_cast<CompoundType *>(ast->scope());
799
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700800 std::string errorMsg;
801 if (!container->setFields($4, &errorMsg)) {
802 std::cerr << "ERROR: " << errorMsg << " at " << @4 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700803 YYERROR;
804 }
805
Andreas Huberc9410c72016-07-28 12:18:40 -0700806 ast->leaveScope();
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700807
Andreas Huber9ed827c2016-08-22 12:31:13 -0700808 if (!ast->addScopedType(container, &errorMsg)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700809 std::cerr << "ERROR: " << errorMsg << " at " << @2 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700810 YYERROR;
811 }
Andreas Huber7c5ddfb2016-09-29 13:45:22 -0700812
813 $$ = container;
Andreas Huberc9410c72016-07-28 12:18:40 -0700814 }
815 ;
816
Andreas Huberc9410c72016-07-28 12:18:40 -0700817struct_or_union_body
818 : '{' field_declarations '}' { $$ = $2; }
819 ;
820
821field_declarations
Andreas Huber881227d2016-08-02 14:20:21 -0700822 : /* empty */ { $$ = new std::vector<CompoundField *>; }
Andreas Huberc9410c72016-07-28 12:18:40 -0700823 | field_declarations field_declaration
824 {
825 $$ = $1;
826
827 if ($2 != NULL) {
828 $$->push_back($2);
829 }
830 }
831 ;
832
833field_declaration
Yifan Hongbe627b32016-10-28 18:38:56 -0700834 : error_stmt { $$ = nullptr; }
Yifan Hong27e85db2016-11-09 15:45:52 -0800835 | type valid_identifier require_semicolon
836 {
837 std::string errorMsg;
838 if (ast->scope()->isCompoundType() &&
839 static_cast<CompoundType *>(ast->scope())->style() == CompoundType::STYLE_STRUCT &&
840 !isValidStructField($2, &errorMsg)) {
841 std::cerr << "ERROR: " << errorMsg << " at "
842 << @2 << "\n";
843 YYERROR;
844 }
845 $$ = new CompoundField($2, $1);
846 }
847 | annotated_compound_declaration ';'
848 {
849 std::string errorMsg;
850 if (ast->scope()->isCompoundType() &&
851 static_cast<CompoundType *>(ast->scope())->style() == CompoundType::STYLE_STRUCT &&
852 $1 != nullptr &&
853 $1->isNamedType() &&
854 !isValidStructField(static_cast<NamedType *>($1)->localName().c_str(), &errorMsg)) {
855 std::cerr << "ERROR: " << errorMsg << " at "
856 << @2 << "\n";
857 YYERROR;
858 }
859 $$ = NULL;
860 }
Andreas Huber7c5ddfb2016-09-29 13:45:22 -0700861 ;
862
863annotated_compound_declaration
864 : opt_annotations compound_declaration
865 {
866 $2->setAnnotations($1);
867 $$ = $2;
868 }
869 ;
870
871compound_declaration
Yifan Honga2855012016-10-11 13:36:54 -0700872 : named_struct_or_union_declaration { $$ = $1; }
Yifan Hong6a2fedf2016-10-11 13:44:07 -0700873 | named_enum_declaration { $$ = $1; }
Andreas Huberc9410c72016-07-28 12:18:40 -0700874 ;
875
Steven Moreland1c71fd52016-11-29 14:03:33 -0800876enum_storage_type
877 : ':' fqtype
Andreas Huber8d3ac0c2016-08-04 14:49:23 -0700878 {
879 $$ = $2;
880
881 if ($$ != NULL && !$$->isValidEnumStorageType()) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700882 std::cerr << "ERROR: Invalid enum storage type specified. at "
883 << @2 << "\n";
884
Yifan Hongbe627b32016-10-28 18:38:56 -0700885 YYERROR;
Andreas Huber8d3ac0c2016-08-04 14:49:23 -0700886 }
887 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700888 ;
889
890opt_comma
891 : /* empty */
892 | ','
893 ;
894
895named_enum_declaration
Steven Moreland1c71fd52016-11-29 14:03:33 -0800896 : ENUM valid_identifier enum_storage_type
Andreas Huberc9410c72016-07-28 12:18:40 -0700897 {
Yifan Honga4b53d02016-10-31 17:29:10 -0700898 ast->enterScope(new EnumType($2, convertYYLoc(@2), $3));
Yifan Hongf24fa852016-09-23 11:03:15 -0700899 }
900 enum_declaration_body
901 {
Yifan Hongbe627b32016-10-28 18:38:56 -0700902 if (!ast->scope()->isEnum()) {
903 std::cerr << "ERROR: unknown error in enum declaration at "
904 << @5 << "\n";
905 YYERROR;
906 }
907
Yifan Hongf24fa852016-09-23 11:03:15 -0700908 EnumType *enumType = static_cast<EnumType *>(ast->scope());
909 ast->leaveScope();
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700910
911 std::string errorMsg;
Andreas Huber9ed827c2016-08-22 12:31:13 -0700912 if (!ast->addScopedType(enumType, &errorMsg)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700913 std::cerr << "ERROR: " << errorMsg << " at " << @2 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700914 YYERROR;
915 }
Andreas Huber7c5ddfb2016-09-29 13:45:22 -0700916
917 $$ = enumType;
Andreas Huberc9410c72016-07-28 12:18:40 -0700918 }
919 ;
920
Yifan Hongf24fa852016-09-23 11:03:15 -0700921enum_declaration_body
922 : '{' enum_values opt_comma '}' { $$ = $2; }
923 ;
924
Andreas Huberc9410c72016-07-28 12:18:40 -0700925enum_value
Yifan Hong27e85db2016-11-09 15:45:52 -0800926 : valid_identifier { $$ = new EnumValue($1); }
927 | valid_identifier '=' const_expr { $$ = new EnumValue($1, $3); }
Andreas Huberc9410c72016-07-28 12:18:40 -0700928 ;
929
930enum_values
931 : /* empty */
Yifan Hongf24fa852016-09-23 11:03:15 -0700932 { /* do nothing */ }
Andreas Huberc9410c72016-07-28 12:18:40 -0700933 | enum_value
934 {
Yifan Hongbe627b32016-10-28 18:38:56 -0700935 if (!ast->scope()->isEnum()) {
936 std::cerr << "ERROR: unknown error in enum declaration at "
937 << @1 << "\n";
938 YYERROR;
939 }
940
Yifan Hongf24fa852016-09-23 11:03:15 -0700941 static_cast<EnumType *>(ast->scope())->addValue($1);
Andreas Huberc9410c72016-07-28 12:18:40 -0700942 }
943 | enum_values ',' enum_value
944 {
Yifan Hongbe627b32016-10-28 18:38:56 -0700945 if (!ast->scope()->isEnum()) {
946 std::cerr << "ERROR: unknown error in enum declaration at "
947 << @3 << "\n";
948 YYERROR;
949 }
950
Yifan Hongf24fa852016-09-23 11:03:15 -0700951 static_cast<EnumType *>(ast->scope())->addValue($3);
Andreas Huberc9410c72016-07-28 12:18:40 -0700952 }
953 ;
954
Yifan Hongbd33e382016-11-02 13:30:17 -0700955array_type_base
Yifan Hongae16eed2016-09-23 13:25:25 -0700956 : fqtype { $$ = $1; }
Yifan Hongbf459bc2016-08-23 16:50:37 -0700957 | TEMPLATED '<' type '>'
Andreas Huberb95ea8a2016-08-15 15:35:42 -0700958 {
Steven Moreland30bb6a82016-11-30 09:18:34 -0800959 if (!$1->isCompatibleElementType($3)) {
960 std::cerr << "ERROR: " << $1->typeName() << " of " << $3->typeName()
961 << " is not supported. at " << @3 << "\n";
Andreas Huber70a59e12016-08-16 12:57:01 -0700962
Andreas Huberb95ea8a2016-08-15 15:35:42 -0700963 YYERROR;
964 }
Yifan Hongbf459bc2016-08-23 16:50:37 -0700965 $1->setElementType($3);
966 $$ = $1;
967 }
968 | TEMPLATED '<' TEMPLATED '<' type RSHIFT
969 {
Steven Moreland30bb6a82016-11-30 09:18:34 -0800970 if (!$3->isCompatibleElementType($5)) {
971 std::cerr << "ERROR: " << $3->typeName() << " of " << $5->typeName()
972 << " is not supported. at " << @3 << "\n";
Andreas Huberb95ea8a2016-08-15 15:35:42 -0700973
Yifan Hongbf459bc2016-08-23 16:50:37 -0700974 YYERROR;
975 }
976 $3->setElementType($5);
Steven Moreland30bb6a82016-11-30 09:18:34 -0800977 if (!$1->isCompatibleElementType($3)) {
978 std::cerr << "ERROR: " << $1->typeName() << " of " << $3->typeName()
979 << " is not supported. at " << @3 << "\n";
980
981 YYERROR;
982 }
Yifan Hongbf459bc2016-08-23 16:50:37 -0700983 $1->setElementType($3);
984 $$ = $1;
Andreas Huberb95ea8a2016-08-15 15:35:42 -0700985 }
Yifan Hongbd33e382016-11-02 13:30:17 -0700986 ;
987
988array_type
989 : array_type_base '[' const_expr ']'
990 {
991 if ($1->isBinder()) {
992 std::cerr << "ERROR: Arrays of interface types are not supported."
993 << " at " << @1 << "\n";
994
995 YYERROR;
996 }
997 if ($1->isArray()) {
998 $$ = new ArrayType(static_cast<ArrayType *>($1), $3);
999 } else {
1000 $$ = new ArrayType($1, $3);
1001 }
1002 }
1003 | array_type '[' const_expr ']'
1004 {
1005 $$ = $1;
1006 $$->appendDimension($3);
1007 }
1008 ;
1009
1010type
1011 : array_type_base { $$ = $1; }
1012 | array_type { $$ = $1; }
Andreas Huber7c5ddfb2016-09-29 13:45:22 -07001013 | annotated_compound_declaration { $$ = $1; }
Yifan Hongc8934042016-11-17 17:10:52 -08001014 | INTERFACE
1015 {
1016 // "interface" is a synonym of android.hidl.base@1.0::IBase
1017 $$ = ast->lookupType(gIBaseFqName);
1018 if ($$ == nullptr) {
1019 std::cerr << "FATAL: Cannot find "
1020 << gIBaseFqName.string()
1021 << " at " << @1 << "\n";
1022
1023 YYERROR;
1024 }
1025 }
Andreas Huberc9410c72016-07-28 12:18:40 -07001026 ;
1027
Andreas Huberc9410c72016-07-28 12:18:40 -07001028%%
Andreas Huber0d0f9a22016-08-17 10:26:11 -07001029
1030#include <android-base/logging.h>
1031
1032void yy::parser::error(
1033 const yy::parser::location_type &where,
1034 const std::string &errstr) {
1035 std::cerr << "ERROR: " << errstr << " at " << where << "\n";
1036}
1037