blob: fce44a314410b44754dd8fb6a06de495ec9b3782 [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({
Yifan Hongf3d3c732017-05-08 17:27:54 -070053 // Injected names to C++ interfaces by auto-generated code
Yifan Hongc8934042016-11-17 17:10:52 -080054 "isRemote", "descriptor", "hidlStaticBlock", "onTransact",
Yifan Hongf3d3c732017-05-08 17:27:54 -070055 "castFrom", "Proxy", "Stub", "getService",
56
57 // Injected names to Java interfaces by auto-generated code
58 "asInterface", "castFrom", "getService", "toString",
Yifan Hongb16199d2016-12-09 14:49:46 -080059
60 // Inherited methods from IBase is detected in addMethod. Not added here
61 // because we need hidl-gen to compile IBase.
Yifan Hong27e85db2016-11-09 15:45:52 -080062
63 // Inherited names by interfaces from IInterface / IBinder
64 "onAsBinder", "asBinder", "queryLocalInterface", "getInterfaceDescriptor", "isBinderAlive",
Martijn Coenen115d4282016-12-19 05:14:04 +010065 "pingBinder", "dump", "transact", "checkSubclass", "attachObject", "findObject",
66 "detachObject", "localBinder", "remoteBinder", "mImpl",
Yifan Hongf3d3c732017-05-08 17:27:54 -070067
68 // Inherited names from HidlInstrumentor
69 "InstrumentationEvent", "configureInstrumentation", "registerInstrumentationCallbacks",
70 "isInstrumentationLib", "mInstrumentationCal1lbacks", "mEnableInstrumentation",
71 "mInstrumentationLibPackage", "mInterfaceName",
72
73 // Collide with names in BsFoo
74 "mImpl", "addOnewayTask", "mOnewayQueue",
75
76 // Inherited names from Java IHwInterface
77 "asBinder",
Yifan Hong27e85db2016-11-09 15:45:52 -080078 });
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 interface";
82 return false;
83 }
84 return true;
85}
86
87bool isValidStructField(const char *identifier, std::string *errorMsg) {
88 static const std::vector<std::string> reserved({
89 // Injected names to structs and unions by auto-generated code
90 "readEmbeddedFromParcel", "writeEmbeddedToParcel", "readVectorFromParcel",
91 "writeVectorToParcel", "writeEmbeddedToBlob",
92 });
93 std::string idstr(identifier);
94 if (std::find(reserved.begin(), reserved.end(), idstr) != reserved.end()) {
95 *errorMsg = idstr + " cannot be a name inside an struct or union";
96 return false;
97 }
98 return true;
99}
100
101bool isValidIdentifier(const char *identifier, std::string *errorMsg) {
102 static const std::vector<std::string> keywords({
103 "uint8_t", "uint16_t", "uint32_t", "uint64_t",
104 "int8_t", "int16_t", "int32_t", "int64_t", "bool", "float", "double",
105 "interface", "struct", "union", "string", "vec", "enum", "ref", "handle",
106 "package", "import", "typedef", "generates", "oneway", "extends",
Hridya Valsarajua32bde82016-12-27 11:47:46 -0800107 "fmq_sync", "fmq_unsync",
Yifan Hong27e85db2016-11-09 15:45:52 -0800108 });
109 static const std::vector<std::string> cppKeywords({
110 "alignas", "alignof", "and", "and_eq", "asm", "atomic_cancel", "atomic_commit",
111 "atomic_noexcept", "auto", "bitand", "bitor", "bool", "break", "case", "catch",
112 "char", "char16_t", "char32_t", "class", "compl", "concept", "const", "constexpr",
113 "const_cast", "continue", "decltype", "default", "delete", "do", "double",
114 "dynamic_cast", "else", "enum", "explicit", "export", "extern", "false", "float",
115 "for", "friend", "goto", "if", "inline", "int", "import", "long", "module", "mutable",
116 "namespace", "new", "noexcept", "not", "not_eq", "nullptr", "operator", "or", "or_eq",
117 "private", "protected", "public", "register", "reinterpret_cast", "requires", "return",
118 "short", "signed", "sizeof", "static", "static_assert", "static_cast", "struct",
119 "switch", "synchronized", "template", "this", "thread_local", "throw", "true", "try",
120 "typedef", "typeid", "typename", "union", "unsigned", "using", "virtual", "void",
121 "volatile", "wchar_t", "while", "xor", "xor_eq",
122 });
123 static const std::vector<std::string> javaKeywords({
124 "abstract", "continue", "for", "new", "switch", "assert", "default", "goto", "package",
125 "synchronized", "boolean", "do", "if", "private", "this", "break", "double",
126 "implements", "protected", "throw", "byte", "else", "import", "public", "throws",
127 "case", "enum", "instanceof", "return", "transient", "catch", "extends", "int",
128 "short", "try", "char", "final", "interface", "static", "void", "class", "finally",
129 "long", "strictfp", "volatile", "const", "float", "native", "super", "while",
130 });
131 static const std::vector<std::string> cppCollide({
132 "size_t", "offsetof",
Yifan Hong27e85db2016-11-09 15:45:52 -0800133 });
134
135 // errors
136 std::string idstr(identifier);
137 if (std::find(keywords.begin(), keywords.end(), idstr) != keywords.end()) {
138 *errorMsg = idstr + " is a HIDL keyword "
139 "and is therefore not a valid identifier";
140 return false;
141 }
142 if (std::find(cppKeywords.begin(), cppKeywords.end(), idstr) != cppKeywords.end()) {
143 *errorMsg = idstr + " is a C++ keyword "
144 "and is therefore not a valid identifier";
145 return false;
146 }
147 if (std::find(javaKeywords.begin(), javaKeywords.end(), idstr) != javaKeywords.end()) {
148 *errorMsg = idstr + " is a Java keyword "
149 "and is therefore not a valid identifier";
150 return false;
151 }
152 if (std::find(cppCollide.begin(), cppCollide.end(), idstr) != cppCollide.end()) {
153 *errorMsg = idstr + " collides with reserved names in C++ code "
154 "and is therefore not a valid identifier";
155 return false;
156 }
157 if (StringHelper::StartsWith(idstr, "_hidl_")) {
158 *errorMsg = idstr + " starts with _hidl_ "
159 "and is therefore not a valid identifier";
160 return false;
161 }
Yifan Hongf3d3c732017-05-08 17:27:54 -0700162 if (StringHelper::StartsWith(idstr, "hidl_")) {
163 *errorMsg = idstr + " starts with hidl_ "
164 "and is therefore not a valid identifier";
165 return false;
166 }
Yifan Hong27e85db2016-11-09 15:45:52 -0800167 if (StringHelper::EndsWith(idstr, "_cb")) {
168 *errorMsg = idstr + " ends with _cb "
169 "and is therefore not a valid identifier";
170 return false;
171 }
172
Yifan Hongf3d3c732017-05-08 17:27:54 -0700173 return true;
174}
175
176// Return true if identifier is an acceptable name for an UDT.
177bool isValidTypeName(const char *identifier, std::string *errorMsg) {
178 if (!isValidIdentifier(identifier, errorMsg)) {
179 return false;
Yifan Hong27e85db2016-11-09 15:45:52 -0800180 }
Yifan Hongf3d3c732017-05-08 17:27:54 -0700181
182 std::string idstr(identifier);
183 if (idstr == "toString") {
184 *errorMsg = idstr + " is not a valid type name";
185 return false;
186 }
187
Yifan Hong27e85db2016-11-09 15:45:52 -0800188 return true;
189}
Yifan Honga4b53d02016-10-31 17:29:10 -0700190
Andreas Huberc9410c72016-07-28 12:18:40 -0700191%}
192
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700193%initial-action {
194 // Initialize the initial location.
195 @$.begin.filename = @$.end.filename =
196 const_cast<std::string *>(&ast->getFilename());
197}
198
Andreas Huberc9410c72016-07-28 12:18:40 -0700199%parse-param { android::AST *ast }
200%lex-param { void *scanner }
201%pure-parser
Steven Moreland4ab9b792016-09-26 14:14:07 -0700202%glr-parser
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700203%skeleton "glr.cc"
Andreas Huberc9410c72016-07-28 12:18:40 -0700204
Steven Moreland4ab9b792016-09-26 14:14:07 -0700205%expect-rr 0
206
Andreas Huberc9410c72016-07-28 12:18:40 -0700207%token<str> ENUM
208%token<str> EXTENDS
Andreas Huber84f89de2016-07-28 15:39:51 -0700209%token<str> FQNAME
Andreas Huberc9410c72016-07-28 12:18:40 -0700210%token<str> GENERATES
211%token<str> IDENTIFIER
212%token<str> IMPORT
213%token<str> INTEGER
Yifan Hong52165692016-08-12 18:06:40 -0700214%token<str> FLOAT
Andreas Huberc9410c72016-07-28 12:18:40 -0700215%token<str> INTERFACE
216%token<str> PACKAGE
Hridya Valsarajucd91bf62016-10-25 12:41:04 -0700217%token<type> TYPE
Andreas Huberc9410c72016-07-28 12:18:40 -0700218%token<str> STRUCT
219%token<str> STRING_LITERAL
220%token<str> TYPEDEF
221%token<str> UNION
Yifan Hongbf459bc2016-08-23 16:50:37 -0700222%token<templatedType> TEMPLATED
Iliyan Malchev639bff82016-08-13 14:24:11 -0700223%token<void> ONEWAY
Andreas Huberc9410c72016-07-28 12:18:40 -0700224
Yifan Hong52165692016-08-12 18:06:40 -0700225/* Operator precedence and associativity, as per
226 * http://en.cppreference.com/w/cpp/language/operator_precedence */
227/* Precedence level 15 ternary operator */
228%right '?' ':'
229/* Precedence level 13 - 14, LTR, logical operators*/
230%left LOGICAL_OR
231%left LOGICAL_AND
232/* Precedence level 10 - 12, LTR, bitwise operators*/
233%left '|'
234%left '^'
235%left '&'
236/* Precedence level 9, LTR */
237%left EQUALITY NEQ
238/* Precedence level 8, LTR */
239%left '<' '>' LEQ GEQ
240/* Precedence level 7, LTR */
241%left LSHIFT RSHIFT
242/* Precedence level 6, LTR */
243%left '+' '-'
244/* Precedence level 5, LTR */
245%left '*' '/' '%'
246/* Precedence level 3, RTL; but we have to use %left here */
247%left UNARY_MINUS UNARY_PLUS '!' '~'
248
Yifan Hongbe627b32016-10-28 18:38:56 -0700249%type<str> error_stmt opt_error_stmt error
Yifan Hong6a2fedf2016-10-11 13:44:07 -0700250%type<str> package
Yifan Hongae16eed2016-09-23 13:25:25 -0700251%type<fqName> fqname
252%type<type> fqtype
Yifan Hongf3d3c732017-05-08 17:27:54 -0700253%type<str> valid_identifier valid_type_name
Andreas Huberc9410c72016-07-28 12:18:40 -0700254
Steven Moreland1c71fd52016-11-29 14:03:33 -0800255%type<type> type enum_storage_type
Yifan Hongbd33e382016-11-02 13:30:17 -0700256%type<type> array_type_base
257%type<arrayType> array_type
Andreas Huberc9410c72016-07-28 12:18:40 -0700258%type<type> opt_extends
Yifan Hong27e85db2016-11-09 15:45:52 -0800259%type<type> type_declaration type_declaration_body interface_declaration typedef_declaration
Andreas Huber7c5ddfb2016-09-29 13:45:22 -0700260%type<type> named_struct_or_union_declaration named_enum_declaration
261%type<type> compound_declaration annotated_compound_declaration
Andreas Huberc9410c72016-07-28 12:18:40 -0700262
263%type<field> field_declaration
264%type<fields> field_declarations struct_or_union_body
Yifan Hong52165692016-08-12 18:06:40 -0700265%type<constantExpression> const_expr
Andreas Huberc9410c72016-07-28 12:18:40 -0700266%type<enumValue> enum_value
Yifan Hongf24fa852016-09-23 11:03:15 -0700267%type<enumValues> enum_values enum_declaration_body
Andreas Huberc9410c72016-07-28 12:18:40 -0700268%type<typedVars> typed_vars
269%type<typedVar> typed_var
270%type<method> method_declaration
271%type<compoundStyle> struct_or_union_keyword
Yifan Hongf24fa852016-09-23 11:03:15 -0700272%type<stringVec> annotation_string_values annotation_string_value
273%type<constExprVec> annotation_const_expr_values annotation_const_expr_value
Andreas Huber3599d922016-08-09 10:42:57 -0700274%type<annotationParam> annotation_param
275%type<annotationParams> opt_annotation_params annotation_params
276%type<annotation> annotation
277%type<annotations> opt_annotations
Andreas Huberc9410c72016-07-28 12:18:40 -0700278
279%start program
280
281%union {
282 const char *str;
283 android::Type *type;
Yifan Hongbd33e382016-11-02 13:30:17 -0700284 android::ArrayType *arrayType;
Yifan Hongbf459bc2016-08-23 16:50:37 -0700285 android::TemplatedType *templatedType;
Yifan Hongae16eed2016-09-23 13:25:25 -0700286 android::FQName *fqName;
Andreas Huberc9410c72016-07-28 12:18:40 -0700287 android::CompoundType *compoundType;
288 android::CompoundField *field;
Andreas Huber881227d2016-08-02 14:20:21 -0700289 std::vector<android::CompoundField *> *fields;
Andreas Huberc9410c72016-07-28 12:18:40 -0700290 android::EnumValue *enumValue;
Yifan Hong52165692016-08-12 18:06:40 -0700291 android::ConstantExpression *constantExpression;
Andreas Huber881227d2016-08-02 14:20:21 -0700292 std::vector<android::EnumValue *> *enumValues;
Andreas Huberc9410c72016-07-28 12:18:40 -0700293 android::TypedVar *typedVar;
Yifan Hong7763ab32016-12-13 17:42:11 -0800294 android::TypedVarVector *typedVars;
Andreas Huberc9410c72016-07-28 12:18:40 -0700295 android::Method *method;
296 android::CompoundType::Style compoundStyle;
Andreas Huber3599d922016-08-09 10:42:57 -0700297 std::vector<std::string> *stringVec;
Yifan Hongf24fa852016-09-23 11:03:15 -0700298 std::vector<android::ConstantExpression *> *constExprVec;
Steven Morelandd537ab02016-09-12 10:32:01 -0700299 android::AnnotationParam *annotationParam;
300 android::AnnotationParamVector *annotationParams;
Andreas Huber3599d922016-08-09 10:42:57 -0700301 android::Annotation *annotation;
Steven Morelandd537ab02016-09-12 10:32:01 -0700302 std::vector<android::Annotation *> *annotations;
Andreas Huberc9410c72016-07-28 12:18:40 -0700303}
304
305%%
306
Yifan Hong27e85db2016-11-09 15:45:52 -0800307valid_identifier
308 : IDENTIFIER
309 {
310 std::string errorMsg;
311 if (!isValidIdentifier($1, &errorMsg)) {
312 std::cerr << "ERROR: " << errorMsg << " at " << @1 << "\n";
313 YYERROR;
314 }
Yifan Hongf3d3c732017-05-08 17:27:54 -0700315 $$ = $1;
316 }
317 ;
318
319valid_type_name
320 : IDENTIFIER
321 {
322 std::string errorMsg;
323 if (!isValidTypeName($1, &errorMsg)) {
324 std::cerr << "ERROR: " << errorMsg << " at " << @1 << "\n";
325 YYERROR;
Yifan Hong27e85db2016-11-09 15:45:52 -0800326 }
327 $$ = $1;
328 }
329 ;
330
Andreas Huber3599d922016-08-09 10:42:57 -0700331opt_annotations
332 : /* empty */
333 {
Steven Morelandd537ab02016-09-12 10:32:01 -0700334 $$ = new std::vector<Annotation *>;
Andreas Huber3599d922016-08-09 10:42:57 -0700335 }
336 | opt_annotations annotation
337 {
338 $$ = $1;
Steven Morelandd537ab02016-09-12 10:32:01 -0700339 $$->push_back($2);
Andreas Huber3599d922016-08-09 10:42:57 -0700340 }
341 ;
342
343annotation
344 : '@' IDENTIFIER opt_annotation_params
345 {
346 $$ = new Annotation($2, $3);
347 }
348 ;
349
350opt_annotation_params
351 : /* empty */
352 {
Steven Morelandd537ab02016-09-12 10:32:01 -0700353 $$ = new AnnotationParamVector;
Andreas Huber3599d922016-08-09 10:42:57 -0700354 }
355 | '(' annotation_params ')'
356 {
357 $$ = $2;
358 }
359 ;
360
361annotation_params
362 : annotation_param
363 {
Steven Morelandd537ab02016-09-12 10:32:01 -0700364 $$ = new AnnotationParamVector;
365 $$->push_back($1);
Andreas Huber3599d922016-08-09 10:42:57 -0700366 }
367 | annotation_params ',' annotation_param
368 {
369 $$ = $1;
Steven Morelandd537ab02016-09-12 10:32:01 -0700370 $$->push_back($3);
Andreas Huber3599d922016-08-09 10:42:57 -0700371 }
372 ;
373
374annotation_param
Yifan Hongf24fa852016-09-23 11:03:15 -0700375 : IDENTIFIER '=' annotation_string_value
376 {
377 $$ = new AnnotationParam($1, $3);
378 }
379 | IDENTIFIER '=' annotation_const_expr_value
Andreas Huber3599d922016-08-09 10:42:57 -0700380 {
Steven Morelandd537ab02016-09-12 10:32:01 -0700381 $$ = new AnnotationParam($1, $3);
Andreas Huber3599d922016-08-09 10:42:57 -0700382 }
383 ;
384
Yifan Hongf24fa852016-09-23 11:03:15 -0700385annotation_string_value
Andreas Huber3599d922016-08-09 10:42:57 -0700386 : STRING_LITERAL
387 {
388 $$ = new std::vector<std::string>;
389 $$->push_back($1);
390 }
391 | '{' annotation_string_values '}' { $$ = $2; }
392 ;
393
394annotation_string_values
395 : STRING_LITERAL
396 {
397 $$ = new std::vector<std::string>;
398 $$->push_back($1);
399 }
400 | annotation_string_values ',' STRING_LITERAL
401 {
402 $$ = $1;
403 $$->push_back($3);
404 }
405 ;
406
Yifan Hongf24fa852016-09-23 11:03:15 -0700407annotation_const_expr_value
408 : const_expr
409 {
410 $$ = new std::vector<ConstantExpression *>;
411 $$->push_back($1);
412 }
413 | '{' annotation_const_expr_values '}' { $$ = $2; }
414 ;
415
416annotation_const_expr_values
417 : const_expr
418 {
419 $$ = new std::vector<ConstantExpression *>;
420 $$->push_back($1);
421 }
422 | annotation_const_expr_values ',' const_expr
423 {
424 $$ = $1;
425 $$->push_back($3);
426 }
427 ;
428
Yifan Hongbe627b32016-10-28 18:38:56 -0700429error_stmt
430 : error ';'
431 {
432 $$ = $1;
433 ast->addSyntaxError();
434 // std::cerr << "WARNING: skipping errors until " << @2 << ".\n";
435 }
436 ;
437
438opt_error_stmt
439 : /* empty */ { $$ = NULL; }
440 | error_stmt { $$ = $1; }
441 ;
442
443require_semicolon
444 : ';'
445 | /* empty */
446 {
447 std::cerr << "ERROR: missing ; at " << @$ << "\n";
448 ast->addSyntaxError();
449 }
450 ;
451
Andreas Huberc9410c72016-07-28 12:18:40 -0700452program
Yifan Hongbe627b32016-10-28 18:38:56 -0700453 : opt_error_stmt
454 package
455 imports
456 body
Andreas Huber84f89de2016-07-28 15:39:51 -0700457 ;
458
459fqname
460 : FQNAME
461 {
Yifan Hongae16eed2016-09-23 13:25:25 -0700462 $$ = new FQName($1);
463 if(!$$->isValid()) {
464 std::cerr << "ERROR: FQName '" << $1 << "' is not valid at "
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700465 << @1
Yifan Hongae16eed2016-09-23 13:25:25 -0700466 << ".\n";
Andreas Huber84f89de2016-07-28 15:39:51 -0700467 YYERROR;
468 }
469 }
Yifan Hongf3d3c732017-05-08 17:27:54 -0700470 | valid_type_name
Andreas Huber84f89de2016-07-28 15:39:51 -0700471 {
Yifan Hongae16eed2016-09-23 13:25:25 -0700472 $$ = new FQName($1);
473 if(!$$->isValid()) {
474 std::cerr << "ERROR: FQName '" << $1 << "' is not valid at "
475 << @1
476 << ".\n";
477 YYERROR;
478 }
479 }
480 ;
481
482fqtype
483 : fqname
484 {
485 $$ = ast->lookupType(*($1));
Andreas Huber84f89de2016-07-28 15:39:51 -0700486 if ($$ == NULL) {
Yifan Hongae16eed2016-09-23 13:25:25 -0700487 std::cerr << "ERROR: Failed to lookup type '" << $1->string() << "' at "
488 << @1
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700489 << "\n";
490
Andreas Huber84f89de2016-07-28 15:39:51 -0700491 YYERROR;
492 }
493 }
Hridya Valsarajucd91bf62016-10-25 12:41:04 -0700494 | TYPE
Andreas Huber84f89de2016-07-28 15:39:51 -0700495 ;
Andreas Huberc9410c72016-07-28 12:18:40 -0700496
497package
Yifan Hongbe627b32016-10-28 18:38:56 -0700498 : PACKAGE FQNAME require_semicolon
Andreas Hubereb1081f2016-07-28 13:13:24 -0700499 {
Andreas Huber84f89de2016-07-28 15:39:51 -0700500 if (!ast->setPackage($2)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700501 std::cerr << "ERROR: Malformed package identifier '"
502 << $2
503 << "' at "
504 << @2
505 << "\n";
506
Andreas Huber84f89de2016-07-28 15:39:51 -0700507 YYERROR;
508 }
Andreas Hubereb1081f2016-07-28 13:13:24 -0700509 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700510
Yifan Hongbe627b32016-10-28 18:38:56 -0700511import_stmt
512 : IMPORT FQNAME require_semicolon
513 {
514 if (!ast->addImport($2)) {
515 std::cerr << "ERROR: Unable to import '" << $2 << "' at " << @2
516 << "\n";
517 ast->addSyntaxError();
518 }
519 }
Yifan Hongf3d3c732017-05-08 17:27:54 -0700520 | IMPORT valid_type_name require_semicolon
Yifan Hongbe627b32016-10-28 18:38:56 -0700521 {
522 if (!ast->addImport($2)) {
523 std::cerr << "ERROR: Unable to import '" << $2 << "' at " << @2
524 << "\n";
525 ast->addSyntaxError();
526 }
527 }
528 | IMPORT error_stmt
529 ;
530
531
Andreas Huberc9410c72016-07-28 12:18:40 -0700532imports
533 : /* empty */
Yifan Hongbe627b32016-10-28 18:38:56 -0700534 | imports import_stmt
Andreas Huberc9410c72016-07-28 12:18:40 -0700535 ;
536
537opt_extends
538 : /* empty */ { $$ = NULL; }
Yifan Hongae16eed2016-09-23 13:25:25 -0700539 | EXTENDS fqtype { $$ = $2; }
Andreas Huberc9410c72016-07-28 12:18:40 -0700540
541body
Andreas Huber7c5ddfb2016-09-29 13:45:22 -0700542 : type_declarations
Andreas Huberc9410c72016-07-28 12:18:40 -0700543 ;
544
545interface_declarations
546 : /* empty */
547 | interface_declarations type_declaration
Yifan Hong27e85db2016-11-09 15:45:52 -0800548 {
549 std::string errorMsg;
550 if ($2 != nullptr &&
551 $2->isNamedType() &&
552 !isValidInterfaceField(static_cast<NamedType *>($2)->localName().c_str(),
553 &errorMsg)) {
554 std::cerr << "ERROR: " << errorMsg << " at "
555 << @2 << "\n";
556 YYERROR;
557 }
558 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700559 | interface_declarations method_declaration
560 {
Yifan Hong27e85db2016-11-09 15:45:52 -0800561 std::string errorMsg;
562 if ($2 != nullptr &&
563 !isValidInterfaceField($2->name().c_str(), &errorMsg)) {
564 std::cerr << "ERROR: " << errorMsg << " at "
565 << @2 << "\n";
566 YYERROR;
567 }
568
Yifan Hongbe627b32016-10-28 18:38:56 -0700569 if ($2 != nullptr) {
570 if (!ast->scope()->isInterface()) {
571 std::cerr << "ERROR: unknown error in interface declaration at "
572 << @2 << "\n";
573 YYERROR;
574 }
Steven Moreland14ee6742016-10-18 12:58:28 -0700575
Yifan Hongbe627b32016-10-28 18:38:56 -0700576 Interface *iface = static_cast<Interface *>(ast->scope());
577 if (!iface->addMethod($2)) {
578 std::cerr << "ERROR: Unable to add method '" << $2->name()
579 << "' at " << @2 << "\n";
580
581 YYERROR;
582 }
Steven Moreland14ee6742016-10-18 12:58:28 -0700583 }
Yifan Hongbe627b32016-10-28 18:38:56 -0700584 // ignore if $2 is nullptr (from error recovery)
Andreas Huberc9410c72016-07-28 12:18:40 -0700585 }
586 ;
587
588type_declarations
Andreas Hubera2723d22016-07-29 15:36:07 -0700589 : /* empty */
Yifan Hongbe627b32016-10-28 18:38:56 -0700590 | error_stmt
Andreas Huberc9410c72016-07-28 12:18:40 -0700591 | type_declarations type_declaration
592 ;
593
594type_declaration
Andreas Huber7c5ddfb2016-09-29 13:45:22 -0700595 : opt_annotations type_declaration_body
596 {
597 if ($2 != nullptr) {
598 $2->setAnnotations($1);
599 } else if (!$1->empty()) {
600 // Since typedefs are always resolved to their target it makes
601 // little sense to annotate them and have their annotations
602 // impose semantics other than their target type.
603 std::cerr << "ERROR: typedefs cannot be annotated. at " << @2
604 << "\n";
605
606 YYERROR;
607 }
Yifan Hong27e85db2016-11-09 15:45:52 -0800608 $$ = $2;
Andreas Huber7c5ddfb2016-09-29 13:45:22 -0700609 }
610 ;
611
612type_declaration_body
Yifan Hongbe627b32016-10-28 18:38:56 -0700613 : named_struct_or_union_declaration require_semicolon
614 | named_enum_declaration require_semicolon
615 | typedef_declaration require_semicolon
616 | interface_declaration require_semicolon
Andreas Huber7c5ddfb2016-09-29 13:45:22 -0700617 ;
618
619interface_declaration
Yifan Hongf3d3c732017-05-08 17:27:54 -0700620 : INTERFACE valid_type_name opt_extends
Andreas Huber7c5ddfb2016-09-29 13:45:22 -0700621 {
Yifan Hongc8934042016-11-17 17:10:52 -0800622 Type *parent = $3;
623
624 if (ast->package() != gIBasePackageFqName) {
625 if (!ast->addImport(gIBaseFqName.string().c_str())) {
626 std::cerr << "ERROR: Unable to automatically import '"
627 << gIBaseFqName.string()
628 << "' at " << @$
629 << "\n";
630 YYERROR;
631 }
632 if (parent == nullptr) {
633 parent = ast->lookupType(gIBaseFqName);
634 }
635 }
636
637 if (parent != NULL && !parent->isInterface()) {
Yifan Hongbe627b32016-10-28 18:38:56 -0700638 std::cerr << "ERROR: You can only extend interfaces. at " << @3
Andreas Huber7c5ddfb2016-09-29 13:45:22 -0700639 << "\n";
640
641 YYERROR;
642 }
643
644 if ($2[0] != 'I') {
645 std::cerr << "ERROR: All interface names must start with an 'I' "
646 << "prefix. at " << @2 << "\n";
647
648 YYERROR;
649 }
650
Yifan Hongc8934042016-11-17 17:10:52 -0800651 Interface *iface = new Interface($2, convertYYLoc(@2), static_cast<Interface *>(parent));
Andreas Huber7c5ddfb2016-09-29 13:45:22 -0700652
653 // Register interface immediately so it can be referenced inside
654 // definition.
655 std::string errorMsg;
656 if (!ast->addScopedType(iface, &errorMsg)) {
657 std::cerr << "ERROR: " << errorMsg << " at " << @2 << "\n";
658 YYERROR;
659 }
660
661 ast->enterScope(iface);
662 }
663 '{' interface_declarations '}'
664 {
Yifan Hongbe627b32016-10-28 18:38:56 -0700665 if (!ast->scope()->isInterface()) {
666 std::cerr << "ERROR: unknown error in interface declaration at "
667 << @5 << "\n";
668 YYERROR;
669 }
670
Andreas Huber7c5ddfb2016-09-29 13:45:22 -0700671 Interface *iface = static_cast<Interface *>(ast->scope());
Yifan Hongffa91392017-01-31 13:41:23 -0800672 if (!iface->addAllReservedMethods()) {
673 std::cerr << "ERROR: unknown error in adding reserved methods at "
674 << @5 << "\n";
675 YYERROR;
676 }
Andreas Huber7c5ddfb2016-09-29 13:45:22 -0700677
678 ast->leaveScope();
679
680 $$ = iface;
681 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700682 ;
683
684typedef_declaration
Yifan Hongf3d3c732017-05-08 17:27:54 -0700685 : TYPEDEF type valid_type_name
Andreas Huberc9410c72016-07-28 12:18:40 -0700686 {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700687 std::string errorMsg;
Yifan Honga4b53d02016-10-31 17:29:10 -0700688 if (!ast->addTypeDef($3, $2, convertYYLoc(@3), &errorMsg)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700689 std::cerr << "ERROR: " << errorMsg << " at " << @3 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700690 YYERROR;
691 }
Andreas Huber7c5ddfb2016-09-29 13:45:22 -0700692
693 $$ = nullptr;
Andreas Huberc9410c72016-07-28 12:18:40 -0700694 }
695 ;
696
Yifan Hong52165692016-08-12 18:06:40 -0700697const_expr
Yifan Hongf24fa852016-09-23 11:03:15 -0700698 : INTEGER { $$ = new ConstantExpression($1); }
Yifan Hongb44a6c82016-09-22 15:50:18 -0700699 | fqname
700 {
Yifan Hongf24fa852016-09-23 11:03:15 -0700701 if(!$1->isValidValueName()) {
702 std::cerr << "ERROR: '" << $1->string()
703 << "' does not refer to an enum value at "
704 << @1 << ".\n";
705 YYERROR;
706 }
707 if($1->isIdentifier()) {
708 std::string identifier = $1->name();
709 LocalIdentifier *iden = ast->scope()->lookupIdentifier(identifier);
710 if(!iden) {
Yifan Hongbe627b32016-10-28 18:38:56 -0700711 std::cerr << "ERROR: identifier " << $1->string()
712 << " could not be found at " << @1 << ".\n";
Yifan Hongf24fa852016-09-23 11:03:15 -0700713 YYERROR;
714 }
715 if(!iden->isEnumValue()) {
Yifan Hongbe627b32016-10-28 18:38:56 -0700716 std::cerr << "ERROR: identifier " << $1->string()
717 << " is not an enum value at " << @1 << ".\n";
Yifan Hongf24fa852016-09-23 11:03:15 -0700718 YYERROR;
719 }
720 $$ = new ConstantExpression(
721 *(static_cast<EnumValue *>(iden)->constExpr()), $1->string());
722 } else {
723 std::string errorMsg;
724 EnumValue *v = ast->lookupEnumValue(*($1), &errorMsg);
725 if(v == nullptr) {
726 std::cerr << "ERROR: " << errorMsg << " at " << @1 << ".\n";
727 YYERROR;
728 }
729 $$ = new ConstantExpression(*(v->constExpr()), $1->string());
730 }
Yifan Hongb44a6c82016-09-22 15:50:18 -0700731 }
Yifan Hong52165692016-08-12 18:06:40 -0700732 | const_expr '?' const_expr ':' const_expr
733 {
Yifan Hongb44a6c82016-09-22 15:50:18 -0700734 $$ = new ConstantExpression($1, $3, $5);
Yifan Hong52165692016-08-12 18:06:40 -0700735 }
736 | const_expr LOGICAL_OR const_expr { $$ = new ConstantExpression($1, "||", $3); }
737 | const_expr LOGICAL_AND const_expr { $$ = new ConstantExpression($1, "&&", $3); }
738 | const_expr '|' const_expr { $$ = new ConstantExpression($1, "|" , $3); }
739 | const_expr '^' const_expr { $$ = new ConstantExpression($1, "^" , $3); }
740 | const_expr '&' const_expr { $$ = new ConstantExpression($1, "&" , $3); }
741 | const_expr EQUALITY const_expr { $$ = new ConstantExpression($1, "==", $3); }
742 | const_expr NEQ const_expr { $$ = new ConstantExpression($1, "!=", $3); }
743 | const_expr '<' const_expr { $$ = new ConstantExpression($1, "<" , $3); }
744 | const_expr '>' const_expr { $$ = new ConstantExpression($1, ">" , $3); }
745 | const_expr LEQ const_expr { $$ = new ConstantExpression($1, "<=", $3); }
746 | const_expr GEQ const_expr { $$ = new ConstantExpression($1, ">=", $3); }
747 | const_expr LSHIFT const_expr { $$ = new ConstantExpression($1, "<<", $3); }
748 | const_expr RSHIFT const_expr { $$ = new ConstantExpression($1, ">>", $3); }
749 | const_expr '+' const_expr { $$ = new ConstantExpression($1, "+" , $3); }
750 | const_expr '-' const_expr { $$ = new ConstantExpression($1, "-" , $3); }
751 | const_expr '*' const_expr { $$ = new ConstantExpression($1, "*" , $3); }
752 | const_expr '/' const_expr { $$ = new ConstantExpression($1, "/" , $3); }
753 | const_expr '%' const_expr { $$ = new ConstantExpression($1, "%" , $3); }
754 | '+' const_expr %prec UNARY_PLUS { $$ = new ConstantExpression("+", $2); }
755 | '-' const_expr %prec UNARY_MINUS { $$ = new ConstantExpression("-", $2); }
756 | '!' const_expr { $$ = new ConstantExpression("!", $2); }
757 | '~' const_expr { $$ = new ConstantExpression("~", $2); }
758 | '(' const_expr ')' { $$ = $2; }
Yifan Hongbe627b32016-10-28 18:38:56 -0700759 | '(' error ')'
760 {
761 ast->addSyntaxError();
762 // to avoid segfaults
763 $$ = new ConstantExpression(ConstantExpression::Zero(ScalarType::KIND_INT32));
764 }
Yifan Hong52165692016-08-12 18:06:40 -0700765 ;
766
Andreas Huberc9410c72016-07-28 12:18:40 -0700767method_declaration
Yifan Hongbe627b32016-10-28 18:38:56 -0700768 : error_stmt { $$ = nullptr; }
Yifan Hong27e85db2016-11-09 15:45:52 -0800769 | opt_annotations valid_identifier '(' typed_vars ')' require_semicolon
Andreas Huberc9410c72016-07-28 12:18:40 -0700770 {
Iliyan Malchev639bff82016-08-13 14:24:11 -0700771 $$ = new Method($2, $4, new std::vector<TypedVar *>, false, $1);
772 }
Yifan Hong27e85db2016-11-09 15:45:52 -0800773 | opt_annotations ONEWAY valid_identifier '(' typed_vars ')' require_semicolon
Iliyan Malchev639bff82016-08-13 14:24:11 -0700774 {
775 $$ = new Method($3, $5, new std::vector<TypedVar *>, true, $1);
Andreas Huberc9410c72016-07-28 12:18:40 -0700776 }
Yifan Hong27e85db2016-11-09 15:45:52 -0800777 | opt_annotations valid_identifier '(' typed_vars ')' GENERATES '(' typed_vars ')' require_semicolon
Andreas Huberc9410c72016-07-28 12:18:40 -0700778 {
Iliyan Malchev639bff82016-08-13 14:24:11 -0700779 $$ = new Method($2, $4, $8, false, $1);
Andreas Huberc9410c72016-07-28 12:18:40 -0700780 }
781 ;
782
783typed_vars
784 : /* empty */
785 {
Yifan Hong7763ab32016-12-13 17:42:11 -0800786 $$ = new TypedVarVector();
Andreas Huberc9410c72016-07-28 12:18:40 -0700787 }
788 | typed_var
789 {
Yifan Hong7763ab32016-12-13 17:42:11 -0800790 $$ = new TypedVarVector();
791 if (!$$->add($1)) {
792 std::cerr << "ERROR: duplicated argument or result name "
793 << $1->name() << " at " << @1 << "\n";
794 ast->addSyntaxError();
795 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700796 }
797 | typed_vars ',' typed_var
798 {
799 $$ = $1;
Yifan Hong7763ab32016-12-13 17:42:11 -0800800 if (!$$->add($3)) {
801 std::cerr << "ERROR: duplicated argument or result name "
802 << $3->name() << " at " << @3 << "\n";
803 ast->addSyntaxError();
804 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700805 }
806 ;
807
Yifan Hong27e85db2016-11-09 15:45:52 -0800808typed_var : type valid_identifier { $$ = new TypedVar($2, $1); }
Andreas Huberc9410c72016-07-28 12:18:40 -0700809 ;
810
811
812struct_or_union_keyword
813 : STRUCT { $$ = CompoundType::STYLE_STRUCT; }
814 | UNION { $$ = CompoundType::STYLE_UNION; }
815 ;
816
817named_struct_or_union_declaration
Yifan Hongf3d3c732017-05-08 17:27:54 -0700818 : struct_or_union_keyword valid_type_name
Andreas Huberc9410c72016-07-28 12:18:40 -0700819 {
Yifan Honga4b53d02016-10-31 17:29:10 -0700820 CompoundType *container = new CompoundType($1, $2, convertYYLoc(@2));
Andreas Huberc9410c72016-07-28 12:18:40 -0700821 ast->enterScope(container);
822 }
823 struct_or_union_body
824 {
Yifan Hongbe627b32016-10-28 18:38:56 -0700825 if (!ast->scope()->isCompoundType()) {
826 std::cerr << "ERROR: unknown error in struct or union declaration at "
827 << @4 << "\n";
828 YYERROR;
829 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700830 CompoundType *container = static_cast<CompoundType *>(ast->scope());
831
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700832 std::string errorMsg;
833 if (!container->setFields($4, &errorMsg)) {
834 std::cerr << "ERROR: " << errorMsg << " at " << @4 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700835 YYERROR;
836 }
837
Andreas Huberc9410c72016-07-28 12:18:40 -0700838 ast->leaveScope();
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700839
Andreas Huber9ed827c2016-08-22 12:31:13 -0700840 if (!ast->addScopedType(container, &errorMsg)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700841 std::cerr << "ERROR: " << errorMsg << " at " << @2 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700842 YYERROR;
843 }
Andreas Huber7c5ddfb2016-09-29 13:45:22 -0700844
845 $$ = container;
Andreas Huberc9410c72016-07-28 12:18:40 -0700846 }
847 ;
848
Andreas Huberc9410c72016-07-28 12:18:40 -0700849struct_or_union_body
850 : '{' field_declarations '}' { $$ = $2; }
851 ;
852
853field_declarations
Andreas Huber881227d2016-08-02 14:20:21 -0700854 : /* empty */ { $$ = new std::vector<CompoundField *>; }
Andreas Huberc9410c72016-07-28 12:18:40 -0700855 | field_declarations field_declaration
856 {
857 $$ = $1;
858
859 if ($2 != NULL) {
860 $$->push_back($2);
861 }
862 }
863 ;
864
865field_declaration
Yifan Hongbe627b32016-10-28 18:38:56 -0700866 : error_stmt { $$ = nullptr; }
Yifan Hong27e85db2016-11-09 15:45:52 -0800867 | type valid_identifier require_semicolon
868 {
869 std::string errorMsg;
870 if (ast->scope()->isCompoundType() &&
871 static_cast<CompoundType *>(ast->scope())->style() == CompoundType::STYLE_STRUCT &&
872 !isValidStructField($2, &errorMsg)) {
873 std::cerr << "ERROR: " << errorMsg << " at "
874 << @2 << "\n";
875 YYERROR;
876 }
877 $$ = new CompoundField($2, $1);
878 }
879 | annotated_compound_declaration ';'
880 {
881 std::string errorMsg;
882 if (ast->scope()->isCompoundType() &&
883 static_cast<CompoundType *>(ast->scope())->style() == CompoundType::STYLE_STRUCT &&
884 $1 != nullptr &&
885 $1->isNamedType() &&
886 !isValidStructField(static_cast<NamedType *>($1)->localName().c_str(), &errorMsg)) {
887 std::cerr << "ERROR: " << errorMsg << " at "
888 << @2 << "\n";
889 YYERROR;
890 }
891 $$ = NULL;
892 }
Andreas Huber7c5ddfb2016-09-29 13:45:22 -0700893 ;
894
895annotated_compound_declaration
896 : opt_annotations compound_declaration
897 {
898 $2->setAnnotations($1);
899 $$ = $2;
900 }
901 ;
902
903compound_declaration
Yifan Honga2855012016-10-11 13:36:54 -0700904 : named_struct_or_union_declaration { $$ = $1; }
Yifan Hong6a2fedf2016-10-11 13:44:07 -0700905 | named_enum_declaration { $$ = $1; }
Andreas Huberc9410c72016-07-28 12:18:40 -0700906 ;
907
Steven Moreland1c71fd52016-11-29 14:03:33 -0800908enum_storage_type
909 : ':' fqtype
Andreas Huber8d3ac0c2016-08-04 14:49:23 -0700910 {
911 $$ = $2;
912
913 if ($$ != NULL && !$$->isValidEnumStorageType()) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700914 std::cerr << "ERROR: Invalid enum storage type specified. at "
915 << @2 << "\n";
916
Yifan Hongbe627b32016-10-28 18:38:56 -0700917 YYERROR;
Andreas Huber8d3ac0c2016-08-04 14:49:23 -0700918 }
919 }
Andreas Huberc9410c72016-07-28 12:18:40 -0700920 ;
921
922opt_comma
923 : /* empty */
924 | ','
925 ;
926
927named_enum_declaration
Yifan Hongf3d3c732017-05-08 17:27:54 -0700928 : ENUM valid_type_name enum_storage_type
Andreas Huberc9410c72016-07-28 12:18:40 -0700929 {
Yifan Honga4b53d02016-10-31 17:29:10 -0700930 ast->enterScope(new EnumType($2, convertYYLoc(@2), $3));
Yifan Hongf24fa852016-09-23 11:03:15 -0700931 }
932 enum_declaration_body
933 {
Yifan Hongbe627b32016-10-28 18:38:56 -0700934 if (!ast->scope()->isEnum()) {
935 std::cerr << "ERROR: unknown error in enum declaration at "
936 << @5 << "\n";
937 YYERROR;
938 }
939
Yifan Hongf24fa852016-09-23 11:03:15 -0700940 EnumType *enumType = static_cast<EnumType *>(ast->scope());
941 ast->leaveScope();
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700942
943 std::string errorMsg;
Andreas Huber9ed827c2016-08-22 12:31:13 -0700944 if (!ast->addScopedType(enumType, &errorMsg)) {
Andreas Huber0d0f9a22016-08-17 10:26:11 -0700945 std::cerr << "ERROR: " << errorMsg << " at " << @2 << "\n";
Andreas Huber5a545442016-08-03 10:44:56 -0700946 YYERROR;
947 }
Andreas Huber7c5ddfb2016-09-29 13:45:22 -0700948
949 $$ = enumType;
Andreas Huberc9410c72016-07-28 12:18:40 -0700950 }
951 ;
952
Yifan Hongf24fa852016-09-23 11:03:15 -0700953enum_declaration_body
954 : '{' enum_values opt_comma '}' { $$ = $2; }
955 ;
956
Andreas Huberc9410c72016-07-28 12:18:40 -0700957enum_value
Yifan Hong27e85db2016-11-09 15:45:52 -0800958 : valid_identifier { $$ = new EnumValue($1); }
959 | valid_identifier '=' const_expr { $$ = new EnumValue($1, $3); }
Andreas Huberc9410c72016-07-28 12:18:40 -0700960 ;
961
962enum_values
963 : /* empty */
Yifan Hongf24fa852016-09-23 11:03:15 -0700964 { /* do nothing */ }
Andreas Huberc9410c72016-07-28 12:18:40 -0700965 | enum_value
966 {
Yifan Hongbe627b32016-10-28 18:38:56 -0700967 if (!ast->scope()->isEnum()) {
968 std::cerr << "ERROR: unknown error in enum declaration at "
969 << @1 << "\n";
970 YYERROR;
971 }
972
Yifan Hongf24fa852016-09-23 11:03:15 -0700973 static_cast<EnumType *>(ast->scope())->addValue($1);
Andreas Huberc9410c72016-07-28 12:18:40 -0700974 }
975 | enum_values ',' enum_value
976 {
Yifan Hongbe627b32016-10-28 18:38:56 -0700977 if (!ast->scope()->isEnum()) {
978 std::cerr << "ERROR: unknown error in enum declaration at "
979 << @3 << "\n";
980 YYERROR;
981 }
982
Yifan Hongf24fa852016-09-23 11:03:15 -0700983 static_cast<EnumType *>(ast->scope())->addValue($3);
Andreas Huberc9410c72016-07-28 12:18:40 -0700984 }
985 ;
986
Yifan Hongbd33e382016-11-02 13:30:17 -0700987array_type_base
Yifan Hongae16eed2016-09-23 13:25:25 -0700988 : fqtype { $$ = $1; }
Yifan Hongbf459bc2016-08-23 16:50:37 -0700989 | TEMPLATED '<' type '>'
Andreas Huberb95ea8a2016-08-15 15:35:42 -0700990 {
Steven Moreland30bb6a82016-11-30 09:18:34 -0800991 if (!$1->isCompatibleElementType($3)) {
992 std::cerr << "ERROR: " << $1->typeName() << " of " << $3->typeName()
993 << " is not supported. at " << @3 << "\n";
Andreas Huber70a59e12016-08-16 12:57:01 -0700994
Andreas Huberb95ea8a2016-08-15 15:35:42 -0700995 YYERROR;
996 }
Yifan Hongbf459bc2016-08-23 16:50:37 -0700997 $1->setElementType($3);
998 $$ = $1;
999 }
1000 | TEMPLATED '<' TEMPLATED '<' type RSHIFT
1001 {
Steven Moreland30bb6a82016-11-30 09:18:34 -08001002 if (!$3->isCompatibleElementType($5)) {
1003 std::cerr << "ERROR: " << $3->typeName() << " of " << $5->typeName()
1004 << " is not supported. at " << @3 << "\n";
Andreas Huberb95ea8a2016-08-15 15:35:42 -07001005
Yifan Hongbf459bc2016-08-23 16:50:37 -07001006 YYERROR;
1007 }
1008 $3->setElementType($5);
Steven Moreland30bb6a82016-11-30 09:18:34 -08001009 if (!$1->isCompatibleElementType($3)) {
1010 std::cerr << "ERROR: " << $1->typeName() << " of " << $3->typeName()
1011 << " is not supported. at " << @3 << "\n";
1012
1013 YYERROR;
1014 }
Yifan Hongbf459bc2016-08-23 16:50:37 -07001015 $1->setElementType($3);
1016 $$ = $1;
Andreas Huberb95ea8a2016-08-15 15:35:42 -07001017 }
Yifan Hongbd33e382016-11-02 13:30:17 -07001018 ;
1019
1020array_type
1021 : array_type_base '[' const_expr ']'
1022 {
1023 if ($1->isBinder()) {
1024 std::cerr << "ERROR: Arrays of interface types are not supported."
1025 << " at " << @1 << "\n";
1026
1027 YYERROR;
1028 }
1029 if ($1->isArray()) {
1030 $$ = new ArrayType(static_cast<ArrayType *>($1), $3);
1031 } else {
1032 $$ = new ArrayType($1, $3);
1033 }
1034 }
1035 | array_type '[' const_expr ']'
1036 {
1037 $$ = $1;
1038 $$->appendDimension($3);
1039 }
1040 ;
1041
1042type
1043 : array_type_base { $$ = $1; }
1044 | array_type { $$ = $1; }
Andreas Huber7c5ddfb2016-09-29 13:45:22 -07001045 | annotated_compound_declaration { $$ = $1; }
Yifan Hongc8934042016-11-17 17:10:52 -08001046 | INTERFACE
1047 {
1048 // "interface" is a synonym of android.hidl.base@1.0::IBase
1049 $$ = ast->lookupType(gIBaseFqName);
1050 if ($$ == nullptr) {
1051 std::cerr << "FATAL: Cannot find "
1052 << gIBaseFqName.string()
1053 << " at " << @1 << "\n";
1054
1055 YYERROR;
1056 }
1057 }
Andreas Huberc9410c72016-07-28 12:18:40 -07001058 ;
1059
Andreas Huberc9410c72016-07-28 12:18:40 -07001060%%
Andreas Huber0d0f9a22016-08-17 10:26:11 -07001061
1062#include <android-base/logging.h>
1063
1064void yy::parser::error(
1065 const yy::parser::location_type &where,
1066 const std::string &errstr) {
1067 std::cerr << "ERROR: " << errstr << " at " << where << "\n";
1068}
1069