blob: 384f848c5e036c0fffae0ba69cc1879988712d19 [file] [log] [blame]
David Gibsonfc14dad2005-06-08 17:18:34 +10001/*
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
David Gibson86dbcbd2005-10-19 16:00:31 +100021%option noyywrap nounput yylineno
David Gibsonfc14dad2005-06-08 17:18:34 +100022
Jon Loeligere45e6fd2007-03-23 15:18:41 -050023%x INCLUDE
David Gibsonfc14dad2005-06-08 17:18:34 +100024%x CELLDATA
25%x BYTESTRING
David Gibsonf0517db2005-07-15 17:14:24 +100026%x MEMRESERVE
David Gibsonfc14dad2005-06-08 17:18:34 +100027
28PROPCHAR [a-zA-Z0-9,._+*#?-]
29UNITCHAR [0-9a-f,]
David Gibson41eecd42007-06-07 12:07:35 +100030WS [[:space:]]
David Gibsonfc14dad2005-06-08 17:18:34 +100031
David Gibson81f2e892005-06-16 17:04:00 +100032REFCHAR ({PROPCHAR}|{UNITCHAR}|[/@])
33
David Gibsonfc14dad2005-06-08 17:18:34 +100034%{
35#include "dtc.h"
Jon Loeligerce34ae32007-03-28 17:05:33 -050036#include "srcpos.h"
David Gibson4102d842005-06-16 14:36:37 +100037#include "dtc-parser.tab.h"
Jon Loeligere45e6fd2007-03-23 15:18:41 -050038
David Gibsonfc14dad2005-06-08 17:18:34 +100039
David Gibson81f2e892005-06-16 17:04:00 +100040/*#define LEXDEBUG 1*/
41
42#ifdef LEXDEBUG
43#define DPRINT(fmt, ...) fprintf(stderr, fmt, ##__VA_ARGS__)
44#else
45#define DPRINT(fmt, ...) do { } while (0)
46#endif
David Gibsonfc14dad2005-06-08 17:18:34 +100047
David Gibson86dbcbd2005-10-19 16:00:31 +100048
49
David Gibsonfc14dad2005-06-08 17:18:34 +100050%}
51
David Gibsonc5c437e2005-07-04 13:53:14 +100052%%
53
Jon Loeligerce34ae32007-03-28 17:05:33 -050054"/include/" BEGIN(INCLUDE);
Jon Loeligere45e6fd2007-03-23 15:18:41 -050055
Jon Loeligere45e6fd2007-03-23 15:18:41 -050056<INCLUDE>\"[^"\n]*\" {
57 yytext[strlen(yytext) - 1] = 0;
58 if (!push_input_file(yytext + 1)) {
59 /* Some unrecoverable error.*/
60 exit(1);
61 }
62 BEGIN(INITIAL);
63 }
64
65
66<<EOF>> {
67 if (!pop_input_file()) {
68 yyterminate();
69 }
70 }
71
David Gibsonfc14dad2005-06-08 17:18:34 +100072\"[^"]*\" {
Jon Loeligere45e6fd2007-03-23 15:18:41 -050073 yylloc.filenum = srcpos_filenum;
David Gibson86dbcbd2005-10-19 16:00:31 +100074 yylloc.first_line = yylineno;
David Gibson81f2e892005-06-16 17:04:00 +100075 DPRINT("String: %s\n", yytext);
David Gibsonfc14dad2005-06-08 17:18:34 +100076 yylval.data = data_copy_escape_string(yytext+1,
77 yyleng-2);
David Gibson86dbcbd2005-10-19 16:00:31 +100078 yylloc.first_line = yylineno;
David Gibsonfc14dad2005-06-08 17:18:34 +100079 return DT_STRING;
80 }
81
David Gibsonf0517db2005-07-15 17:14:24 +100082"/memreserve/" {
Jon Loeligere45e6fd2007-03-23 15:18:41 -050083 yylloc.filenum = srcpos_filenum;
David Gibson86dbcbd2005-10-19 16:00:31 +100084 yylloc.first_line = yylineno;
David Gibsonf0517db2005-07-15 17:14:24 +100085 DPRINT("Keyword: /memreserve/\n");
86 BEGIN(MEMRESERVE);
87 return DT_MEMRESERVE;
88 }
89
90<MEMRESERVE>[0-9a-fA-F]+ {
Jon Loeligere45e6fd2007-03-23 15:18:41 -050091 yylloc.filenum = srcpos_filenum;
David Gibson86dbcbd2005-10-19 16:00:31 +100092 yylloc.first_line = yylineno;
David Gibsonf0517db2005-07-15 17:14:24 +100093 if (yyleng > 2*sizeof(yylval.addr)) {
94 fprintf(stderr, "Address value %s too large\n",
95 yytext);
96 }
97 yylval.addr = (u64) strtoull(yytext, NULL, 16);
98 DPRINT("Addr: %llx\n",
99 (unsigned long long)yylval.addr);
100 return DT_ADDR;
101 }
102
103<MEMRESERVE>";" {
Jon Loeligere45e6fd2007-03-23 15:18:41 -0500104 yylloc.filenum = srcpos_filenum;
David Gibson86dbcbd2005-10-19 16:00:31 +1000105 yylloc.first_line = yylineno;
David Gibsonf0517db2005-07-15 17:14:24 +1000106 DPRINT("/MEMRESERVE\n");
107 BEGIN(INITIAL);
108 return ';';
109 }
Milton Millerac6a5e22007-07-07 01:18:50 -0500110
111<*>[a-zA-Z_][a-zA-Z0-9_]*: {
112 yylloc.filenum = srcpos_filenum;
113 yylloc.first_line = yylineno;
114 DPRINT("Label: %s\n", yytext);
115 yylval.str = strdup(yytext);
116 yylval.str[yyleng-1] = '\0';
117 return DT_LABEL;
118 }
119
Jon Loeligeraf0278a2007-02-15 10:59:27 -0600120<CELLDATA>[bodh]# {
Jon Loeligere45e6fd2007-03-23 15:18:41 -0500121 yylloc.filenum = srcpos_filenum;
Jon Loeligeraf0278a2007-02-15 10:59:27 -0600122 yylloc.first_line = yylineno;
123 if (*yytext == 'b')
124 yylval.cbase = 2;
125 else if (*yytext == 'o')
126 yylval.cbase = 8;
127 else if (*yytext == 'd')
128 yylval.cbase = 10;
129 else
130 yylval.cbase = 16;
131 DPRINT("Base: %d\n", yylval.cbase);
132 return DT_BASE;
133 }
David Gibsonf0517db2005-07-15 17:14:24 +1000134
David Gibsonfc14dad2005-06-08 17:18:34 +1000135<CELLDATA>[0-9a-fA-F]+ {
Jon Loeligere45e6fd2007-03-23 15:18:41 -0500136 yylloc.filenum = srcpos_filenum;
David Gibson86dbcbd2005-10-19 16:00:31 +1000137 yylloc.first_line = yylineno;
Jon Loeligeraf0278a2007-02-15 10:59:27 -0600138 yylval.str = strdup(yytext);
139 DPRINT("Cell: '%s'\n", yylval.str);
David Gibsonfc14dad2005-06-08 17:18:34 +1000140 return DT_CELL;
141 }
142
143<CELLDATA>">" {
Jon Loeligere45e6fd2007-03-23 15:18:41 -0500144 yylloc.filenum = srcpos_filenum;
David Gibson86dbcbd2005-10-19 16:00:31 +1000145 yylloc.first_line = yylineno;
David Gibson81f2e892005-06-16 17:04:00 +1000146 DPRINT("/CELLDATA\n");
David Gibsonfc14dad2005-06-08 17:18:34 +1000147 BEGIN(INITIAL);
148 return '>';
149 }
150
David Gibson81f2e892005-06-16 17:04:00 +1000151<CELLDATA>\&{REFCHAR}* {
Jon Loeligere45e6fd2007-03-23 15:18:41 -0500152 yylloc.filenum = srcpos_filenum;
David Gibson86dbcbd2005-10-19 16:00:31 +1000153 yylloc.first_line = yylineno;
David Gibson81f2e892005-06-16 17:04:00 +1000154 DPRINT("Ref: %s\n", yytext+1);
155 yylval.str = strdup(yytext+1);
156 return DT_REF;
157 }
158
David Gibsonfc14dad2005-06-08 17:18:34 +1000159<BYTESTRING>[0-9a-fA-F]{2} {
Jon Loeligere45e6fd2007-03-23 15:18:41 -0500160 yylloc.filenum = srcpos_filenum;
David Gibson86dbcbd2005-10-19 16:00:31 +1000161 yylloc.first_line = yylineno;
David Gibsonfc14dad2005-06-08 17:18:34 +1000162 yylval.byte = strtol(yytext, NULL, 16);
David Gibson81f2e892005-06-16 17:04:00 +1000163 DPRINT("Byte: %02x\n", (int)yylval.byte);
David Gibsonfc14dad2005-06-08 17:18:34 +1000164 return DT_BYTE;
165 }
166
167<BYTESTRING>"]" {
Jon Loeligere45e6fd2007-03-23 15:18:41 -0500168 yylloc.filenum = srcpos_filenum;
David Gibson86dbcbd2005-10-19 16:00:31 +1000169 yylloc.first_line = yylineno;
David Gibson81f2e892005-06-16 17:04:00 +1000170 DPRINT("/BYTESTRING\n");
David Gibsonfc14dad2005-06-08 17:18:34 +1000171 BEGIN(INITIAL);
172 return ']';
173 }
174
David Gibson32da4752007-02-07 16:37:50 +1100175, { /* Technically this is a valid property name,
176 but we'd rather use it as punctuation, so detect it
177 here in preference */
Jon Loeligere45e6fd2007-03-23 15:18:41 -0500178 yylloc.filenum = srcpos_filenum;
David Gibson32da4752007-02-07 16:37:50 +1100179 yylloc.first_line = yylineno;
180 DPRINT("Char (propname like): %c (\\x%02x)\n", yytext[0],
181 (unsigned)yytext[0]);
182 return yytext[0];
183 }
184
David Gibsonfc14dad2005-06-08 17:18:34 +1000185{PROPCHAR}+ {
Jon Loeligere45e6fd2007-03-23 15:18:41 -0500186 yylloc.filenum = srcpos_filenum;
David Gibson86dbcbd2005-10-19 16:00:31 +1000187 yylloc.first_line = yylineno;
David Gibson81f2e892005-06-16 17:04:00 +1000188 DPRINT("PropName: %s\n", yytext);
David Gibsonfc14dad2005-06-08 17:18:34 +1000189 yylval.str = strdup(yytext);
190 return DT_PROPNAME;
191 }
192
David Gibson4102d842005-06-16 14:36:37 +1000193{PROPCHAR}+(@{UNITCHAR}+)? {
Jon Loeligere45e6fd2007-03-23 15:18:41 -0500194 yylloc.filenum = srcpos_filenum;
David Gibson86dbcbd2005-10-19 16:00:31 +1000195 yylloc.first_line = yylineno;
David Gibson81f2e892005-06-16 17:04:00 +1000196 DPRINT("NodeName: %s\n", yytext);
David Gibson4102d842005-06-16 14:36:37 +1000197 yylval.str = strdup(yytext);
198 return DT_NODENAME;
199 }
200
201
David Gibsonfc14dad2005-06-08 17:18:34 +1000202<*>{WS}+ /* eat whitespace */
203
204<*>"/*"([^*]|\*+[^*/])*\*+"/" {
Jon Loeligere45e6fd2007-03-23 15:18:41 -0500205 yylloc.filenum = srcpos_filenum;
David Gibson86dbcbd2005-10-19 16:00:31 +1000206 yylloc.first_line = yylineno;
David Gibson81f2e892005-06-16 17:04:00 +1000207 DPRINT("Comment: %s\n", yytext);
David Gibsonfc14dad2005-06-08 17:18:34 +1000208 /* eat comments */
David Gibsonfc14dad2005-06-08 17:18:34 +1000209 }
210
211<*>"//".*\n /* eat line comments */
212
David Gibsonf0517db2005-07-15 17:14:24 +1000213<*>. {
Jon Loeligere45e6fd2007-03-23 15:18:41 -0500214 yylloc.filenum = srcpos_filenum;
David Gibson86dbcbd2005-10-19 16:00:31 +1000215 yylloc.first_line = yylineno;
David Gibsonfc14dad2005-06-08 17:18:34 +1000216 switch (yytext[0]) {
217 case '<':
David Gibson81f2e892005-06-16 17:04:00 +1000218 DPRINT("CELLDATA\n");
David Gibsonfc14dad2005-06-08 17:18:34 +1000219 BEGIN(CELLDATA);
220 break;
221 case '[':
David Gibson81f2e892005-06-16 17:04:00 +1000222 DPRINT("BYTESTRING\n");
David Gibsonfc14dad2005-06-08 17:18:34 +1000223 BEGIN(BYTESTRING);
224 break;
225 default:
226
David Gibson81f2e892005-06-16 17:04:00 +1000227 DPRINT("Char: %c (\\x%02x)\n", yytext[0],
David Gibsonfc14dad2005-06-08 17:18:34 +1000228 (unsigned)yytext[0]);
David Gibsonfc14dad2005-06-08 17:18:34 +1000229 break;
230 }
231
232 return yytext[0];
233 }
234
235%%
Jon Loeligerce34ae32007-03-28 17:05:33 -0500236
237
238/*
239 * Stack of nested include file contexts.
240 */
241
242struct incl_file {
243 int filenum;
244 FILE *file;
245 YY_BUFFER_STATE yy_prev_buf;
246 int yy_prev_lineno;
247 struct incl_file *prev;
248};
249
250struct incl_file *incl_file_stack;
251
252
253/*
254 * Detect infinite include recursion.
255 */
256#define MAX_INCLUDE_DEPTH (100)
257
258static int incl_depth = 0;
259
260
261int push_input_file(const char *filename)
262{
263 FILE *f;
264 struct incl_file *incl_file;
265
266 if (!filename) {
267 yyerror("No include file name given.");
268 return 0;
269 }
270
271 if (incl_depth++ >= MAX_INCLUDE_DEPTH) {
272 yyerror("Includes nested too deeply");
273 return 0;
274 }
275
276 f = dtc_open_file(filename);
277
278 incl_file = malloc(sizeof(struct incl_file));
279 if (!incl_file) {
280 yyerror("Can not allocate include file space.");
281 return 0;
282 }
283
284 /*
285 * Save current context.
286 */
287 incl_file->yy_prev_buf = YY_CURRENT_BUFFER;
288 incl_file->yy_prev_lineno = yylineno;
289 incl_file->filenum = srcpos_filenum;
290 incl_file->file = yyin;
291 incl_file->prev = incl_file_stack;
292
293 incl_file_stack = incl_file;
294
295 /*
296 * Establish new context.
297 */
298 srcpos_filenum = lookup_file_name(filename, 0);
299 yylineno = 1;
300 yyin = f;
301 yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
302
303 return 1;
304}
305
306
307int pop_input_file(void)
308{
309 struct incl_file *incl_file;
310
311 if (incl_file_stack == 0)
312 return 0;
313
314 fclose(yyin);
315
316 /*
317 * Pop.
318 */
319 --incl_depth;
320 incl_file = incl_file_stack;
321 incl_file_stack = incl_file->prev;
322
323 /*
324 * Recover old context.
325 */
326 yy_delete_buffer(YY_CURRENT_BUFFER);
327 yy_switch_to_buffer(incl_file->yy_prev_buf);
328 yylineno = incl_file->yy_prev_lineno;
329 srcpos_filenum = incl_file->filenum;
330 yyin = incl_file->file;
331
332 /*
333 * Free old state.
334 */
335 free(incl_file);
336
337 if (YY_CURRENT_BUFFER == 0)
338 return 0;
339
340 return 1;
341}