aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/boot/dtc-src/dtc-lexer.l
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/boot/dtc-src/dtc-lexer.l')
-rw-r--r--arch/powerpc/boot/dtc-src/dtc-lexer.l328
1 files changed, 328 insertions, 0 deletions
diff --git a/arch/powerpc/boot/dtc-src/dtc-lexer.l b/arch/powerpc/boot/dtc-src/dtc-lexer.l
new file mode 100644
index 000000000000..c811b221b31e
--- /dev/null
+++ b/arch/powerpc/boot/dtc-src/dtc-lexer.l
@@ -0,0 +1,328 @@
1/*
2 * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation. 2005.
3 *
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of the
8 * License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
18 * USA
19 */
20
21%option noyywrap nounput yylineno
22
23%x INCLUDE
24%x BYTESTRING
25%x PROPNODENAME
26%s V1
27
28PROPNODECHAR [a-zA-Z0-9,._+*#?@-]
29PATHCHAR ({PROPNODECHAR}|[/])
30LABEL [a-zA-Z_][a-zA-Z0-9_]*
31
32%{
33#include "dtc.h"
34#include "srcpos.h"
35#include "dtc-parser.tab.h"
36
37
38/*#define LEXDEBUG 1*/
39
40#ifdef LEXDEBUG
41#define DPRINT(fmt, ...) fprintf(stderr, fmt, ##__VA_ARGS__)
42#else
43#define DPRINT(fmt, ...) do { } while (0)
44#endif
45
46static int dts_version; /* = 0 */
47
48#define BEGIN_DEFAULT() if (dts_version == 0) { \
49 DPRINT("<INITIAL>\n"); \
50 BEGIN(INITIAL); \
51 } else { \
52 DPRINT("<V1>\n"); \
53 BEGIN(V1); \
54 }
55%}
56
57%%
58<*>"/include/" BEGIN(INCLUDE);
59
60<INCLUDE>\"[^"\n]*\" {
61 yytext[strlen(yytext) - 1] = 0;
62 if (!push_input_file(yytext + 1)) {
63 /* Some unrecoverable error.*/
64 exit(1);
65 }
66 BEGIN_DEFAULT();
67 }
68
69
70<*><<EOF>> {
71 if (!pop_input_file()) {
72 yyterminate();
73 }
74 }
75
76<*>\"([^\\"]|\\.)*\" {
77 yylloc.filenum = srcpos_filenum;
78 yylloc.first_line = yylineno;
79 DPRINT("String: %s\n", yytext);
80 yylval.data = data_copy_escape_string(yytext+1,
81 yyleng-2);
82 yylloc.first_line = yylineno;
83 return DT_STRING;
84 }
85
86<*>"/dts-v1/" {
87 yylloc.filenum = srcpos_filenum;
88 yylloc.first_line = yylineno;
89 DPRINT("Keyword: /dts-v1/\n");
90 dts_version = 1;
91 BEGIN_DEFAULT();
92 return DT_V1;
93 }
94
95<*>"/memreserve/" {
96 yylloc.filenum = srcpos_filenum;
97 yylloc.first_line = yylineno;
98 DPRINT("Keyword: /memreserve/\n");
99 BEGIN_DEFAULT();
100 return DT_MEMRESERVE;
101 }
102
103<*>{LABEL}: {
104 yylloc.filenum = srcpos_filenum;
105 yylloc.first_line = yylineno;
106 DPRINT("Label: %s\n", yytext);
107 yylval.labelref = strdup(yytext);
108 yylval.labelref[yyleng-1] = '\0';
109 return DT_LABEL;
110 }
111
112<INITIAL>[bodh]# {
113 yylloc.filenum = srcpos_filenum;
114 yylloc.first_line = yylineno;
115 if (*yytext == 'b')
116 yylval.cbase = 2;
117 else if (*yytext == 'o')
118 yylval.cbase = 8;
119 else if (*yytext == 'd')
120 yylval.cbase = 10;
121 else
122 yylval.cbase = 16;
123 DPRINT("Base: %d\n", yylval.cbase);
124 return DT_BASE;
125 }
126
127<INITIAL>[0-9a-fA-F]+ {
128 yylloc.filenum = srcpos_filenum;
129 yylloc.first_line = yylineno;
130 yylval.literal = strdup(yytext);
131 DPRINT("Literal: '%s'\n", yylval.literal);
132 return DT_LEGACYLITERAL;
133 }
134
135<V1>[0-9]+|0[xX][0-9a-fA-F]+ {
136 yylloc.filenum = srcpos_filenum;
137 yylloc.first_line = yylineno;
138 yylval.literal = strdup(yytext);
139 DPRINT("Literal: '%s'\n", yylval.literal);
140 return DT_LITERAL;
141 }
142
143\&{LABEL} { /* label reference */
144 yylloc.filenum = srcpos_filenum;
145 yylloc.first_line = yylineno;
146 DPRINT("Ref: %s\n", yytext+1);
147 yylval.labelref = strdup(yytext+1);
148 return DT_REF;
149 }
150
151"&{/"{PATHCHAR}+\} { /* new-style path reference */
152 yylloc.filenum = srcpos_filenum;
153 yylloc.first_line = yylineno;
154 yytext[yyleng-1] = '\0';
155 DPRINT("Ref: %s\n", yytext+2);
156 yylval.labelref = strdup(yytext+2);
157 return DT_REF;
158 }
159
160<INITIAL>"&/"{PATHCHAR}+ { /* old-style path reference */
161 yylloc.filenum = srcpos_filenum;
162 yylloc.first_line = yylineno;
163 DPRINT("Ref: %s\n", yytext+1);
164 yylval.labelref = strdup(yytext+1);
165 return DT_REF;
166 }
167
168<BYTESTRING>[0-9a-fA-F]{2} {
169 yylloc.filenum = srcpos_filenum;
170 yylloc.first_line = yylineno;
171 yylval.byte = strtol(yytext, NULL, 16);
172 DPRINT("Byte: %02x\n", (int)yylval.byte);
173 return DT_BYTE;
174 }
175
176<BYTESTRING>"]" {
177 yylloc.filenum = srcpos_filenum;
178 yylloc.first_line = yylineno;
179 DPRINT("/BYTESTRING\n");
180 BEGIN_DEFAULT();
181 return ']';
182 }
183
184<PROPNODENAME>{PROPNODECHAR}+ {
185 yylloc.filenum = srcpos_filenum;
186 yylloc.first_line = yylineno;
187 DPRINT("PropNodeName: %s\n", yytext);
188 yylval.propnodename = strdup(yytext);
189 BEGIN_DEFAULT();
190 return DT_PROPNODENAME;
191 }
192
193
194<*>[[:space:]]+ /* eat whitespace */
195
196<*>"/*"([^*]|\*+[^*/])*\*+"/" {
197 yylloc.filenum = srcpos_filenum;
198 yylloc.first_line = yylineno;
199 DPRINT("Comment: %s\n", yytext);
200 /* eat comments */
201 }
202
203<*>"//".*\n /* eat line comments */
204
205<*>. {
206 yylloc.filenum = srcpos_filenum;
207 yylloc.first_line = yylineno;
208 DPRINT("Char: %c (\\x%02x)\n", yytext[0],
209 (unsigned)yytext[0]);
210 if (yytext[0] == '[') {
211 DPRINT("<BYTESTRING>\n");
212 BEGIN(BYTESTRING);
213 }
214 if ((yytext[0] == '{')
215 || (yytext[0] == ';')) {
216 DPRINT("<PROPNODENAME>\n");
217 BEGIN(PROPNODENAME);
218 }
219 return yytext[0];
220 }
221
222%%
223
224
225/*
226 * Stack of nested include file contexts.
227 */
228
229struct incl_file {
230 int filenum;
231 FILE *file;
232 YY_BUFFER_STATE yy_prev_buf;
233 int yy_prev_lineno;
234 struct incl_file *prev;
235};
236
237struct incl_file *incl_file_stack;
238
239
240/*
241 * Detect infinite include recursion.
242 */
243#define MAX_INCLUDE_DEPTH (100)
244
245static int incl_depth = 0;
246
247
248int push_input_file(const char *filename)
249{
250 FILE *f;
251 struct incl_file *incl_file;
252
253 if (!filename) {
254 yyerror("No include file name given.");
255 return 0;
256 }
257
258 if (incl_depth++ >= MAX_INCLUDE_DEPTH) {
259 yyerror("Includes nested too deeply");
260 return 0;
261 }
262
263 f = dtc_open_file(filename);
264
265 incl_file = malloc(sizeof(struct incl_file));
266 if (!incl_file) {
267 yyerror("Can not allocate include file space.");
268 return 0;
269 }
270
271 /*
272 * Save current context.
273 */
274 incl_file->yy_prev_buf = YY_CURRENT_BUFFER;
275 incl_file->yy_prev_lineno = yylineno;
276 incl_file->filenum = srcpos_filenum;
277 incl_file->file = yyin;
278 incl_file->prev = incl_file_stack;
279
280 incl_file_stack = incl_file;
281
282 /*
283 * Establish new context.
284 */
285 srcpos_filenum = lookup_file_name(filename, 0);
286 yylineno = 1;
287 yyin = f;
288 yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
289
290 return 1;
291}
292
293
294int pop_input_file(void)
295{
296 struct incl_file *incl_file;
297
298 if (incl_file_stack == 0)
299 return 0;
300
301 fclose(yyin);
302
303 /*
304 * Pop.
305 */
306 --incl_depth;
307 incl_file = incl_file_stack;
308 incl_file_stack = incl_file->prev;
309
310 /*
311 * Recover old context.
312 */
313 yy_delete_buffer(YY_CURRENT_BUFFER);
314 yy_switch_to_buffer(incl_file->yy_prev_buf);
315 yylineno = incl_file->yy_prev_lineno;
316 srcpos_filenum = incl_file->filenum;
317 yyin = incl_file->file;
318
319 /*
320 * Free old state.
321 */
322 free(incl_file);
323
324 if (YY_CURRENT_BUFFER == 0)
325 return 0;
326
327 return 1;
328}