blob: e27b928d5bee5397c1ce1fe0c232bbe85f05182f [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
78%token START_HEADER
79%token START_EXPR
80
81%token STRUCT
82%token UNION
83%token ENUM
84%token CONST
85%token VOID
86%token INCLUDE
87%token DEFINE
88%token TYPEDEF
89%token UNSIGNED
90%token SIGNED
91%token LSHIFT
92%token RSHIFT
93%token VARARGS
94%token NAMESPACE
95%token EXTERN
96%token C_STRING
97
98%left ','
99%right '?' ':'
100%left '|'
101%left '^'
102%left '&'
103%left RSHIFT LSHIFT
104%left '+' '-'
105%left '*' '/' '%'
106%right '~' '!' UMINUS UPLUS
107%left ARRAY_SUBSCRIPT FUNCTION_CALL
108
109%token<str> ID
110%token<str> COMMENT
111%token<str> VALUE
112%token<str> INTEGRAL_VALUE
113%token<str> INCLUDE_FILE
114%token<str> FUNCTION
115%token<str> DEFINE_SLURP
116%token<str> OTHER_STATEMENT
117
Steven Morelandce651892016-09-19 13:12:58 -0700118%type<expression> array
119%type<expressions> arrays
Steven Morelandf1a35f72016-08-17 08:41:49 -0700120%type<expression> expr
121%type<expressions> args
122%type<type> type
123%type<qualifier> type_qualifier
124%type<qualifiers> type_qualifiers
125%type<declaration> declaration
126%type<declarations> declarations
127%type<composite> struct_or_union_declaration
128%type<composite> enum_declaration
129%type<param> param
130%type<params> params
131%type<qualification> struct_or_union
132%type<str> opt_id
133%type<include> include
134%type<enum_var> enum_var
135%type<declarations> enum_vars
136
137%start parse_selector
138
139%union {
140 const char *str;
141 int count;
142 android::Declaration *declaration;
143 android::CompositeDeclaration *composite;
144 std::vector<android::Declaration *> *declarations;
145 android::EnumVarDeclaration *enum_var;
146 android::Declaration *param;
147 std::vector<android::Declaration *> *params;
148 android::Type *type;
149 android::Type::Qualifier *qualifier;
150 android::Type::Qualifier::Qualification qualification;
151 std::vector<android::Type::Qualifier*> *qualifiers;
152 android::Include *include;
153 std::vector<android::Include *> *includes;
154 android::Expression *expression;
155 std::vector<android::Expression *> *expressions;
156}
157
158%%
159
160parse_selector
161 : START_HEADER header
162 | START_EXPR expr_parser
163 ;
164
165expr_parser
166 : expr
167 {
168 ast->setExpression($1);
169 }
170 ;
171
172header
173 : declarations /* well, we are a header file */
174 {
175 std::reverse($1->begin(), $1->end());
176 ast->setDeclarations($1);
177 }
178 ;
179
180declarations
181 : /* EMPTY */
182 {
183 $$ = new std::vector<Declaration *>;
184 }
185 | declaration declarations
186 {
187 $$ = $2;
188 $$->push_back($1);
189 }
190 | EXTERN C_STRING '{' declarations '}' declarations
191 {
192 $6->push_back(new Note("} // end of extern C"));
193 $6->insert($6->end(), $4->begin(), $4->end());
194 $6->push_back(new Note("extern \"C\" { "));
195 delete $4;
196
197 $$ = $6;
198 }
199 ;
200
201declaration
202 : param ';'
203 {
204 $$ = $1;
205 $$->setComment(get_last_comment());
206 }
207 | struct_or_union_declaration ';'
208 {
209 $$ = $1;
210 }
211 | enum_declaration ';'
212 {
213 $$ = $1;
214 }
215 | TYPEDEF struct_or_union_declaration ';'
216 {
217 // ignore that it is a typedef, for our purposes it doesn't matter
218 $$ = $2;
219 }
220 | TYPEDEF enum_declaration ';'
221 {
222 // ignore that it is a typedef, for our purposes it doesn't matter
223 $$ = $2;
224 }
225 | TYPEDEF param ';' /* looks like 'typedef const int8_t store;' */
226 {
227 $$ = new TypeDef($2->getName(), $2);
228 $$->setComment(get_last_comment());
229 }
230 | DEFINE ID DEFINE_SLURP
231 {
232 $$ = new Define($2, $3);
233 $$->setComment(get_last_comment());
234 }
235 | OTHER_STATEMENT
236 {
237 $$ = new Note($1);
238 $$->setComment(get_last_comment());
239 }
240 | FUNCTION
241 {
242 $$ = new Note($1);
243 $$->setComment(get_last_comment());
244 }
245 | type ID '=' expr ';'
246 {
247 $$ = new Note($1->decorateName($2) + " = " + $4->toString());
248 }
249 | include
250 {
251 $$ = $1;
252 $$->setComment(get_last_comment());
253 }
254 | NAMESPACE ID '{' declarations '}'
255 {
256 $$ = new CompositeDeclaration(Type::Qualifier::STRUCT,
257 $2,
258 $4);
259
260 get_last_comment(); // clear it
261 $$->setComment("/* from namespace declaration */");
262 }
263 ;
264
265include
266 : INCLUDE '<' INCLUDE_FILE '>'
267 {
268 $$ = new Include($3, true /* isLibrary */);
269 }
270 | INCLUDE '"' INCLUDE_FILE '"'
271 {
272 $$ = new Include($3, false /* isLibrary */);
273 }
274 ;
275
276struct_or_union_declaration
277 : struct_or_union opt_id
278 {
279 $<str>$ = strdup(get_last_comment().c_str());
280 }
281 '{' declarations '}' opt_id
282 {
283 std::reverse($5->begin(), $5->end());
284 $$ = new CompositeDeclaration($1, $2, $5);
285 $$->setComment($<str>3);
286
287 if(!std::string($7).empty()) {
288 $$->setName($7);
289 }
290 }
291 ;
292
293enum_declaration
294 : ENUM opt_id
295 {
296 $<str>$ = strdup(get_last_comment().c_str());
297 }
298 '{' enum_vars '}' opt_id
299 {
300 std::reverse($5->begin(), $5->end());
301 $$ = new CompositeDeclaration(Type::Qualifier::ENUM, $2, $5);
302 $$->setComment($<str>3);
303
304 if(!std::string($7).empty()) {
305 $$->setName($7);
306 }
307 }
308 ;
309
310enum_vars
311 : /* EMPTY */
312 {
313 $$ = new std::vector<Declaration *>;
314 }
315 | enum_var /* a comma is optional on the last item */
316 {
317 $$ = new std::vector<Declaration *>;
318 $$->push_back($1);
319 }
Steven Morelandc38c8582016-09-19 15:04:37 -0700320 | OTHER_STATEMENT
321 {
322 $$ = new std::vector<Declaration *>;
323 Note *note = new Note($1);
324 note->setComment(get_last_comment());
325 $$->push_back(note);
326 }
Steven Morelandf1a35f72016-08-17 08:41:49 -0700327 | enum_var ',' enum_vars
328 {
329 $$ = $3;
330 $$->push_back($1);
331 }
Steven Morelandc38c8582016-09-19 15:04:37 -0700332 | OTHER_STATEMENT enum_vars
333 {
334 $$ = $2;
335 Note *note = new Note($1);
336 note->setComment(get_last_comment());
337 $$->push_back(note);
338 }
Steven Morelandf1a35f72016-08-17 08:41:49 -0700339 ;
340
341enum_var
342 : ID
343 {
344 $$ = new EnumVarDeclaration($1, NULL);
345 $$->setComment(get_last_comment());
346 }
347 | ID '=' expr
348 {
349 $$ = new EnumVarDeclaration($1, $3);
350 $$->setComment(get_last_comment());
351 }
352 ;
353
354params
355 : /* EMPTY */
356 {
357 $$ = new std::vector<Declaration *>;
358 }
359 | param
360 {
361 $$ = new std::vector<Declaration *>;
362 $$->push_back($1);
363 }
364 | param ',' params
365 {
366 $$ = $3;
367 $$->push_back($1);
368 }
369 ;
370
371param
Steven Morelandce651892016-09-19 13:12:58 -0700372 : type arrays
Steven Morelandf1a35f72016-08-17 08:41:49 -0700373 {
Steven Morelandce651892016-09-19 13:12:58 -0700374 $1->setArrays($2);
Steven Morelandf1a35f72016-08-17 08:41:49 -0700375
376 // allow for either "const int myvar" or "const int"
377 // as a parameter declaration
378 std::string lastId = $1->removeLastId();
379
380 $$ = new VarDeclaration($1, lastId);
381 }
Steven Morelandce651892016-09-19 13:12:58 -0700382 | type '(' '*' ID arrays ')' '(' params ')'
Steven Morelandf1a35f72016-08-17 08:41:49 -0700383 {
Steven Morelandce651892016-09-19 13:12:58 -0700384 $1->setArrays($5);
Steven Morelandf1a35f72016-08-17 08:41:49 -0700385 std::reverse($8->begin(), $8->end());
386 $$ = new FunctionDeclaration($1, $4, $8);
387 }
388 | type ID '(' params ')'
389 {
390 std::reverse($4->begin(), $4->end());
391 $$ = new FunctionDeclaration($1, $2, $4);
392 }
393 | type '(' ID ')' '(' params ')'
394 {
395 std::reverse($6->begin(), $6->end());
396 $$ = new FunctionDeclaration($1, $3, $6);
397 }
398 | VARARGS
399 {
400 $$ = new VarDeclaration(new Type(NULL), "...");
401 }
402 ;
403
404type
405 : type_qualifiers
406 {
407 std::reverse($1->begin(), $1->end());
408 $$ = new Type($1);
409 }
410 ;
411
412type_qualifiers
413 : type_qualifier
414 {
415 $$ = new std::vector<Type::Qualifier *>;
416 $$->push_back($1);
417 }
418 | type_qualifier type_qualifiers
419 {
420 $$ = $2;
421 $$->push_back($1);
422 }
423 ;
424
425opt_id
426 : /* EMPTY */ { $$ = ""; }
427 |
428 ID { $$ = $1; }
429 ;
430
431expr
432 : ID { $$ = Expression::atom(Expression::Type::UNKOWN, $1); }
433 | VALUE { $$ = Expression::atom(Expression::Type::UNKOWN, $1); }
434 | INTEGRAL_VALUE { $$ = Expression::atom(Expression::integralType($1), $1); }
435 | '(' expr ')' { $$ = Expression::parenthesize($2); }
436 | ID '[' expr ']' %prec ARRAY_SUBSCRIPT {
437 $$ = Expression::arraySubscript($1, $3);
438 }
439 | ID '(' args ')' %prec FUNCTION_CALL {
440 std::reverse($3->begin(), $3->end());
441 $$ = Expression::functionCall($1, $3);
442 }
443 | expr '?' expr ':' expr { $$ = Expression::ternary($1, $3, $5); }
444 | expr '+' expr { $$ = Expression::binary($1, "+", $3); }
445 | expr '-' expr { $$ = Expression::binary($1, "-", $3); }
446 | expr '/' expr { $$ = Expression::binary($1, "/", $3); }
447 | expr '*' expr { $$ = Expression::binary($1, "*", $3); }
448 | expr '%' expr { $$ = Expression::binary($1, "%%", $3); }
449 | expr '&' expr { $$ = Expression::binary($1, "&", $3); }
450 | expr '|' expr { $$ = Expression::binary($1, "|", $3); }
451 | expr '^' expr { $$ = Expression::binary($1, "^", $3); }
452 | expr LSHIFT expr { $$ = Expression::binary($1, "<<", $3); }
453 | expr RSHIFT expr { $$ = Expression::binary($1, ">>", $3); }
454 | '~' expr { $$ = Expression::unary("~", $2); }
455 | '-' expr %prec UMINUS { $$ = Expression::unary("-", $2); }
456 | '+' expr %prec UPLUS { $$ = Expression::unary("+", $2); }
457 ;
458
459args
460 : /* empty */
461 {
462 $$ = new std::vector<Expression *>;
463 }
464 | expr
465 {
466 $$ = new std::vector<Expression *>;
467 $$->push_back($1);
468 }
469 | expr ',' args
470 {
471 $$ = $3;
472 $$->push_back($1);
473 }
474 ;
475
476type_qualifier
477 : UNSIGNED { $$ = new Type::Qualifier(Type::Qualifier::UNSIGNED); }
478 | SIGNED { $$ = new Type::Qualifier(Type::Qualifier::SIGNED); }
479 | VOID { $$ = new Type::Qualifier(Type::Qualifier::VOID); }
480 | '*' { $$ = new Type::Qualifier(Type::Qualifier::POINTER); }
481 | CONST { $$ = new Type::Qualifier(Type::Qualifier::CONST); }
482 | ID { $$ = new Type::Qualifier(Type::Qualifier::ID, $1); }
483 | '<' type '>' { $$ = new Type::Qualifier(Type::Qualifier::GENERICS, $2); }
484 | ENUM { $$ = new Type::Qualifier(Type::Qualifier::ENUM); }
485 | struct_or_union { $$ = new Type::Qualifier($1); }
486 ;
487
488struct_or_union
489 : STRUCT { $$ = android::Type::Qualifier::STRUCT; }
490 | UNION { $$ = android::Type::Qualifier::UNION; }
491 ;
492
Steven Morelandce651892016-09-19 13:12:58 -0700493arrays
494 : /* empty */ { $$ = new std::vector<Expression *>; }
495 | array arrays {
496 $$ = $2;
497 $$->push_back($1);
498 }
499 ;
500
501array
502 : '[' ']' { $$ = Expression::atom(Expression::Type::UNKOWN, " "); }
Steven Morelandf1a35f72016-08-17 08:41:49 -0700503 | '[' expr ']' { $$ = $2; }
504 ;
505
506%%