blob: 596b211352d6ae431080844f2f9b37b440c9a070 [file] [log] [blame]
Steven Morelandf1a35f72016-08-17 08:41:49 -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
17%{
18
19#include "AST.h"
20#include "Declaration.h"
21#include "Type.h"
22#include "VarDeclaration.h"
23#include "FunctionDeclaration.h"
24#include "CompositeDeclaration.h"
25#include "Define.h"
26#include "Include.h"
27#include "EnumVarDeclaration.h"
28#include "Note.h"
29#include "TypeDef.h"
30#include "Expression.h"
31
32#include "c2hal_y.h"
33
34#include <stdio.h>
Steven Morelandf1a35f72016-08-17 08:41:49 -070035#include <algorithm>
36
37using namespace android;
38
39extern int yylex(YYSTYPE *yylval_param, YYLTYPE *llocp, void *);
40
41int yyerror(YYLTYPE *llocp, AST *, const char *s) {
42 extern bool should_report_errors;
43
44 if (!should_report_errors) {
45 return 0;
46 }
47
48 fflush(stdout);
49 LOG(ERROR) << " "
50 << s
51 << " near line "
52 << llocp->first_line;
53
54 return 0;
55}
56
57#define scanner ast->scanner()
58
59std::string get_last_comment() {
60 extern std::string last_comment;
61
62 std::string ret{last_comment};
63
64 // clear the last comment now that it's been taken
65 last_comment = "";
66
67 return ret;
68}
69
70%}
71
72%parse-param { android::AST *ast }
73%lex-param { void *scanner }
74%locations
75%pure-parser
76%glr-parser
77
Steven Moreland039bf852016-09-26 14:38:46 -070078/* These have to do with the fact that
Yifan Hongcea77732016-10-03 14:59:42 -070079 * struct_or_union_declaration and enum_declaration
Steven Moreland039bf852016-09-26 14:38:46 -070080 * both start with STRUCT/UNION/ENUM opt_id
81 * and type_qualifiers contain these.
82 */
83%expect 3
84
Steven Morelandf1a35f72016-08-17 08:41:49 -070085%token START_HEADER
86%token START_EXPR
87
88%token STRUCT
89%token UNION
90%token ENUM
Yifan Hongcea77732016-10-03 14:59:42 -070091%token CLASS
Steven Morelandf1a35f72016-08-17 08:41:49 -070092%token CONST
93%token VOID
94%token INCLUDE
95%token DEFINE
96%token TYPEDEF
97%token UNSIGNED
98%token SIGNED
99%token LSHIFT
100%token RSHIFT
101%token VARARGS
102%token NAMESPACE
103%token EXTERN
104%token C_STRING
105
106%left ','
107%right '?' ':'
108%left '|'
109%left '^'
110%left '&'
111%left RSHIFT LSHIFT
112%left '+' '-'
113%left '*' '/' '%'
114%right '~' '!' UMINUS UPLUS
115%left ARRAY_SUBSCRIPT FUNCTION_CALL
116
Yifan Hongcea77732016-10-03 14:59:42 -0700117%right STRUCT ENUM
118
Steven Morelandf1a35f72016-08-17 08:41:49 -0700119%token<str> ID
120%token<str> COMMENT
121%token<str> VALUE
122%token<str> INTEGRAL_VALUE
123%token<str> INCLUDE_FILE
124%token<str> FUNCTION
125%token<str> DEFINE_SLURP
126%token<str> OTHER_STATEMENT
127
Steven Morelandce651892016-09-19 13:12:58 -0700128%type<expression> array
129%type<expressions> arrays
Steven Morelandf1a35f72016-08-17 08:41:49 -0700130%type<expression> expr
131%type<expressions> args
132%type<type> type
Yifan Hongcea77732016-10-03 14:59:42 -0700133%type<type> opt_enum_base_type
Steven Morelandf1a35f72016-08-17 08:41:49 -0700134%type<qualifier> type_qualifier
135%type<qualifiers> type_qualifiers
136%type<declaration> declaration
137%type<declarations> declarations
138%type<composite> struct_or_union_declaration
139%type<composite> enum_declaration
140%type<param> param
141%type<params> params
142%type<qualification> struct_or_union
143%type<str> opt_id
144%type<include> include
145%type<enum_var> enum_var
Yifan Hong7c0a90a2016-09-30 10:57:22 -0700146%type<declarations> enum_vars enum_vars_all_but_last
147%type<declaration> enum_var_line enum_var_last_line
Steven Morelandf1a35f72016-08-17 08:41:49 -0700148
149%start parse_selector
150
151%union {
152 const char *str;
153 int count;
154 android::Declaration *declaration;
155 android::CompositeDeclaration *composite;
156 std::vector<android::Declaration *> *declarations;
157 android::EnumVarDeclaration *enum_var;
158 android::Declaration *param;
159 std::vector<android::Declaration *> *params;
160 android::Type *type;
161 android::Type::Qualifier *qualifier;
162 android::Type::Qualifier::Qualification qualification;
163 std::vector<android::Type::Qualifier*> *qualifiers;
164 android::Include *include;
165 std::vector<android::Include *> *includes;
166 android::Expression *expression;
167 std::vector<android::Expression *> *expressions;
168}
169
170%%
171
172parse_selector
173 : START_HEADER header
174 | START_EXPR expr_parser
175 ;
176
177expr_parser
178 : expr
179 {
180 ast->setExpression($1);
181 }
182 ;
183
184header
185 : declarations /* well, we are a header file */
186 {
Steven Morelandf1a35f72016-08-17 08:41:49 -0700187 ast->setDeclarations($1);
188 }
189 ;
190
191declarations
192 : /* EMPTY */
193 {
194 $$ = new std::vector<Declaration *>;
195 }
Yifan Hong7c0a90a2016-09-30 10:57:22 -0700196 | declarations declaration
Steven Morelandf1a35f72016-08-17 08:41:49 -0700197 {
Yifan Hong7c0a90a2016-09-30 10:57:22 -0700198 $$ = $1;
199 $$->push_back($2);
Steven Morelandf1a35f72016-08-17 08:41:49 -0700200 }
Yifan Hong7c0a90a2016-09-30 10:57:22 -0700201 | declarations EXTERN C_STRING '{' declarations '}'
Steven Morelandf1a35f72016-08-17 08:41:49 -0700202 {
Yifan Hong7c0a90a2016-09-30 10:57:22 -0700203 $1->push_back(new Note("extern \"C\" { "));
204 $1->insert($1->end(), $5->begin(), $5->end());
205 $1->push_back(new Note("} // end of extern C"));
206 delete $5;
Steven Morelandf1a35f72016-08-17 08:41:49 -0700207
Yifan Hong7c0a90a2016-09-30 10:57:22 -0700208 $$ = $1;
Steven Morelandf1a35f72016-08-17 08:41:49 -0700209 }
210 ;
211
212declaration
213 : param ';'
214 {
215 $$ = $1;
216 $$->setComment(get_last_comment());
217 }
218 | struct_or_union_declaration ';'
219 {
220 $$ = $1;
221 }
222 | enum_declaration ';'
223 {
224 $$ = $1;
225 }
226 | TYPEDEF struct_or_union_declaration ';'
227 {
228 // ignore that it is a typedef, for our purposes it doesn't matter
229 $$ = $2;
230 }
231 | TYPEDEF enum_declaration ';'
232 {
233 // ignore that it is a typedef, for our purposes it doesn't matter
234 $$ = $2;
235 }
236 | TYPEDEF param ';' /* looks like 'typedef const int8_t store;' */
237 {
238 $$ = new TypeDef($2->getName(), $2);
239 $$->setComment(get_last_comment());
240 }
241 | DEFINE ID DEFINE_SLURP
242 {
243 $$ = new Define($2, $3);
244 $$->setComment(get_last_comment());
245 }
246 | OTHER_STATEMENT
247 {
248 $$ = new Note($1);
249 $$->setComment(get_last_comment());
250 }
251 | FUNCTION
252 {
253 $$ = new Note($1);
254 $$->setComment(get_last_comment());
255 }
256 | type ID '=' expr ';'
257 {
258 $$ = new Note($1->decorateName($2) + " = " + $4->toString());
259 }
260 | include
261 {
262 $$ = $1;
263 $$->setComment(get_last_comment());
264 }
265 | NAMESPACE ID '{' declarations '}'
266 {
267 $$ = new CompositeDeclaration(Type::Qualifier::STRUCT,
268 $2,
269 $4);
270
271 get_last_comment(); // clear it
272 $$->setComment("/* from namespace declaration */");
273 }
274 ;
275
276include
277 : INCLUDE '<' INCLUDE_FILE '>'
278 {
279 $$ = new Include($3, true /* isLibrary */);
280 }
281 | INCLUDE '"' INCLUDE_FILE '"'
282 {
283 $$ = new Include($3, false /* isLibrary */);
284 }
285 ;
286
287struct_or_union_declaration
288 : struct_or_union opt_id
289 {
290 $<str>$ = strdup(get_last_comment().c_str());
291 }
292 '{' declarations '}' opt_id
293 {
Steven Morelandf1a35f72016-08-17 08:41:49 -0700294 $$ = new CompositeDeclaration($1, $2, $5);
295 $$->setComment($<str>3);
296
297 if(!std::string($7).empty()) {
298 $$->setName($7);
299 }
300 }
301 ;
302
Yifan Hong7c0a90a2016-09-30 10:57:22 -0700303opt_comma
304 : /* EMPTY */
305 | ','
306 ;
307
Yifan Hongcea77732016-10-03 14:59:42 -0700308enum_key
309 : ENUM
310 | ENUM CLASS /* c++11 */
311 | ENUM STRUCT /* c++11 */
312 ;
313
314opt_enum_base_type
315 : /* EMPTY */ { $$ = NULL; }
316 | ':' type { $$ = $2; }
317 ;
318
Steven Morelandf1a35f72016-08-17 08:41:49 -0700319enum_declaration
Yifan Hongcea77732016-10-03 14:59:42 -0700320 : enum_key opt_id
Steven Morelandf1a35f72016-08-17 08:41:49 -0700321 {
322 $<str>$ = strdup(get_last_comment().c_str());
323 }
Yifan Hongcea77732016-10-03 14:59:42 -0700324 opt_enum_base_type '{' enum_vars '}' opt_id
Steven Morelandf1a35f72016-08-17 08:41:49 -0700325 {
Yifan Hongcea77732016-10-03 14:59:42 -0700326 $$ = new CompositeDeclaration(Type::Qualifier::ENUM, $2, $6);
Steven Morelandf1a35f72016-08-17 08:41:49 -0700327 $$->setComment($<str>3);
328
Yifan Hongcea77732016-10-03 14:59:42 -0700329 if($4) {
330 $$->setEnumTypeName($4->decorateName(""));
331 delete $4;
332 }
333
334 if(!std::string($8).empty()) {
335 $$->setName($8);
Steven Morelandf1a35f72016-08-17 08:41:49 -0700336 }
337 }
338 ;
339
340enum_vars
341 : /* EMPTY */
342 {
343 $$ = new std::vector<Declaration *>;
344 }
Yifan Hong7c0a90a2016-09-30 10:57:22 -0700345 | enum_vars_all_but_last enum_var_last_line
346 {
347 $$ = $1;
348 $$->push_back($2);
349 }
350
351enum_vars_all_but_last
352 : /* EMPTY */
Steven Morelandf1a35f72016-08-17 08:41:49 -0700353 {
354 $$ = new std::vector<Declaration *>;
Steven Morelandf1a35f72016-08-17 08:41:49 -0700355 }
Yifan Hong7c0a90a2016-09-30 10:57:22 -0700356 | enum_vars_all_but_last enum_var_line
Steven Morelandf1a35f72016-08-17 08:41:49 -0700357 {
Yifan Hong7c0a90a2016-09-30 10:57:22 -0700358 $$ = $1;
359 $$->push_back($2);
Steven Morelandf1a35f72016-08-17 08:41:49 -0700360 }
Yifan Hong7c0a90a2016-09-30 10:57:22 -0700361 ;
362
363enum_var_last_line
364 : enum_var opt_comma { $$ = $1; }
365 | OTHER_STATEMENT
Steven Morelandc38c8582016-09-19 15:04:37 -0700366 {
Yifan Hong7c0a90a2016-09-30 10:57:22 -0700367 $$ = new Note($1);
368 $$->setComment(get_last_comment());
369 }
370 ;
371
372enum_var_line
373 : enum_var ',' { $$ = $1; }
374 | OTHER_STATEMENT
375 {
376 $$ = new Note($1);
377 $$->setComment(get_last_comment());
Steven Morelandc38c8582016-09-19 15:04:37 -0700378 }
Steven Morelandf1a35f72016-08-17 08:41:49 -0700379 ;
380
381enum_var
382 : ID
383 {
384 $$ = new EnumVarDeclaration($1, NULL);
385 $$->setComment(get_last_comment());
386 }
387 | ID '=' expr
388 {
389 $$ = new EnumVarDeclaration($1, $3);
390 $$->setComment(get_last_comment());
391 }
392 ;
393
394params
395 : /* EMPTY */
396 {
397 $$ = new std::vector<Declaration *>;
398 }
399 | param
400 {
401 $$ = new std::vector<Declaration *>;
402 $$->push_back($1);
403 }
Yifan Hong7c0a90a2016-09-30 10:57:22 -0700404 | params ',' param
Steven Morelandf1a35f72016-08-17 08:41:49 -0700405 {
Yifan Hong7c0a90a2016-09-30 10:57:22 -0700406 $$ = $1;
407 $$->push_back($3);
Steven Morelandf1a35f72016-08-17 08:41:49 -0700408 }
409 ;
410
411param
Steven Morelandce651892016-09-19 13:12:58 -0700412 : type arrays
Steven Morelandf1a35f72016-08-17 08:41:49 -0700413 {
Steven Morelandce651892016-09-19 13:12:58 -0700414 $1->setArrays($2);
Steven Morelandf1a35f72016-08-17 08:41:49 -0700415
416 // allow for either "const int myvar" or "const int"
417 // as a parameter declaration
418 std::string lastId = $1->removeLastId();
419
420 $$ = new VarDeclaration($1, lastId);
421 }
Steven Morelandce651892016-09-19 13:12:58 -0700422 | type '(' '*' ID arrays ')' '(' params ')'
Steven Morelandf1a35f72016-08-17 08:41:49 -0700423 {
Steven Morelandce651892016-09-19 13:12:58 -0700424 $1->setArrays($5);
Steven Morelandf1a35f72016-08-17 08:41:49 -0700425 $$ = new FunctionDeclaration($1, $4, $8);
426 }
427 | type ID '(' params ')'
428 {
Steven Morelandf1a35f72016-08-17 08:41:49 -0700429 $$ = new FunctionDeclaration($1, $2, $4);
430 }
431 | type '(' ID ')' '(' params ')'
432 {
Steven Morelandf1a35f72016-08-17 08:41:49 -0700433 $$ = new FunctionDeclaration($1, $3, $6);
434 }
435 | VARARGS
436 {
437 $$ = new VarDeclaration(new Type(NULL), "...");
438 }
439 ;
440
441type
442 : type_qualifiers
443 {
Steven Morelandf1a35f72016-08-17 08:41:49 -0700444 $$ = new Type($1);
445 }
446 ;
447
448type_qualifiers
449 : type_qualifier
450 {
451 $$ = new std::vector<Type::Qualifier *>;
452 $$->push_back($1);
453 }
Yifan Hong7c0a90a2016-09-30 10:57:22 -0700454 | type_qualifiers type_qualifier
Steven Morelandf1a35f72016-08-17 08:41:49 -0700455 {
Yifan Hong7c0a90a2016-09-30 10:57:22 -0700456 $$ = $1;
457 $$->push_back($2);
Steven Morelandf1a35f72016-08-17 08:41:49 -0700458 }
459 ;
460
461opt_id
462 : /* EMPTY */ { $$ = ""; }
463 |
464 ID { $$ = $1; }
465 ;
466
467expr
Yifan Hong42009032016-09-29 09:38:15 -0700468 : ID
469 {
Yifan Hongb33b5ee2016-09-29 13:48:54 -0700470 $$ = Expression::atom(Expression::Type::UNKNOWN, $1, true /* isId*/ );
Yifan Hong42009032016-09-29 09:38:15 -0700471 }
Yifan Hongb33b5ee2016-09-29 13:48:54 -0700472 | VALUE { $$ = Expression::atom(Expression::Type::UNKNOWN, $1); }
Steven Morelandf1a35f72016-08-17 08:41:49 -0700473 | INTEGRAL_VALUE { $$ = Expression::atom(Expression::integralType($1), $1); }
474 | '(' expr ')' { $$ = Expression::parenthesize($2); }
475 | ID '[' expr ']' %prec ARRAY_SUBSCRIPT {
476 $$ = Expression::arraySubscript($1, $3);
477 }
478 | ID '(' args ')' %prec FUNCTION_CALL {
Steven Morelandf1a35f72016-08-17 08:41:49 -0700479 $$ = Expression::functionCall($1, $3);
480 }
481 | expr '?' expr ':' expr { $$ = Expression::ternary($1, $3, $5); }
482 | expr '+' expr { $$ = Expression::binary($1, "+", $3); }
483 | expr '-' expr { $$ = Expression::binary($1, "-", $3); }
484 | expr '/' expr { $$ = Expression::binary($1, "/", $3); }
485 | expr '*' expr { $$ = Expression::binary($1, "*", $3); }
486 | expr '%' expr { $$ = Expression::binary($1, "%%", $3); }
487 | expr '&' expr { $$ = Expression::binary($1, "&", $3); }
488 | expr '|' expr { $$ = Expression::binary($1, "|", $3); }
489 | expr '^' expr { $$ = Expression::binary($1, "^", $3); }
490 | expr LSHIFT expr { $$ = Expression::binary($1, "<<", $3); }
491 | expr RSHIFT expr { $$ = Expression::binary($1, ">>", $3); }
492 | '~' expr { $$ = Expression::unary("~", $2); }
493 | '-' expr %prec UMINUS { $$ = Expression::unary("-", $2); }
494 | '+' expr %prec UPLUS { $$ = Expression::unary("+", $2); }
495 ;
496
497args
498 : /* empty */
499 {
500 $$ = new std::vector<Expression *>;
501 }
502 | expr
503 {
504 $$ = new std::vector<Expression *>;
505 $$->push_back($1);
506 }
Yifan Hong7c0a90a2016-09-30 10:57:22 -0700507 | args ',' expr
Steven Morelandf1a35f72016-08-17 08:41:49 -0700508 {
Yifan Hong7c0a90a2016-09-30 10:57:22 -0700509 $$ = $1;
510 $$->push_back($3);
Steven Morelandf1a35f72016-08-17 08:41:49 -0700511 }
512 ;
513
514type_qualifier
515 : UNSIGNED { $$ = new Type::Qualifier(Type::Qualifier::UNSIGNED); }
516 | SIGNED { $$ = new Type::Qualifier(Type::Qualifier::SIGNED); }
517 | VOID { $$ = new Type::Qualifier(Type::Qualifier::VOID); }
518 | '*' { $$ = new Type::Qualifier(Type::Qualifier::POINTER); }
519 | CONST { $$ = new Type::Qualifier(Type::Qualifier::CONST); }
520 | ID { $$ = new Type::Qualifier(Type::Qualifier::ID, $1); }
521 | '<' type '>' { $$ = new Type::Qualifier(Type::Qualifier::GENERICS, $2); }
Yifan Hongcea77732016-10-03 14:59:42 -0700522 | enum_key { $$ = new Type::Qualifier(Type::Qualifier::ENUM); }
Steven Morelandf1a35f72016-08-17 08:41:49 -0700523 | struct_or_union { $$ = new Type::Qualifier($1); }
524 ;
525
526struct_or_union
527 : STRUCT { $$ = android::Type::Qualifier::STRUCT; }
528 | UNION { $$ = android::Type::Qualifier::UNION; }
529 ;
530
Steven Morelandce651892016-09-19 13:12:58 -0700531arrays
532 : /* empty */ { $$ = new std::vector<Expression *>; }
Yifan Hong643e5092016-09-29 17:49:43 -0700533 | arrays array {
534 $$ = $1;
535 $$->push_back($2);
Steven Morelandce651892016-09-19 13:12:58 -0700536 }
537 ;
538
539array
Yifan Hongb33b5ee2016-09-29 13:48:54 -0700540 : '[' ']' { $$ = Expression::atom(Expression::Type::UNKNOWN, " "); }
Steven Morelandf1a35f72016-08-17 08:41:49 -0700541 | '[' expr ']' { $$ = $2; }
542 ;
543
Yifan Hong42009032016-09-29 09:38:15 -0700544%%