diff options
Diffstat (limited to 'arch/powerpc/boot/dtc-src/dtc-lexer.l')
-rw-r--r-- | arch/powerpc/boot/dtc-src/dtc-lexer.l | 328 |
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 | |||
28 | PROPNODECHAR [a-zA-Z0-9,._+*#?@-] | ||
29 | PATHCHAR ({PROPNODECHAR}|[/]) | ||
30 | LABEL [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 | |||
46 | static 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 | |||
229 | struct 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 | |||
237 | struct incl_file *incl_file_stack; | ||
238 | |||
239 | |||
240 | /* | ||
241 | * Detect infinite include recursion. | ||
242 | */ | ||
243 | #define MAX_INCLUDE_DEPTH (100) | ||
244 | |||
245 | static int incl_depth = 0; | ||
246 | |||
247 | |||
248 | int 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 | |||
294 | int 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 | } | ||