• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
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
17D             [0-9]
18L             [a-zA-Z_]
19AN            [a-zA-Z_0-9]
20H             [a-fA-F_0-9]
21E             [Ee][+-]?{D}+
22FS            (f|F|l|L)
23IS            (u|U|l|L)*
24S             [ \t]
25DOT           [.]
26PATH          ({DOT}|{AN}|\/|-)+
27ID            {L}{AN}*
28
29%{
30
31#include "AST.h"
32#include "Declaration.h"
33#include "Type.h"
34#include "VarDeclaration.h"
35#include "FunctionDeclaration.h"
36#include "CompositeDeclaration.h"
37#include "Define.h"
38#include "Include.h"
39#include "EnumVarDeclaration.h"
40#include "Note.h"
41#include "TypeDef.h"
42#include "Expression.h"
43
44#include <assert.h>
45#include <utils/Errors.h>
46
47#include "c2hal_y.h"
48
49using namespace android;
50
51int check_type(yyscan_t yyscanner, struct yyguts_t *yyg);
52
53extern int start_token;
54
55extern std::string last_comment;
56
57// :(
58extern int numB;
59extern std::string functionText;
60
61extern std::string defineText;
62extern std::string otherText;
63
64extern bool isOpenGl;
65
66#define YY_USER_ACTION yylloc->first_line = yylineno;
67
68#define ID_UNLESS_OPEN_GL(OPEN_GL_CODE)                                  \
69        do {                                                             \
70            if (isOpenGl) {                                              \
71                OPEN_GL_CODE                                             \
72            } else {                                                     \
73                yylval->str = strdup(yytext);                            \
74                return ID;                                               \
75            }                                                            \
76        } while(0)
77
78#pragma clang diagnostic push
79#pragma clang diagnostic ignored "-Wunused-parameter"
80#pragma clang diagnostic ignored "-Wdeprecated-register"
81#pragma clang diagnostic ignored "-Wregister"
82
83%}
84
85%option yylineno
86%option nounput
87%option noinput
88%option reentrant
89%option bison-bridge
90%option bison-locations
91%option extra-type="android::AST *"
92
93%x COMMENT_STATE
94%x INCLUDE_STATE
95%x COPY_DECL_STATE
96%x FUNCTION_STATE
97%x DEFINE_STATE
98%x DEFINE_SLURP_STATE
99
100%%
101%{
102    if (start_token) {
103        int token = start_token;
104        start_token = 0;
105        return token;
106    }
107%}
108
109"\n"                              { /* needed for yylineno to update */ }
110
111\/\*([^*]|\*+[^*\/])*\*+\/        { last_comment = strdup(yytext); }
112
113"//"[^\r\n]*                      { /* skip C++ style comment */ }
114
115"__BEGIN_DECLS"                   { /* macro'd 'extern "C" {' if CPP or nothing */ }
116"__END_DECLS"                     { /* '}' */ }
117
118"__attribute__((__packed__))"     { /* ignore */ }
119"__attribute__((packed))"         { /* ignore */ }
120"__attribute__((__deprecated__))" { /* ignore */ }
121
122"EGLAPIENTRYP"                    { ID_UNLESS_OPEN_GL(return '*';); }
123"EGLAPIENTRY"                     { ID_UNLESS_OPEN_GL(/* actually is nothing on android */); }
124"GL_APIENTRYP"                    { ID_UNLESS_OPEN_GL(return '*';); }
125"GL_APIENTRY"                     { ID_UNLESS_OPEN_GL(/* actually is nothing on android */); }
126"GL_APICALL"                      { ID_UNLESS_OPEN_GL(/* __attribute__((visibility("default"))) */); }
127
128"#include"                        { BEGIN(INCLUDE_STATE); return INCLUDE; }
129<INCLUDE_STATE>"<"                { return '<'; }
130<INCLUDE_STATE>">"                { return '>'; }
131<INCLUDE_STATE>"\""               { return '"'; }
132<INCLUDE_STATE>"\n"               { BEGIN(INITIAL); }
133<INCLUDE_STATE>{PATH}             { yylval->str = strdup(yytext); return INCLUDE_FILE; }
134<INCLUDE_STATE>.                  { /* ignore other characters */ }
135
136"static"|"inline"                 {
137                                    BEGIN(FUNCTION_STATE);
138                                    functionText = strdup(yytext);
139                                    numB = 0;
140                                  }
141<FUNCTION_STATE>[^{}]+            { functionText += yytext; }
142<FUNCTION_STATE>"{"               { functionText += yytext; numB += 1;}
143<FUNCTION_STATE>"}"               {
144                                    functionText += yytext;
145                                    numB -= 1;
146
147                                    // Will fail if unbalanced brackets in
148                                    // strings or comments in the function.
149                                    if (numB <= 0) {
150                                        BEGIN(INITIAL);
151                                        yylval->str = strdup(functionText.c_str());
152                                        return FUNCTION;
153                                    }
154                                   }
155
156"#"{S}*"define"                   { BEGIN(DEFINE_STATE); return DEFINE; }
157<DEFINE_STATE>{ID}                {
158                                    BEGIN(DEFINE_SLURP_STATE);
159                                    defineText = "";
160                                    yylval->str = strdup(yytext);
161                                    return ID;
162                                  }
163<DEFINE_STATE>.                   { /* ignore other characters */ }
164
165<DEFINE_SLURP_STATE>\/\*([^*]|\*+[^*\/])*\*+\/ {
166                                    defineText += yytext;
167                                  }
168<DEFINE_SLURP_STATE>[^\\\n]       { defineText += yytext; }
169<DEFINE_SLURP_STATE>"\\\n"        { defineText += yytext; }
170<DEFINE_SLURP_STATE>"\n"          {
171                                    BEGIN(INITIAL);
172                                    yylval->str = strdup(defineText.c_str());
173                                    return DEFINE_SLURP;
174                                  }
175
176"using"                           { BEGIN(COPY_DECL_STATE); otherText = strdup(yytext); }
177"#"{S}*{L}+                       { BEGIN(COPY_DECL_STATE); otherText = strdup(yytext); }
178<COPY_DECL_STATE>\/\*([^*]|\*+[^*\/])*\*+\/ {
179                                    otherText += yytext;
180                                  }
181<COPY_DECL_STATE>[^\\\n]          { otherText += yytext; }
182<COPY_DECL_STATE>"\\\n"           { otherText += yytext; }
183<COPY_DECL_STATE>"\n"             {
184                                    BEGIN(INITIAL);
185                                    yylval->str = strdup(otherText.c_str());
186                                    // decls/macros we want to preserve
187                                    // in the output, but there is nothing
188                                    // special to do about them yet
189                                    return OTHER_STATEMENT;
190                                  }
191
192"struct"                          { return STRUCT; }
193"union"                           { return UNION; }
194"enum"                            { return ENUM; }
195"class"                           { return CLASS; }
196"const"                           { return CONST; }
197"typedef"                         { return TYPEDEF; }
198"void"                            { return VOID; }
199"unsigned"                        { return UNSIGNED; }
200"signed"                          { return SIGNED; }
201"namespace"                       { return NAMESPACE; }
202"extern"                          { return EXTERN; }
203"\"C\""                           { return C_STRING; }
204
205{ID}                              { yylval->str = strdup(yytext); return ID; }
2060[xX]{H}+{IS}?                    { yylval->str = strdup(yytext); return INTEGRAL_VALUE; }
2070{D}+{IS}?                        { yylval->str = strdup(yytext); return INTEGRAL_VALUE; }
208{D}+{IS}?                         { yylval->str = strdup(yytext); return INTEGRAL_VALUE; }
209
210{D}+{E}{FS}?                      { yylval->str = strdup(yytext); return VALUE; }
211{D}+\.{E}?{FS}?                   { yylval->str = strdup(yytext); return VALUE; }
212{D}*\.{D}+{E}?{FS}?               { yylval->str = strdup(yytext); return VALUE; }
213L?\"(\\.|[^\\"])*\"               { yylval->str = strdup(yytext); return VALUE; }
214
215"("                               { return '('; }
216")"                               { return ')'; }
217"<"                               { return '<'; }
218">"                               { return '>'; }
219"{"                               { return '{'; }
220"}"                               { return '}'; }
221"["                               { return '['; }
222"]"                               { return ']'; }
223"?"                               { return '?'; }
224":"                               { return ':'; }
225"*"                               { return '*'; }
226";"                               { return ';'; }
227","                               { return ','; }
228"="                               { return '='; }
229"+"                               { return '+'; }
230"-"                               { return '-'; }
231"/"                               { return '/'; }
232"%"                               { return '%'; }
233"&"                               { return '&'; }
234"|"                               { return '|'; }
235"^"                               { return '^'; }
236"~"                               { return '~'; }
237"<<"                              { return LSHIFT; }
238">>"                              { return RSHIFT; }
239
240"..."                             { return VARARGS; }
241
242.                                 { /* ignore other characters */ }
243
244%%
245
246#pragma clang diagnostic pop
247
248// allows us to specify what start symbol will be used in the grammar
249int start_token;
250bool should_report_errors;
251
252std::string last_comment;
253
254// this is so frowned upon on so many levels, but here vars are so that we can
255// slurp up function text as a string and don't have to implement
256// the *entire* grammar of C (and C++ in some files) just to parse headers
257int numB;
258std::string functionText;
259
260std::string defineText;
261std::string otherText;
262
263bool isOpenGl;
264
265int yywrap(yyscan_t) {
266    return 1;
267}
268
269status_t parseFile(AST *ast) {
270    FILE *file = fopen(ast->getFilename().c_str(), "rb");
271
272    if (file == NULL) {
273        return -errno;
274    }
275
276    start_token = START_HEADER;
277    isOpenGl = ast->isOpenGl();
278    should_report_errors = true;
279
280    yyscan_t scanner;
281    yylex_init_extra(ast, &scanner);
282    ast->setScanner(scanner);
283
284    yyset_in(file, scanner);
285    int res = yyparse(ast);
286
287    yylex_destroy(scanner);
288    ast->setScanner(NULL);
289
290    fclose(file);
291    file = NULL;
292
293    return res;
294}
295
296status_t parseExpression(AST *ast, std::string str) {
297    start_token = START_EXPR;
298    isOpenGl = ast->isOpenGl();
299    should_report_errors = false;
300
301    yyscan_t scanner;
302    yylex_init_extra(ast, &scanner);
303    ast->setScanner(scanner);
304
305    YY_BUFFER_STATE buf = yy_scan_string(str.c_str(), scanner);
306
307    int res = yyparse(ast);
308
309    yy_delete_buffer(buf, scanner);
310
311    yylex_destroy(scanner);
312    ast->setScanner(NULL);
313
314    return res;
315}
316